summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Giannangeli <benoit.giannangeli@boursorama.fr>2017-02-22 08:23:37 +0100
committerBenoit Giannangeli <benoit.giannangeli@boursorama.fr>2017-02-22 08:23:37 +0100
commitdbe2a3bf2ef8c053e6c596c99e29eb27b6118f1b (patch)
tree4920ab827f35d0305a951fde5d627cc8c767b4fe /src
parentc1824a99035a231172f3c10ae3ee24a3e6330260 (diff)
downloadfengari-dbe2a3bf2ef8c053e6c596c99e29eb27b6118f1b.tar.gz
fengari-dbe2a3bf2ef8c053e6c596c99e29eb27b6118f1b.tar.bz2
fengari-dbe2a3bf2ef8c053e6c596c99e29eb27b6118f1b.zip
ipairs
Diffstat (limited to 'src')
-rw-r--r--src/lapi.js15
-rw-r--r--src/lbaselib.js39
2 files changed, 54 insertions, 0 deletions
diff --git a/src/lapi.js b/src/lapi.js
index c091150..e149619 100644
--- a/src/lapi.js
+++ b/src/lapi.js
@@ -426,6 +426,20 @@ const lua_getfield = function(L, idx, k) {
return auxgetstr(L, index2addr(L, idx), k);
};
+const lua_geti = function(L, idx, n) {
+ let t = index2addr(L, idx);
+ let slot = t.__index(t, n);
+ if (!slot.ttisnil()) {
+ L.stack[L.top++] = slot;
+ assert(L.top <= L.ci.top, "stack overflow");
+ } else {
+ L.stack[L.top++] = new TValue(CT.LUA_TNUMINT, n);
+ assert(L.top <= L.ci.top, "stack overflow");
+ lvm.gettable(L, t, L.stack[L.top - 1], L.top - 1);
+ }
+ return L.stack[L.top - 1].ttnov();
+};
+
const lua_getglobal = function(L, name) {
return auxgetstr(L, L.l_G.l_registry.value.array[lua.LUA_RIDX_GLOBALS - 1], name);
};
@@ -651,6 +665,7 @@ module.exports.lua_createtable = lua_createtable;
module.exports.lua_newtable = lua_newtable;
module.exports.lua_settable = lua_settable;
module.exports.lua_gettable = lua_gettable;
+module.exports.lua_geti = lua_geti;
module.exports.lua_absindex = lua_absindex;
module.exports.index2addr = index2addr;
module.exports.lua_rawget = lua_rawget;
diff --git a/src/lbaselib.js b/src/lbaselib.js
index b3dcd12..d0e094f 100644
--- a/src/lbaselib.js
+++ b/src/lbaselib.js
@@ -89,6 +89,44 @@ const luaB_type = function(L) {
return 1;
};
+const pairsmeta = function(L, method, iszero, iter) {
+ lauxlib.luaL_checkany(L, 1);
+ if (lauxlib.luaL_getmetafield(L, 1, method).ttisnil()) { /* no metamethod? */
+ lapi.lua_pushcfunction(L, iter); /* will return generator, */
+ lapi.lua_pushvalue(L, 1); /* state, */
+ if (iszero) lapi.lua_pushinteger(L, 0); /* and initial value */
+ else lapi.lua_pushnil(L);
+ } else {
+ lapi.lua_pushvalue(L, 1); /* argument 'self' to metamethod */
+ lapi.lua_call(L, 1, 3); /* get 3 values from metamethod */
+ }
+ return 3;
+};
+
+/*
+** Traversal function for 'ipairs'
+*/
+const ipairsaux = function(L) {
+ let i = lauxlib.luaL_checkinteger(L, 2) + 1;
+ lapi.lua_pushinteger(L, i);
+ return lapi.lua_geti(L, 1, i) === CT.LUA_TNIL ? 1 : 2;
+};
+
+/*
+** 'ipairs' function. Returns 'ipairsaux', given "table", 0.
+** (The given "table" may not be a table.)
+*/
+const luaB_ipairs = function(L) {
+ // Lua 5.2
+ // return pairsmeta(L, "__ipairs", 1, ipairsaux);
+
+ lauxlib.luaL_checkany(L, 1);
+ lapi.lua_pushcfunction(L, ipairsaux); /* iteration function */
+ lapi.lua_pushvalue(L, 1); /* state */
+ lapi.lua_pushinteger(L, 0); /* initial value */
+ return 3;
+};
+
const luaB_error = function(L) {
let level = lauxlib.luaL_optinteger(L, 2, 1);
lapi.lua_settop(L, 1);
@@ -144,6 +182,7 @@ const base_funcs = {
"print": luaB_print,
"tostring": luaB_tostring,
"getmetatable": luaB_getmetatable,
+ "ipairs": luaB_ipairs,
"setmetatable": luaB_setmetatable,
"rawequal": luaB_rawequal,
"rawset": luaB_rawset,