From d3530bdc202419c85ec79fdb01197112cab8a788 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Thu, 23 Mar 2017 15:46:09 +0100 Subject: strings.lua --- src/lapi.js | 4 ++-- src/lauxlib.js | 4 ++-- src/lmathlib.js | 6 ++--- src/lobject.js | 28 +++++++++++----------- src/lstrlib.js | 14 +++++------ src/luaconf.js | 4 ++-- src/lvm.js | 44 +++++++++++++++++----------------- tests/load.js | 4 +--- tests/lua.js | 33 +++++++++++++++++++++++++ tests/single.lua | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 159 insertions(+), 55 deletions(-) create mode 100644 tests/lua.js create mode 100644 tests/single.lua diff --git a/src/lapi.js b/src/lapi.js index 991e982..5064c30 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -209,7 +209,7 @@ const lua_pushnumber = function(L, n) { const lua_pushinteger = function(L, n) { assert(typeof n === "number"); - L.stack[L.top++] = new TValue(CT.LUA_TNUMINT, n|0); + L.stack[L.top++] = new TValue(CT.LUA_TNUMINT, n); assert(L.top <= L.ci.top, "stack overflow"); }; @@ -959,4 +959,4 @@ module.exports.lua_touserdata = lua_touserdata; module.exports.lua_type = lua_type; module.exports.lua_typename = lua_typename; module.exports.lua_version = lua_version; -module.exports.lua_xmove = lua_xmove; \ No newline at end of file +module.exports.lua_xmove = lua_xmove; diff --git a/src/lauxlib.js b/src/lauxlib.js index f175fde..c2852ac 100644 --- a/src/lauxlib.js +++ b/src/lauxlib.js @@ -165,7 +165,7 @@ const luaL_checkstring = function(L, n) { const luaL_checklstring = function(L, arg) { let s = lapi.lua_tolstring(L, arg); - if (!s) tag_error(L, arg, CT.LUA_TSTRING); + if (typeof s !== "string") tag_error(L, arg, CT.LUA_TSTRING); return s; }; @@ -577,4 +577,4 @@ module.exports.luaL_requiref = luaL_requiref; module.exports.luaL_setfuncs = luaL_setfuncs; module.exports.luaL_tolstring = luaL_tolstring; module.exports.luaL_typename = luaL_typename; -module.exports.luaL_where = luaL_where; \ No newline at end of file +module.exports.luaL_where = luaL_where; diff --git a/src/lmathlib.js b/src/lmathlib.js index 55f8416..724ad75 100644 --- a/src/lmathlib.js +++ b/src/lmathlib.js @@ -268,11 +268,11 @@ const luaopen_math = function(L) { lapi.lua_setfield(L, -2, "pi"); lapi.lua_pushnumber(L, Number.MAX_VALUE); lapi.lua_setfield(L, -2, "huge"); - lapi.lua_pushnumber(L, Number.MAX_SAFE_INTEGER); + lapi.lua_pushinteger(L, Number.MAX_SAFE_INTEGER); lapi.lua_setfield(L, -2, "maxinteger"); - lapi.lua_pushnumber(L, Number.MIN_SAFE_INTEGER); + lapi.lua_pushinteger(L, Number.MIN_SAFE_INTEGER); lapi.lua_setfield(L, -2, "mininteger"); return 1; }; -module.exports.luaopen_math = luaopen_math; \ No newline at end of file +module.exports.luaopen_math = luaopen_math; diff --git a/src/lobject.js b/src/lobject.js index 8fc587d..c2950b6 100644 --- a/src/lobject.js +++ b/src/lobject.js @@ -424,18 +424,18 @@ const luaO_int2fb = function(x) { const intarith = function(L, op, v1, v2) { switch (op) { - case lua.LUA_OPADD: return (v1 + v2)|0; - case lua.LUA_OPSUB: return (v1 - v2)|0; - case lua.LUA_OPMUL: return (v1 * v2)|0; - case lua.LUA_OPMOD: return (v1 % v2)|0; - case lua.LUA_OPIDIV: return (v1 / v2)|0; - case lua.LUA_OPBAND: return (v1 & v2)|0; - case lua.LUA_OPBOR: return (v1 | v2)|0; - case lua.LUA_OPBXOR: return (v1 ^ v2)|0; - case lua.LUA_OPSHL: return (v1 << v2)|0; - case lua.LUA_OPSHR: return (v1 >> v2)|0; - case lua.LUA_OPUNM: return (-v1)|0; - case lua.LUA_OPBNOT: return (~v1)|0; + case lua.LUA_OPADD: return (v1 + v2); + case lua.LUA_OPSUB: return (v1 - v2); + case lua.LUA_OPMUL: return (v1 * v2); + case lua.LUA_OPMOD: return (v1 % v2); + case lua.LUA_OPIDIV: return (v1 / v2); + case lua.LUA_OPBAND: return (v1 & v2); + case lua.LUA_OPBOR: return (v1 | v2); + case lua.LUA_OPBXOR: return (v1 ^ v2); + case lua.LUA_OPSHL: return (v1 << v2); + case lua.LUA_OPSHR: return (v1 >> v2); + case lua.LUA_OPUNM: return (-v1); + case lua.LUA_OPBNOT: return (~v1); } }; @@ -447,7 +447,7 @@ const numarith = function(L, op, v1, v2) { case lua.LUA_OPMUL: return v1 * v2; case lua.LUA_OPDIV: return v1 / v2; case lua.LUA_OPPOW: return Math.pow(v1, v2); - case lua.LUA_OPIDIV: return (v1 / v2)|0; + case lua.LUA_OPIDIV: return (v1 / v2); case lua.LUA_OPUNM: return -v1; case lua.LUA_OPMOD: return v1 % v2; } @@ -465,4 +465,4 @@ module.exports.luaO_hexavalue = luaO_hexavalue; module.exports.luaO_int2fb = luaO_int2fb; module.exports.luaO_str2num = luaO_str2num; module.exports.luaO_utf8desc = luaO_utf8desc; -module.exports.numarith = numarith; \ No newline at end of file +module.exports.numarith = numarith; diff --git a/src/lstrlib.js b/src/lstrlib.js index 95fb375..c6c0dc3 100644 --- a/src/lstrlib.js +++ b/src/lstrlib.js @@ -109,7 +109,7 @@ const ldexp = function(mantissa, exponent) { ** Add integer part of 'x' to buffer and return new 'x' */ const adddigit = function(buff, n, x) { - let d = Math.floor(x)|0; /* get integer part from 'x' */ + let d = Math.floor(x); /* get integer part from 'x' */ buff[n] = d < 10 ? d + '0'.charCodeAt(0) : d - 10 + 'a'.charCodeAt(0); /* add to buffer */ return x - d; /* return what is left */ }; @@ -233,7 +233,7 @@ const addliteral = function(L, b, arg) { } else { /* integers */ let n = lapi.lua_tointeger(L, arg); let format = (n === Number.MIN_SAFE_INTEGER) ? `0x%${luaconf.LUA_INTEGER_FRMLEN}x` : luaconf.LUA_INTEGER_FMT; - buff.b += sprintf(format, n|0); + buff.b += sprintf(format, n); } break; } @@ -319,7 +319,7 @@ const str_format = function(L) { strfrmt = strfrmt.slice(1); let n = lauxlib.luaL_checkinteger(L, arg); form = addlenmod(form, luaconf.LUA_INTEGER_FRMLEN.split('').map(e => e.charCodeAt(0))); - buff.b += sprintf(String.fromCharCode(...form), n|0); + buff.b += sprintf(String.fromCharCode(...form), n); break; } case 'a': case 'A': { @@ -1177,16 +1177,16 @@ const str_find_aux = function(L, find) { let init = posrelat(lauxlib.luaL_optinteger(L, 3, 1), ls); if (init < 1) init = 1; else if (init > ls + 1) { /* start after string's end? */ - lauxlib.lua_pushnil(L); /* cannot find anything */ + lapi.lua_pushnil(L); /* cannot find anything */ return 1; } /* explicit request or no special characters? */ if (find && (lapi.lua_toboolean(L, 4) || nospecials(p, lp))) { /* do a plain search */ - let f = s.indexOf(p); + let f = s.slice(init - 1).indexOf(p); if (f > -1) { - lapi.lua_pushinteger(L, f + 1); - lapi.lua_pushinteger(L, f + lp); + lapi.lua_pushinteger(L, init + f); + lapi.lua_pushinteger(L, init + f + lp - 1); return 2; } } else { diff --git a/src/luaconf.js b/src/luaconf.js index fc96224..a965954 100644 --- a/src/luaconf.js +++ b/src/luaconf.js @@ -17,7 +17,7 @@ const LUAI_MAXSTACK = 1000000; const LUA_IDSIZE = 60; const lua_numbertointeger = function(n) { - return n|0; + return n; }; const LUA_INTEGER_FRMLEN = ""; @@ -37,4 +37,4 @@ module.exports.LUA_INTEGER_FRMLEN = LUA_INTEGER_FRMLEN; module.exports.LUA_NUMBER_FMT = LUA_NUMBER_FMT; module.exports.LUA_NUMBER_FRMLEN = LUA_NUMBER_FRMLEN; module.exports.lua_getlocaledecpoint = lua_getlocaledecpoint; -module.exports.lua_numbertointeger = lua_numbertointeger; \ No newline at end of file +module.exports.lua_numbertointeger = lua_numbertointeger; diff --git a/src/lvm.js b/src/lvm.js index 873cd20..b48d5b6 100644 --- a/src/lvm.js +++ b/src/lvm.js @@ -222,7 +222,7 @@ const luaV_execute = function(L) { let numberop2 = tonumber(op2); if (op1.ttisinteger() && op2.ttisinteger()) { - L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value + op2.value)|0); + L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value + op2.value)); } else if (numberop1 !== false && numberop2 !== false) { L.stack[ra] = new TValue(CT.LUA_TNUMFLT, op1.value + op2.value); } else { @@ -238,7 +238,7 @@ const luaV_execute = function(L) { let numberop2 = tonumber(op2); if (op1.ttisinteger() && op2.ttisinteger()) { - L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value - op2.value)|0); + L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value - op2.value)); } else if (numberop1 !== false && numberop2 !== false) { L.stack[ra] = new TValue(CT.LUA_TNUMFLT, op1.value - op2.value); } else { @@ -254,7 +254,7 @@ const luaV_execute = function(L) { let numberop2 = tonumber(op2); if (op1.ttisinteger() && op2.ttisinteger()) { - L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value * op2.value)|0); + L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value * op2.value)); } else if (numberop1 !== false && numberop2 !== false) { L.stack[ra] = new TValue(CT.LUA_TNUMFLT, k[i.B].value * op2.value); } else { @@ -270,7 +270,7 @@ const luaV_execute = function(L) { let numberop2 = tonumber(op2); if (op1.ttisinteger() && op2.ttisinteger()) { - L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value % op2.value)|0); + L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value % op2.value)); } else if (numberop1 !== false && numberop2 !== false) { L.stack[ra] = new TValue(CT.LUA_TNUMFLT, k[i.B].value % op2.value); } else { @@ -314,9 +314,9 @@ const luaV_execute = function(L) { let numberop2 = tonumber(op2); if (op1.ttisinteger() && op2.ttisinteger()) { - L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value / op2.value)|0); + L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value / op2.value)); } else if (numberop1 !== false && numberop2 !== false) { - L.stack[ra] = new TValue(CT.LUA_TNUMFLT, (op1.value / op2.value)|0); + L.stack[ra] = new TValue(CT.LUA_TNUMFLT, (op1.value / op2.value)); } else { ltm.luaT_trybinTM(L, op1, op2, ra, ltm.TMS.TM_IDIV); base = ci.u.l.base; @@ -330,7 +330,7 @@ const luaV_execute = function(L) { let numberop2 = tonumber(op2); if (op1.ttisinteger() && op2.ttisinteger()) { - L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value & op2.value)|0); + L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value & op2.value)); } else { ltm.luaT_trybinTM(L, op1, op2, ra, ltm.TMS.TM_BAND); base = ci.u.l.base; @@ -344,7 +344,7 @@ const luaV_execute = function(L) { let numberop2 = tonumber(op2); if (op1.ttisinteger() && op2.ttisinteger()) { - L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value | op2.value)|0); + L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value | op2.value)); } else { ltm.luaT_trybinTM(L, op1, op2, ra, ltm.TMS.TM_BOR); base = ci.u.l.base; @@ -358,7 +358,7 @@ const luaV_execute = function(L) { let numberop2 = tonumber(op2); if (op1.ttisinteger() && op2.ttisinteger()) { - L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value ^ op2.value)|0); + L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value ^ op2.value)); } else { ltm.luaT_trybinTM(L, op1, op2, ra, ltm.TMS.TM_BXOR); base = ci.u.l.base; @@ -372,7 +372,7 @@ const luaV_execute = function(L) { let numberop2 = tonumber(op2); if (op1.ttisinteger() && op2.ttisinteger()) { - L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value << op2.value)|0); + L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value << op2.value)); } else { ltm.luaT_trybinTM(L, op1, op2, ra, ltm.TMS.TM_SHL); base = ci.u.l.base; @@ -386,7 +386,7 @@ const luaV_execute = function(L) { let numberop2 = tonumber(op2); if (op1.ttisinteger() && op2.ttisinteger()) { - L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value >> op2.value)|0); + L.stack[ra] = new TValue(CT.LUA_TNUMINT, (op1.value >> op2.value)); } else { ltm.luaT_trybinTM(L, op1, op2, ra, ltm.TMS.TM_SHR); base = ci.u.l.base; @@ -716,14 +716,14 @@ const donextjump = function(L, ci) { const luaV_lessthan = function(L, l, r) { if (l.ttisnumber() && r.ttisnumber()) - return LTnum(l, r); + return LTnum(l, r) ? 1 : 0; else if (l.ttisstring() && r.ttisstring()) - return l_strcmp(l, r) < 0; + return l_strcmp(l, r) < 0 ? 1 : 0; else { let res = ltm.luaT_callorderTM(L, l, r, ltm.TMS.TM_LT); if (res < 0) ldebug.luaG_ordererror(L, l, r); - return res; + return res ? 1 : 0; } }; @@ -731,13 +731,13 @@ const luaV_lessequal = function(L, l, r) { let res; if (l.ttisnumber() && r.ttisnumber()) - return LEnum(l, r); + return LEnum(l, r) ? 1 : 0; else if (l.ttisstring() && r.ttisstring()) - return l_strcmp(l, r) <= 0; + return l_strcmp(l, r) <= 0 ? 1 : 0; else { res = ltm.luaT_callorderTM(L, l, r, ltm.TMS.TM_LE); if (res >= 0) - return res; + return res ? 1 : 0; } L.ci.callstatus |= lstate.CIST_LEQ; /* mark it is doing 'lt' for 'le' */ @@ -843,7 +843,7 @@ const forlimit = function(obj, step) { const luaV_tointeger = function(obj, mode) { if (obj.ttisfloat()) { let n = obj.value; - let f = n|0; + let f = n; if (n !== f) { /* not an integral value? */ if (mode === 0) @@ -852,9 +852,9 @@ const luaV_tointeger = function(obj, mode) { f += 1; /* convert floor to ceil (remember: n !== f) */ } - return f|0; + return f; } else if (obj.ttisinteger()) { - return obj.value|0; + return obj.value; } else if (obj.ttisstring()) { return luaV_tointeger(new TValue(CT.LUA_TNUMFLT, parseFloat(obj.jsstring())), mode); // TODO: luaO_str2num } @@ -863,7 +863,7 @@ const luaV_tointeger = function(obj, mode) { }; const tointeger = function(o) { - return o.ttisinteger() ? o.value|0 : luaV_tointeger(o, 0); + return o.ttisinteger() ? o.value : luaV_tointeger(o, 0); }; const tonumber = function(v) { @@ -1117,4 +1117,4 @@ module.exports.luaV_rawequalobj = luaV_rawequalobj; module.exports.luaV_tointeger = luaV_tointeger; module.exports.settable = settable; module.exports.tointeger = tointeger; -module.exports.tonumber = tonumber; \ No newline at end of file +module.exports.tonumber = tonumber; diff --git a/tests/load.js b/tests/load.js index 143549a..9b76ad3 100644 --- a/tests/load.js +++ b/tests/load.js @@ -1,10 +1,8 @@ "use strict"; const test = require('tape'); -const beautify = require('js-beautify').js_beautify; const tests = require("./tests.js"); -const getState = tests.getState; const toByteCode = tests.toByteCode; const VM = require("../src/lvm.js"); @@ -212,4 +210,4 @@ test('dofile', function (t) { "Correct element(s) on the stack" ); -}); \ No newline at end of file +}); diff --git a/tests/lua.js b/tests/lua.js new file mode 100644 index 0000000..b2e0a6b --- /dev/null +++ b/tests/lua.js @@ -0,0 +1,33 @@ +"use strict"; + +const test = require('tape'); + +const lapi = require("../src/lapi.js"); +const lauxlib = require("../src/lauxlib.js"); +const lua = require('../src/lua.js'); +const linit = require('../src/linit.js'); + +test('string.lua', function (t) { + let luaCode = ` + return dofile("tests/single.lua") + `, L; + + t.plan(1); + + t.doesNotThrow(function () { + + L = lauxlib.luaL_newstate(); + + linit.luaL_openlibs(L); + + lauxlib.luaL_loadstring(L, luaCode); + + }, "Lua program loaded without error"); + + // t.doesNotThrow(function () { + + lapi.lua_call(L, 0, -1); + + // }, "Lua program ran without error"); + +}); diff --git a/tests/single.lua b/tests/single.lua new file mode 100644 index 0000000..616e2a4 --- /dev/null +++ b/tests/single.lua @@ -0,0 +1,73 @@ +-- $Id: strings.lua,v 1.86 2016/11/07 13:11:28 roberto Exp roberto $ +-- See Copyright Notice in file all.lua + +print('testing strings and string library') + +local maxi, mini = math.maxinteger, math.mininteger + + +local function checkerror (msg, f, ...) + local s, err = pcall(f, ...) + assert(not s and string.find(err, msg)) +end + + +-- testing string comparisons +assert('alo' < 'alo1') +assert('' < 'a') +assert('alo\0alo' < 'alo\0b') +assert('alo\0alo\0\0' > 'alo\0alo\0') +assert('alo' < 'alo\0') +assert('alo\0' > 'alo') +assert('\0' < '\1') +assert('\0\0' < '\0\1') +assert('\1\0a\0a' <= '\1\0a\0a') +assert(not ('\1\0a\0b' <= '\1\0a\0a')) +assert('\0\0\0' < '\0\0\0\0') +assert(not('\0\0\0\0' < '\0\0\0')) +assert('\0\0\0' <= '\0\0\0\0') +assert(not('\0\0\0\0' <= '\0\0\0')) +assert('\0\0\0' <= '\0\0\0') +assert('\0\0\0' >= '\0\0\0') +assert(not ('\0\0b' < '\0\0a\0')) + +-- testing string.sub +assert(string.sub("123456789",2,4) == "234") +assert(string.sub("123456789",7) == "789") +assert(string.sub("123456789",7,6) == "") +assert(string.sub("123456789",7,7) == "7") +assert(string.sub("123456789",0,0) == "") +assert(string.sub("123456789",-10,10) == "123456789") +assert(string.sub("123456789",1,9) == "123456789") +assert(string.sub("123456789",-10,-20) == "") +assert(string.sub("123456789",-1) == "9") +assert(string.sub("123456789",-4) == "6789") +assert(string.sub("123456789",-6, -4) == "456") +assert(string.sub("123456789", mini, -4) == "123456") +assert(string.sub("123456789", mini, maxi) == "123456789") +assert(string.sub("123456789", mini, mini) == "") +assert(string.sub("\000123456789",3,5) == "234") +assert(("\000123456789"):sub(8) == "789") + +-- testing string.find +assert(string.find("123456789", "345") == 3) +a,b = string.find("123456789", "345") +assert(string.sub("123456789", a, b) == "345") +assert(string.find("1234567890123456789", "345", 3) == 3) +assert(string.find("1234567890123456789", "345", 4) == 13) +assert(string.find("1234567890123456789", "346", 4) == nil) +assert(string.find("1234567890123456789", ".45", -9) == 13) +assert(string.find("abcdefg", "\0", 5, 1) == nil) +assert(string.find("", "") == 1) +assert(string.find("", "", 1) == 1) +assert(not string.find("", "", 2)) +assert(string.find('', 'aaa', 1) == nil) +assert(('alo(.)alo'):find('(.)', 1, 1) == 4) + +assert(string.len("") == 0) +assert(string.len("\0\0\0") == 3) +assert(string.len("1234567890") == 10) + +assert(#"" == 0) +assert(#"\0\0\0" == 3) +assert(#"1234567890" == 10) -- cgit v1.2.3-70-g09d2