diff options
| -rw-r--r-- | README.md | 23 | ||||
| -rw-r--r-- | src/lapi.js | 3 | ||||
| -rw-r--r-- | src/lauxlib.js | 13 | ||||
| -rw-r--r-- | src/ldo.js | 2 | ||||
| -rw-r--r-- | src/linit.js | 8 | ||||
| -rw-r--r-- | src/lstate.js | 1 | ||||
| -rw-r--r-- | src/lstrlib.js | 22 | ||||
| -rw-r--r-- | tests/lstrlib.js | 81 | 
8 files changed, 138 insertions, 15 deletions
@@ -146,12 +146,14 @@      - [x] luaL_argcheck      - [x] luaL_argerror      - [x] luaL_buffinit +    - [x] luaL_buffinitsize      - [x] luaL_callmeta      - [x] luaL_checkany      - [x] luaL_checkinteger      - [x] luaL_checklstring      - [x] luaL_checknumber      - [x] luaL_checkstack +    - [x] luaL_checkstring      - [x] luaL_checktype      - [x] luaL_error      - [x] luaL_getmetafield @@ -166,6 +168,7 @@      - [x] luaL_opt      - [x] luaL_optinteger      - [x] luaL_optlstring +    - [x] luaL_prepbuffsize      - [x] luaL_pushresult      - [x] luaL_requiref      - [x] luaL_setfuncs @@ -174,9 +177,7 @@      - [x] luaL_where      - [ ] luaL_addchar      - [ ] luaL_addsize -    - [ ] luaL_buffinitsize      - [ ] luaL_checkoption -    - [ ] luaL_checkstring      - [ ] luaL_checkudata      - [ ] luaL_checkversion      - [ ] luaL_dofile @@ -192,7 +193,6 @@      - [ ] luaL_optnumber      - [ ] luaL_optstring      - [ ] luaL_prepbuffer -    - [ ] luaL_prepbuffsize      - [ ] luaL_pushresultsize      - [ ] luaL_ref      - [ ] luaL_setmetatable @@ -209,6 +209,23 @@      - [x] Table      - [x] Math      - [ ] String +        - [x] string.char +        - [x] string.len +        - [ ] string.byte +        - [ ] string.dump +        - [ ] string.find +        - [ ] string.format +        - [ ] string.gmatch +        - [ ] string.gsub +        - [ ] string.lower +        - [ ] string.match +        - [ ] string.pack +        - [ ] string.packsize +        - [ ] string.rep +        - [ ] string.reverse +        - [ ] string.sub +        - [ ] string.unpack +        - [ ] string.upper      - [ ] Package      - [ ] os      - [ ] io diff --git a/src/lapi.js b/src/lapi.js index dae533d..2fbd777 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -226,8 +226,7 @@ const lua_pushlstring = function(L, s, len) { // TODO: embedded \0  };  const lua_pushstring = function (L, s) { -    assert(typeof s === "string"); -    if (!s) +    if (typeof s !== "string")          L.stack[L.top] = ldo.nil;      else {          let ts = new TValue(CT.LUA_TLNGSTR, s); diff --git a/src/lauxlib.js b/src/lauxlib.js index 5223b9b..e3afa60 100644 --- a/src/lauxlib.js +++ b/src/lauxlib.js @@ -159,7 +159,7 @@ const luaL_checktype = function(L, arg, t) {  };  const luaL_checkstring = function(L, n) { -    luaL_checklstring(L, n, null); +    return luaL_checklstring(L, n, null);  };  const luaL_checklstring = function(L, arg) { @@ -201,11 +201,20 @@ const luaL_optinteger = function(L, arg, def) {      return luaL_opt(L, luaL_checkinteger, arg, def);  }; +const luaL_prepbuffsize = function(B, sz) { +    return B; +}; +  const luaL_buffinit = function(L, B) {      B.L = L;      B.b = "";  }; +const luaL_buffinitsize = function(L, B, sz) { +    luaL_buffinit(L, B); +    return B; +}; +  const luaL_addlstring = function(B, s) {      B.b += s;  }; @@ -392,6 +401,7 @@ module.exports.luaL_addvalue     = luaL_addvalue;  module.exports.luaL_argcheck     = luaL_argcheck;  module.exports.luaL_argerror     = luaL_argerror;  module.exports.luaL_buffinit     = luaL_buffinit; +module.exports.luaL_buffinitsize = luaL_buffinitsize;  module.exports.luaL_callmeta     = luaL_callmeta;  module.exports.luaL_checkany     = luaL_checkany;  module.exports.luaL_checkinteger = luaL_checkinteger; @@ -413,6 +423,7 @@ module.exports.luaL_opt          = luaL_opt;  module.exports.luaL_optinteger   = luaL_optinteger;  module.exports.luaL_optlstring   = luaL_optlstring;  module.exports.luaL_optstring    = luaL_optstring; +module.exports.luaL_prepbuffsize = luaL_prepbuffsize;  module.exports.luaL_pushresult   = luaL_pushresult;  module.exports.luaL_requiref     = luaL_requiref;  module.exports.luaL_setfuncs     = luaL_setfuncs; @@ -521,7 +521,7 @@ class SParser {  }  const checkmode = function(L, mode, x) { -    if (mode && mode.indexOf(x.charAt(0))) { +    if (mode && mode.indexOf(x.charAt(0)) !== -1) {          lapi.lua_pushstring(L, `attempt to load a ${x} chunk (mode is '${mode}')`);          luaD_throw(L, TS.LUA_ERRSYNTAX);      } diff --git a/src/linit.js b/src/linit.js index b926683..f9f8296 100644 --- a/src/linit.js +++ b/src/linit.js @@ -4,16 +4,18 @@ const assert = require('assert');  const lapi     = require('./lapi.js');  const lauxlib  = require('./lauxlib.js'); -const lualib   = require('./lualib.js');  const lbaselib = require('./lbaselib.js');  const lcorolib = require('./lcorolib.js'); -const ltablib  = require('./ltablib.js');  const lmathlib = require('./lmathlib.js'); +const lstrlib  = require('./lstrlib.js'); +const ltablib  = require('./ltablib.js'); +const lualib   = require('./lualib.js');  const loadedlibs = { +    [lualib.LUA_COLIBNAME]:   lcorolib.luaopen_coroutine,      [lualib.LUA_MATHLIBNAME]: lmathlib.luaopen_math, +    [lualib.LUA_STRLIBNAME]:  lstrlib.luaopen_string,      [lualib.LUA_TABLIBNAME]:  ltablib.luaopen_table, -    [lualib.LUA_COLIBNAME]:   lcorolib.luaopen_coroutine,      "_G":                     lbaselib.luaopen_base  }; diff --git a/src/lstate.js b/src/lstate.js index 29bf186..2e6ebbe 100644 --- a/src/lstate.js +++ b/src/lstate.js @@ -111,7 +111,6 @@ const f_luaopen = function(L) {      let g = L.l_G;      stack_init(L, L);      init_registry(L, g); -    // TODO: luaS_init(L);      luaT_init(L);      g.version = lapi.lua_version(null);  }; diff --git a/src/lstrlib.js b/src/lstrlib.js index 194d6ba..69f634d 100644 --- a/src/lstrlib.js +++ b/src/lstrlib.js @@ -9,13 +9,25 @@ const CT      = lua.constant_types;  const TS      = lua.thread_status;  const str_len = function(L) { -    lauxlib.luaL_checkstring(L, 1); -    lapi.lua_pushinteger(L, lapi.lua_tostring(L, 1).length); +    lapi.lua_pushinteger(L, lauxlib.luaL_checkstring(L, 1).length); +    return 1; +}; + +const str_char = function(L) { +    let n = lapi.lua_gettop(L);  /* number of arguments */ +    let p = ""; +    for (let i = 1; i <= n; i++) { +        let c = lauxlib.luaL_checkinteger(L, i); +        lauxlib.luaL_argcheck(L, c >= 0 && c <= 255, "value out of range"); // Strings are 8-bit clean +        p += String.fromCharCode(c); +    } +    lapi.lua_pushstring(L, p);      return 1;  };  const strlib = { -    "len": str_len +    "len": str_len, +    "char": str_char  };  const createmetatable = function(L) { @@ -33,4 +45,6 @@ const luaopen_string = function(L) {      lauxlib.luaL_newlib(L, strlib);      createmetatable(L);      return 1; -};
\ No newline at end of file +}; + +module.exports.luaopen_string = luaopen_string;
\ No newline at end of file diff --git a/tests/lstrlib.js b/tests/lstrlib.js new file mode 100644 index 0000000..494b881 --- /dev/null +++ b/tests/lstrlib.js @@ -0,0 +1,81 @@ +"use strict"; + +const test       = require('tape'); +const beautify   = require('js-beautify').js_beautify; + +const tests      = require("./tests.js"); +const toByteCode = tests.toByteCode; + +const lapi       = require("../src/lapi.js"); +const lauxlib    = require("../src/lauxlib.js"); +const linit      = require('../src/linit.js'); + + +test('string.len', function (t) { +    let luaCode = ` +        local a = "world" +        return string.len("hello"), a:len() +    `, L; +     +    t.plan(4); + +    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"); + +    t.strictEqual( +        lapi.lua_tointeger(L, -2), +        5, +        "Correct element(s) on the stack" +    ); + +    t.strictEqual( +        lapi.lua_tointeger(L, -1), +        5, +        "Correct element(s) on the stack" +    ); + +}); + + +test('string.char', function (t) { +    let luaCode = ` +        return string.char(104, 101, 108, 108, 111) +    `, L; +     +    t.plan(3); + +    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"); + +    t.strictEqual( +        lapi.lua_tostring(L, -1), +        "hello", +        "Correct element(s) on the stack" +    ); +});
\ No newline at end of file  | 
