From ae4e53e2e7234a167058199085921a9182e8522a Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Fri, 24 Feb 2017 08:52:06 +0100 Subject: table.insert --- .travis.yml | 3 +++ README.md | 2 +- src/lauxlib.js | 4 ++-- src/ltablib.js | 30 ++++++++++++++++++++++++++++-- tests/ltablib.js | 34 ++++++++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..4796715 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "node" \ No newline at end of file diff --git a/README.md b/README.md index 16d967a..c6cae01 100644 --- a/README.md +++ b/README.md @@ -207,7 +207,7 @@ - [x] table.concat - [x] table.pack - [x] table.unpack - - [ ] table.insert + - [x] table.insert - [ ] table.move - [ ] table.remove - [ ] table.sort diff --git a/src/lauxlib.js b/src/lauxlib.js index ba720af..3774309 100644 --- a/src/lauxlib.js +++ b/src/lauxlib.js @@ -53,7 +53,7 @@ const findfield = function(L, objidx, level) { */ const pushglobalfuncname = function(L, ar) { let top = lapi.lua_gettop(L); - lapi.lua_getinfo(L, 'f', ar); /* push function */ + ldebug.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); @@ -76,7 +76,7 @@ const panic = function(L) { const luaL_argerror = function(L, arg, extramsg) { let ar = new lua.lua_Debug(); - if (!lapi.lua_getstack(L, 0, ar)) /* no stack frame? */ + if (!ldebug.lua_getstack(L, 0, ar)) /* no stack frame? */ return luaL_error(L, 'bad argument #%d (%s)', arg, extramsg); ldebug.lua_getinfo(L, 'n', ar); diff --git a/src/ltablib.js b/src/ltablib.js index 86b57d7..8ea6f08 100644 --- a/src/ltablib.js +++ b/src/ltablib.js @@ -47,7 +47,7 @@ const checktab = function(L, arg, what) { const aux_getn = function(L, n, w) { checktab(L, n, w | TAB_L); - lauxlib.luaL_len(L, n); + return lauxlib.luaL_len(L, n); }; const addfield = function(L, b, i) { @@ -58,6 +58,31 @@ const addfield = function(L, b, i) { lauxlib.luaL_addvalue(b); }; +const tinsert = function(L) { + let e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */ + let pos; + switch (lapi.lua_gettop(L)) { + case 2: + pos = e; + break; + case 3: { + pos = lauxlib.luaL_checkinteger(L, 2); /* 2nd argument is the position */ + lauxlib.luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); + for (let i = e; i > pos; i--) { /* move up elements */ + lapi.lua_geti(L, 1, i - 1); + lapi.lua_seti(L, 1, i); /* t[i] = t[i - 1] */ + } + break; + } + default: { + return lauxlib.luaL_error(L, "wrong number of arguments to 'insert'"); + } + } + + lapi.lua_seti(L, 1, pos); /* t[pos] = v */ + return 0; +}; + const tconcat = function(L) { let last = aux_getn(L, 1, TAB_R); let sep = lauxlib.luaL_optlstring(L, 2, ""); @@ -106,8 +131,9 @@ const unpack = function(L) { const tab_funcs = { "concat": tconcat, + "insert": tinsert, "pack": pack, - "unpack": unpack, + "unpack": unpack }; const luaopen_table = function(L) { diff --git a/tests/ltablib.js b/tests/ltablib.js index 8221fe0..1a04e4c 100644 --- a/tests/ltablib.js +++ b/tests/ltablib.js @@ -116,4 +116,38 @@ test('table.unpack', function (t) { 4, "Correct element(s) on the stack" ); +}); + + +test('table.insert', function (t) { + let luaCode = ` + local t = {1, 3, 4} + table.insert(t, 5) + table.insert(t, 2, 2) + return t + `, L; + + t.plan(2); + + t.doesNotThrow(function () { + + let bc = toByteCode(luaCode).dataView; + + L = lauxlib.luaL_newstate(); + + linit.luaL_openlibs(L); + + lapi.lua_load(L, bc, "test-table.insert"); + + lapi.lua_call(L, 0, -1); + + }, "JS Lua program ran without error"); + + t.deepEqual( + [...lapi.lua_topointer(L, -1).entries()] + .filter(e => typeof e[0] === 'number') // Filter out the 'n' field + .map(e => e[1].value).sort(), + [1, 2, 3, 4, 5], + "Correct element(s) on the stack" + ); }); \ No newline at end of file -- cgit v1.2.3-54-g00ecf