summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lapi.js13
-rw-r--r--src/lauxlib.js92
-rw-r--r--src/ltable.js4
3 files changed, 88 insertions, 21 deletions
diff --git a/src/lapi.js b/src/lapi.js
index 76dee1b..625608b 100644
--- a/src/lapi.js
+++ b/src/lapi.js
@@ -149,6 +149,12 @@ const lua_rotate = function(L, idx, n) {
reverse(L, pIdx, L.top - 1);
};
+const lua_copy = function(L, fromidx, toidx) {
+ let fr = index2addr_(L, fromidx);
+ let to = index2addr_(L, toidx);
+ L.stack[to] = fr;
+};
+
const lua_remove = function(L, idx) {
lua_rotate(L, idx, -1);
lua_pop(L, 1);
@@ -647,6 +653,10 @@ const lua_error = function(L) {
ldebug.luaG_errormsg(L);
};
+const lua_next = function(L, idx) {
+
+};
+
const lua_concat = function(L, n) {
assert(n < L.top - L.ci.funcOff, "not enough elements in the stack");
if (n >= 2)
@@ -729,4 +739,5 @@ module.exports.lua_insert = lua_insert;
module.exports.lua_gc = lua_gc;
module.exports.lua_getallocf = lua_getallocf;
module.exports.lua_getextraspace = lua_getextraspace;
-module.exports.lua_stringtonumber = lua_stringtonumber; \ No newline at end of file
+module.exports.lua_stringtonumber = lua_stringtonumber;
+module.exports.lua_copy = lua_copy; \ No newline at end of file
diff --git a/src/lauxlib.js b/src/lauxlib.js
index e295fe6..4e32437 100644
--- a/src/lauxlib.js
+++ b/src/lauxlib.js
@@ -11,29 +11,80 @@ const CT = lua.constant_types;
const LUA_LOADED_TABLE = "_LOADED"
+
+/*
+** search for 'objidx' in table at index -1.
+** return 1 + string at top if find a good name.
+*/
+const findfield = function(L, objidx, level) {
+ if (level === 0 || !lapi.lua_istable(L, -1))
+ return 0; /* not found */
+
+ lapi.lua_pushnil(L); /* start 'next' loop */
+
+ while (lapi.lua_next(L, -2)) { /* for each pair in table */
+ if (lapi.lua_type(L, -2) === CT.LUA_TSTRING) { /* ignore non-string keys */
+ if (lapi.lua_rawequal(L, objidx, -1)) { /* found object? */
+ lapi.lua_pop(L, 1); /* remove value (but keep name) */
+ return 1;
+ } else if (findfield(L, objidx, level - 1)) { /* try recursively */
+ lapi.lua_remove(L, -2); /* remove table (but keep name) */
+ lapi.lua_pushliteral(L, ".");
+ lapi.lua_insert(L, -2); /* place '.' between the two names */
+ lapi.lua_concat(L, 3);
+ return 1;
+ }
+ }
+ lapi.lua_pop(L, 1); /* remove value */
+ }
+
+ return 0; /* not found */
+};
+
+/*
+** Search for a name for a function in all loaded modules
+*/
+const pushglobalfuncname = function(L, ar) {
+ let top = lapi.lua_gettop(L);
+ lapi.lua_getinfo(L, 'f', ar); /* push function */
+ lapi.lua_getfield(L, lua.LUA_REGISTRYINDEX, lua.LUA_LOADED_TABLE);
+ if (findfield(L, top + 1, 2)) {
+ let name = lapi.lua_tostring(L, -1);
+ if (name.startsWith("_G.")) {
+ lapi.lua_pushstring(L, name.slice(3)); /* name start with '_G.'? */
+ lapi.lua_remove(L, -2); /* name start with '_G.'? */
+ }
+ lapi.lua_copy(L, -1, top + 1); /* name start with '_G.'? */
+ lapi.lua_pop(L, 2); /* name start with '_G.'? */
+ } else {
+ lapi.lua_settop(L, top); /* remove function and global table */
+ return 0;
+ }
+};
+
const panic = function(L) {
throw new Error(`PANIC: unprotected error in call to Lua API (${lapi.lua_tostring(L, -1)})`);
};
-// const luaL_argerror = function(L, arg, extramsg) {
-// let ar = new lua.lua_Debug();
-//
-// if (!lapi.lua_getstack(L, 0, ar)) /* no stack frame? */
-// return luaL_error(L, 'bad argument #%d (%s)', arg, extramsg);
-//
-// ldebug.lua_getinfo(L, 'n', ar);
-//
-// if (ar.namewhat === 'method') {
-// arg--; /* do not count 'self' */
-// if (arg === 0) /* error is in the self argument itself? */
-// return luaL_error(L, "calling '%s' on bad self (%s)", ar.name, extramsg);
-// }
-//
-// if (ar.name === null)
-// ar.name = pushglobalfuncname(L, ar) ? lapi.lua_tostring(L, -1) : "?";
-//
-// return luaL_error(L, "bad argument #%d to '%s' (%s)", arg, ar.name, extramsg);
-// };
+const luaL_argerror = function(L, arg, extramsg) {
+ let ar = new lua.lua_Debug();
+
+ if (!lapi.lua_getstack(L, 0, ar)) /* no stack frame? */
+ return luaL_error(L, 'bad argument #%d (%s)', arg, extramsg);
+
+ ldebug.lua_getinfo(L, 'n', ar);
+
+ if (ar.namewhat === 'method') {
+ arg--; /* do not count 'self' */
+ if (arg === 0) /* error is in the self argument itself? */
+ return luaL_error(L, "calling '%s' on bad self (%s)", ar.name, extramsg);
+ }
+
+ if (ar.name === null)
+ ar.name = pushglobalfuncname(L, ar) ? lapi.lua_tostring(L, -1) : "?";
+
+ return luaL_error(L, `bad argument #${arg} to '${ar.name}' (${extramsg})`);
+};
const typeerror = function(L, arg, tname) {
let typearg;
@@ -282,4 +333,5 @@ module.exports.luaL_checkinteger = luaL_checkinteger;
module.exports.luaL_optinteger = luaL_optinteger;
module.exports.luaL_opt = luaL_opt;
module.exports.luaL_where = luaL_where;
-module.exports.luaL_error = luaL_error; \ No newline at end of file
+module.exports.luaL_error = luaL_error;
+module.exports.luaL_argerror = luaL_argerror; \ No newline at end of file
diff --git a/src/ltable.js b/src/ltable.js
index 95ca5a5..c1d5430 100644
--- a/src/ltable.js
+++ b/src/ltable.js
@@ -31,4 +31,8 @@ Table.prototype.luaH_getn = function() {
else if (hash.size === 0)
return j;
else return hash.get(j);
+};
+
+Table.prototype.luaH_next = function(key) {
+
}; \ No newline at end of file