summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/llex.js14
-rw-r--r--src/lobject.js2
-rw-r--r--tests/lexparse.js272
3 files changed, 240 insertions, 48 deletions
diff --git a/src/llex.js b/src/llex.js
index f90dc47..dab384d 100644
--- a/src/llex.js
+++ b/src/llex.js
@@ -132,8 +132,8 @@ const save = function(ls, c) {
};
const luaX_token2str = function(ls, token) {
- if (token < FIRST_RESERVED) { /* single-byte symbols? */
- return `'${String.fromCharCode(token)}'`;
+ if (typeof token === "string" || token < FIRST_RESERVED) { /* single-byte symbols? */
+ return `'${typeof token === "string" ? token : String.fromCharCode(token)}'`;
} else {
let s = luaX_tokens[token - FIRST_RESERVED];
if (token < R.TK_EOS) /* fixed format (symbols and reserved words)? */
@@ -266,11 +266,12 @@ const txtToken = function(ls, token) {
const lexerror = function(ls, msg, token) {
msg = ldebug.luaG_addinfo(ls.L, msg, ls.source, ls.linenumber);
if (token)
- lapi.lua_pushstring(ls.L, `${msg} near ${txtToken(ls, token)}`);
+ lapi.lua_pushstring(ls.L, `${msg instanceof TValue ? msg.value : msg} near ${txtToken(ls, token)}`);
ldo.luaD_throw(ls.L, TS.LUA_ERRSYNTAX);
};
const luaX_syntaxerror = function(ls, msg) {
+ msg = msg instanceof TValue ? msg.value : msg;
lexerror(ls, msg, ls.t.token);
};
@@ -584,7 +585,10 @@ const llex = function(ls, seminfo) {
const luaX_next = function(ls) {
ls.lastline = ls.linenumber;
if (ls.lookahead.token !== R.TK_EOS) { /* is there a look-ahead token? */
- ls.t = ls.lookahead; /* use this one */
+ ls.t.token = ls.lookahead.token; /* use this one */
+ ls.t.seminfo.i = ls.lookahead.seminfo.i;
+ ls.t.seminfo.r = ls.lookahead.seminfo.r;
+ ls.t.seminfo.ts = ls.lookahead.seminfo.ts; // TODO ?
ls.lookahead.token = R.TK_EOS; /* and discharge it */
} else
ls.t.token = llex(ls, ls.t.seminfo); /* read next token */
@@ -592,7 +596,7 @@ const luaX_next = function(ls) {
const luaX_lookahead = function(ls) {
assert(ls.lookahead.token === R.TK_EOS);
- ls.lookahead.token = llex(ls. ls.lookahead.seminfo);
+ ls.lookahead.token = llex(ls, ls.lookahead.seminfo);
return ls.lookahead.token;
};
diff --git a/src/lobject.js b/src/lobject.js
index 0ef6e9a..3d9edb0 100644
--- a/src/lobject.js
+++ b/src/lobject.js
@@ -221,6 +221,8 @@ const PRE = "[string \"";
const POS = "\"]";
const luaO_chunkid = function(source, bufflen) {
+ source = source instanceof TValue ? source.value : source;
+ bufflen = bufflen instanceof TValue ? bufflen.value : bufflen;
let l = source.length;
let out = "";
if (source[0] === '=') { /* 'literal' source */
diff --git a/tests/lexparse.js b/tests/lexparse.js
index 500ef76..df7cae8 100644
--- a/tests/lexparse.js
+++ b/tests/lexparse.js
@@ -19,7 +19,7 @@ test('LOADK, RETURN', function (t) {
return a
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -29,9 +29,13 @@ test('LOADK, RETURN', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.strictEqual(
lapi.lua_tostring(L, -1),
@@ -49,7 +53,7 @@ test('MOVE', function (t) {
return b
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -59,9 +63,13 @@ test('MOVE', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.strictEqual(
lapi.lua_tostring(L, -1),
@@ -79,7 +87,7 @@ test('Binary op', function (t) {
return a + b, a - b, a * b, a / b, a % b, a^b, a // b, a & b, a | b, a ~ b, a << b, a >> b
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -89,9 +97,13 @@ test('Binary op', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.deepEqual(
L.stack.slice(L.top - 12, L.top).map(e => e.value),
@@ -109,7 +121,7 @@ test('Unary op, LOADBOOL', function (t) {
return -a, not b, ~a
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -119,9 +131,13 @@ test('Unary op, LOADBOOL', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.deepEqual(
L.stack.slice(L.top - 3, L.top).map(e => e.value),
@@ -137,7 +153,7 @@ test('NEWTABLE', function (t) {
return a
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -147,9 +163,13 @@ test('NEWTABLE', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.ok(
L.stack[lapi.index2addr_(L, -1)] instanceof Table,
@@ -169,7 +189,7 @@ test('CALL', function (t) {
return c
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -179,9 +199,13 @@ test('CALL', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.strictEqual(
lapi.lua_tointeger(L, -1),
@@ -205,7 +229,7 @@ test('Multiple return', function (t) {
return c, d, e
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -215,9 +239,13 @@ test('Multiple return', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.deepEqual(
L.stack.slice(L.top - 3, L.top).map(e => e.value),
@@ -236,7 +264,7 @@ test('TAILCALL', function (t) {
return f(1,2)
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -246,9 +274,13 @@ test('TAILCALL', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.strictEqual(
lapi.lua_tointeger(L, -1),
@@ -267,7 +299,7 @@ test('VARARG', function (t) {
return f(1,2,3)
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -277,9 +309,13 @@ test('VARARG', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.deepEqual(
L.stack.slice(L.top - 3, L.top).map(e => e.value),
@@ -296,7 +332,7 @@ test('LE, JMP', function (t) {
return a >= b
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -306,9 +342,13 @@ test('LE, JMP', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.strictEqual(
lapi.lua_toboolean(L, -1),
@@ -325,7 +365,7 @@ test('LT', function (t) {
return a > b
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -335,9 +375,13 @@ test('LT', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.strictEqual(
lapi.lua_toboolean(L, -1),
@@ -354,7 +398,7 @@ test('EQ', function (t) {
return a == b
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -364,9 +408,13 @@ test('EQ', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.strictEqual(
lapi.lua_toboolean(L, -1),
@@ -384,7 +432,7 @@ test('TESTSET (and)', function (t) {
return a and b
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -394,9 +442,13 @@ test('TESTSET (and)', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.strictEqual(
lapi.lua_tostring(L, -1),
@@ -414,7 +466,7 @@ test('TESTSET (or)', function (t) {
return a or b
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -424,9 +476,13 @@ test('TESTSET (or)', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.strictEqual(
lapi.lua_tostring(L, -1),
@@ -448,7 +504,7 @@ test('TEST (false)', function (t) {
return "goodbye"
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -458,9 +514,13 @@ test('TEST (false)', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.strictEqual(
lapi.lua_tostring(L, -1),
@@ -481,7 +541,7 @@ test('FORPREP, FORLOOP (int)', function (t) {
return total
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -491,9 +551,13 @@ test('FORPREP, FORLOOP (int)', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.strictEqual(
lapi.lua_tointeger(L, -1),
@@ -514,7 +578,7 @@ test('FORPREP, FORLOOP (float)', function (t) {
return total
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -524,9 +588,13 @@ test('FORPREP, FORLOOP (float)', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.strictEqual(
lapi.lua_tonumber(L, -1),
@@ -546,7 +614,7 @@ test('SETTABLE, GETTABLE', function (t) {
return t
`, L;
- t.plan(3);
+ t.plan(4);
t.doesNotThrow(function () {
@@ -556,9 +624,13 @@ test('SETTABLE, GETTABLE', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.strictEqual(
lapi.lua_topointer(L, -1).get(0).value,
@@ -587,7 +659,7 @@ test('SETUPVAL, GETUPVAL', function (t) {
return f()
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -597,9 +669,13 @@ test('SETUPVAL, GETUPVAL', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.strictEqual(
lapi.lua_tostring(L, -1),
@@ -619,7 +695,7 @@ test('SETTABUP, GETTABUP', function (t) {
return t
`, L;
- t.plan(3);
+ t.plan(4);
t.doesNotThrow(function () {
@@ -629,9 +705,13 @@ test('SETTABUP, GETTABUP', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
+ }, "Lua program ran without error");
t.strictEqual(
lapi.lua_topointer(L, -1).get(0).value,
@@ -659,7 +739,7 @@ test('SELF', function (t) {
return t:get()
`, L;
- t.plan(2);
+ t.plan(3);
t.doesNotThrow(function () {
@@ -669,13 +749,119 @@ test('SELF', function (t) {
lapi.lua_load(L, null, luaCode, "test", "text");
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
lapi.lua_call(L, 0, -1);
- }, "JS Lua program ran without error");
-
+ }, "Lua program ran without error");
+
t.strictEqual(
lapi.lua_tostring(L, -1),
"hello",
"Program output is correct"
);
+});
+
+
+test('SETLIST', function (t) {
+ let luaCode = `
+ local t = {1, 2, 3, 4, 5, 6, 7, 8, 9}
+
+ return t
+ `, L;
+
+ t.plan(3);
+
+ t.doesNotThrow(function () {
+
+ L = lauxlib.luaL_newstate();
+
+ linit.luaL_openlibs(L);
+
+ lapi.lua_load(L, null, luaCode, "test", "text");
+
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
+ lapi.lua_call(L, 0, -1);
+
+ }, "Lua program ran without error");
+
+ t.deepEqual(
+ [...lapi.lua_topointer(L, -1).entries()].map(e => e[1].value).sort(),
+ [1, 2, 3, 4, 5, 6, 7, 8, 9],
+ "Program output is correct"
+ );
+});
+
+
+test('Variable SETLIST', function (t) {
+ let luaCode = `
+ local a = function ()
+ return 6, 7, 8, 9
+ end
+
+ local t = {1, 2, 3, 4, 5, a()}
+
+ return t
+ `, L;
+
+ t.plan(3);
+
+ t.doesNotThrow(function () {
+
+ L = lauxlib.luaL_newstate();
+
+ linit.luaL_openlibs(L);
+
+ lapi.lua_load(L, null, luaCode, "test", "text");
+
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
+ lapi.lua_call(L, 0, -1);
+
+ }, "Lua program ran without error");
+
+ t.deepEqual(
+ [...lapi.lua_topointer(L, -1).entries()].map(e => e[1].value).sort(),
+ [1, 2, 3, 4, 5, 6, 7, 8, 9],
+ "Program output is correct"
+ );
+});
+
+test('Long SETLIST', function (t) {
+ let luaCode = `
+ local t = {1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5}
+
+ return t
+ `, L;
+
+ t.plan(3);
+
+ t.doesNotThrow(function () {
+
+ L = lauxlib.luaL_newstate();
+
+ linit.luaL_openlibs(L);
+
+ lapi.lua_load(L, null, luaCode, "test", "text");
+
+ }, "Lua program loaded without error");
+
+ t.doesNotThrow(function () {
+
+ lapi.lua_call(L, 0, -1);
+
+ }, "Lua program ran without error");
+
+ t.deepEqual(
+ [...lapi.lua_topointer(L, -1).entries()].map(e => e[1].value).reverse(),
+ [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5],
+ "Program output is correct"
+ );
}); \ No newline at end of file