summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNicolas "Pixel" Noble <pixel@nobis-crew.org>2013-08-12 06:59:03 +0200
committerNicolas "Pixel" Noble <pixel@nobis-crew.org>2013-08-12 06:59:03 +0200
commit68e2e03838a475252e519a7a16a9bcb2e3e4dd62 (patch)
treec3f059fc59c4221fda81f006a578b5b4fe7643bb /src
parent0d528cd7be88272ac9ce33641ab80a7fd0600f0a (diff)
Adding LuaBigInt and a few more things.
Diffstat (limited to 'src')
-rw-r--r--src/BLua.cc25
-rw-r--r--src/LuaBigInt.cc210
2 files changed, 234 insertions, 1 deletions
diff --git a/src/BLua.cc b/src/BLua.cc
index eee663b..886f92e 100644
--- a/src/BLua.cc
+++ b/src/BLua.cc
@@ -838,6 +838,29 @@ bool Balau::Lua::resume(int nargs) throw (GeneralException) {
}
}
+void Balau::Lua::pcall(int nargs) throw (GeneralException) {
+ int r = lua_pcall(L, nargs, LUA_MULTRET, 0);
+
+ if (r == 0)
+ return;
+
+ pushLuaContext();
+ showerror();
+
+ switch(r) {
+ case LUA_ERRRUN:
+ throw LuaException("Runtime error while running LUA code.");
+ case LUA_ERRMEM:
+ throw LuaException("Memory allocation error while running LUA code.");
+ case LUA_ERRERR:
+ throw LuaException("Error in Error function.");
+ case LUA_ERRSYNTAX:
+ throw LuaException("Syntax error in Lua code.");
+ default:
+ throw LuaException(String("Unknow error while running LUA code (err code: ") + String(r) + ")");
+ }
+}
+
bool Balau::Lua::resumeC(int & nargs) {
if (!yielded())
return false;
@@ -1016,7 +1039,7 @@ Balau::LuaObjectBase * Balau::LuaObjectFactory::getMeInternal(Lua & L, int i) {
if (L.istable(i)) {
L.push("__obj");
- L.gettable(i, true);
+ L.gettable(i < 0 ? i - 1 : i, true);
if (!(o = (LuaObjectBase *) L.touserdata()))
L.error("Table is not an object.");
L.pop();
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<BigInt>();
+ {
+ LuaBigIntFactory cf(c = new BigInt());
+ cf.pushDestruct(L);
+ }
+ *c = *a + *b;
+ r = 1;
+ break;
+ case BIGINT_SUB:
+ b = L.recast<BigInt>();
+ {
+ LuaBigIntFactory cf(c = new BigInt());
+ cf.pushDestruct(L);
+ }
+ *c = *a - *b;
+ r = 1;
+ break;
+ case BIGINT_MUL:
+ b = L.recast<BigInt>();
+ {
+ LuaBigIntFactory cf(c = new BigInt());
+ cf.pushDestruct(L);
+ }
+ *c = *a * *b;
+ r = 1;
+ break;
+ case BIGINT_DIV:
+ b = L.recast<BigInt>();
+ {
+ LuaBigIntFactory cf(c = new BigInt());
+ cf.pushDestruct(L);
+ }
+ *c = *a / *b;
+ r = 1;
+ break;
+ case BIGINT_MOD:
+ b = L.recast<BigInt>();
+ {
+ 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);
+}