diff options
| author | Benoit Giannangeli <benoit.giannangeli@boursorama.fr> | 2017-02-22 08:23:37 +0100 | 
|---|---|---|
| committer | Benoit Giannangeli <benoit.giannangeli@boursorama.fr> | 2017-02-22 08:23:37 +0100 | 
| commit | dbe2a3bf2ef8c053e6c596c99e29eb27b6118f1b (patch) | |
| tree | 4920ab827f35d0305a951fde5d627cc8c767b4fe /src | |
| parent | c1824a99035a231172f3c10ae3ee24a3e6330260 (diff) | |
| download | fengari-dbe2a3bf2ef8c053e6c596c99e29eb27b6118f1b.tar.gz fengari-dbe2a3bf2ef8c053e6c596c99e29eb27b6118f1b.tar.bz2 fengari-dbe2a3bf2ef8c053e6c596c99e29eb27b6118f1b.zip  | |
ipairs
Diffstat (limited to 'src')
| -rw-r--r-- | src/lapi.js | 15 | ||||
| -rw-r--r-- | src/lbaselib.js | 39 | 
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,  | 
