From 8785e3801b3bd4b3add20f004c9492565fb77fbd Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Thu, 2 Mar 2017 11:56:54 +0100 Subject: [Parsing tests] SETLIST --- src/llex.js | 14 ++- src/lobject.js | 2 + tests/lexparse.js | 272 +++++++++++++++++++++++++++++++++++++++++++++--------- 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 -- cgit v1.2.3-70-g09d2