From 68e2e03838a475252e519a7a16a9bcb2e3e4dd62 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Mon, 12 Aug 2013 06:59:03 +0200 Subject: Adding LuaBigInt and a few more things. --- src/LuaBigInt.cc | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 src/LuaBigInt.cc (limited to 'src/LuaBigInt.cc') diff --git a/src/LuaBigInt.cc b/src/LuaBigInt.cc new file mode 100644 index 0000000..67294d9 --- /dev/null +++ b/src/LuaBigInt.cc @@ -0,0 +1,210 @@ +#include "LuaBigInt.h" + +using namespace Balau; + +enum BigInt_functions_t { + BIGINT_CONSTRUCTOR, +}; + +enum BigInt_methods_t { + BIGINT_SET, + BIGINT_TOSTRING, + + BIGINT_ADD, + BIGINT_SUB, + BIGINT_MUL, + BIGINT_DIV, + BIGINT_MOD, +}; + +struct lua_functypes_t BigInt_functions[] = { + { BIGINT_CONSTRUCTOR, NULL, 0, 2, { BLUA_STRING | BLUA_NUMBER, BLUA_NUMBER } }, + { -1, 0, 0, 0, 0 }, +}; + +struct lua_functypes_t BigInt_methods[] = { + { BIGINT_SET, "set", 1, 2, { BLUA_STRING | BLUA_NUMBER, BLUA_NUMBER } }, + { BIGINT_TOSTRING, "tostring", 0, 1, { BLUA_NUMBER } }, + + { BIGINT_ADD, "add", 1, 1, { BLUA_OBJECT } }, + { BIGINT_SUB, "sub", 1, 1, { BLUA_OBJECT } }, + { BIGINT_MUL, "mul", 1, 1, { BLUA_OBJECT } }, + { BIGINT_DIV, "div", 1, 1, { BLUA_OBJECT } }, + { BIGINT_MOD, "mod", 1, 1, { BLUA_OBJECT } }, + + { -1, 0, 0, 0, 0 }, +}; + +struct sLua_BigInt { + static int BigInt_proceed_static(Lua & L, int n, int caller); + static int BigInt_proceed(Lua & L, int n, BigInt * obj, int caller); +}; + +int sLua_BigInt::BigInt_proceed_static(Lua & L, int n, int caller) { + int r = 0; + String s; + int radix = 10; + + switch (caller) { + case BIGINT_CONSTRUCTOR: + { + BigInt * a = new BigInt(); + if (L.type() == LUA_TSTRING) { + s = L.tostring(1); + if (n == 2) + radix = L.tonumber(-1); + a->set(s, radix); + } else { + lua_Number f = L.tonumber(); + a->set(f); + } + LuaBigIntFactory o(a); + o.pushDestruct(L); + r = 1; + break; + } + } + + return r; +} + +int sLua_BigInt::BigInt_proceed(Lua & L, int n, BigInt * a, int caller) { + int r = 0; + BigInt * b, * c, * m; + String s; + int radix = 10; + + switch (caller) { + case BIGINT_SET: + if (L.type() == LUA_TSTRING) { + s = L.tostring(2); + if (n == 3) + radix = L.tonumber(-1); + a->set(s, radix); + } else { + lua_Number f = L.tonumber(); + a->set(f); + } + r = 0; + break; + case BIGINT_TOSTRING: + if (n == 3) + radix = L.tonumber(-1); + L.push(a->toString(radix)); + r = 1; + break; + case BIGINT_ADD: + b = L.recast(); + { + LuaBigIntFactory cf(c = new BigInt()); + cf.pushDestruct(L); + } + *c = *a + *b; + r = 1; + break; + case BIGINT_SUB: + b = L.recast(); + { + LuaBigIntFactory cf(c = new BigInt()); + cf.pushDestruct(L); + } + *c = *a - *b; + r = 1; + break; + case BIGINT_MUL: + b = L.recast(); + { + LuaBigIntFactory cf(c = new BigInt()); + cf.pushDestruct(L); + } + *c = *a * *b; + r = 1; + break; + case BIGINT_DIV: + b = L.recast(); + { + LuaBigIntFactory cf(c = new BigInt()); + cf.pushDestruct(L); + } + *c = *a / *b; + r = 1; + break; + case BIGINT_MOD: + b = L.recast(); + { + LuaBigIntFactory cf(c = new BigInt()); + cf.pushDestruct(L); + } + *c = *a % *b; + r = 1; + break; + } + + return r; +} + +#define METAMETHOD_WRAPPER(op) \ +L.push("__" #op); \ +L.load("" \ +"return function(bigint) return function(a) \n" \ +" return a:" #op "() \n" \ +"end end\n" \ +""); \ +L.copy(-5); \ +L.pcall(1); \ +L.settable() \ + +#define METAMETHOD_WRAPPER2(op) \ +L.push("__" #op); \ +L.load("" \ +"return function(bigint) return function(a, b) \n" \ +" if type(a) ~= 'table' or a.__type ~= bigint then \n" \ +" a = bigint.new(a) \n" \ +" end \n" \ +" if type(b) ~= 'table' or b.__type ~= bigint then \n" \ +" b = bigint.new(b) \n" \ +" end \n" \ +" return a:" #op "(b) \n" \ +"end end\n" \ +""); \ +L.copy(-5); \ +L.pcall(1); \ +L.settable() \ + +void LuaBigIntFactory::pushStatics(Lua & L) { + CHECK_FUNCTIONS(BigInt); + CHECK_METHODS(BigInt); + PUSH_CLASS(BigInt); + PUSH_CONSTRUCTOR(BigInt, BIGINT_CONSTRUCTOR); + L.push("BIGINT_METAS"); + L.newtable(); + METAMETHOD_WRAPPER2(add); + METAMETHOD_WRAPPER2(sub); + METAMETHOD_WRAPPER2(div); + METAMETHOD_WRAPPER2(mul); + METAMETHOD_WRAPPER2(mod); + METAMETHOD_WRAPPER(tostring); + L.settable(LUA_REGISTRYINDEX); + PUSH_CLASS_DONE(); +} + +void LuaBigIntFactory::pushObjectAndMembers(Lua & L) { + pushObj(L, m_obj, "BigInt"); + + L.push("BIGINT_METAS"); + L.gettable(LUA_REGISTRYINDEX); + L.setmetatable(); + + PUSH_METHOD(BigInt, BIGINT_SET); + PUSH_METHOD(BigInt, BIGINT_TOSTRING); + + PUSH_METHOD(BigInt, BIGINT_ADD); + PUSH_METHOD(BigInt, BIGINT_SUB); + PUSH_METHOD(BigInt, BIGINT_MUL); + PUSH_METHOD(BigInt, BIGINT_DIV); + PUSH_METHOD(BigInt, BIGINT_MOD); +} + +void Balau::registerLuaBigInt(Lua & L) { + LuaBigIntFactory::pushStatics(L); +} -- cgit v1.2.3