aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml3
-rw-r--r--README.md2
-rw-r--r--src/lauxlib.js4
-rw-r--r--src/ltablib.js30
-rw-r--r--tests/ltablib.js34
5 files changed, 68 insertions, 5 deletions
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