diff options
| -rw-r--r-- | README.md | 4 | ||||
| -rw-r--r-- | src/lapi.js | 10 | ||||
| -rw-r--r-- | src/lbaselib.js | 28 | ||||
| -rw-r--r-- | tests/lbaselib.js | 47 | 
4 files changed, 86 insertions, 3 deletions
@@ -76,6 +76,7 @@      - [x] lua_remove      - [x] lua_rotate      - [x] lua_insert +    - [x] lua_stringtonumber      - [ ] lua_arith      - [ ] lua_close      - [ ] lua_compare @@ -129,7 +130,6 @@      - [ ] lua_setupvalue      - [ ] lua_setuservalue      - [ ] lua_status -    - [ ] lua_stringtonumber      - [ ] lua_tocfunction      - [ ] lua_tothread      - [ ] lua_touserdata @@ -214,11 +214,11 @@          - [x] collectgarbage (unavailable)          - [x] ipairs          - [x] select +        - [x] tonumber          - [ ] assert          - [ ] next          - [ ] pairs          - [ ] rawlen -        - [ ] tonumber          - [ ] dofile          - [ ] loadfile          - [ ] load diff --git a/src/lapi.js b/src/lapi.js index bc4dd54..19e3090 100644 --- a/src/lapi.js +++ b/src/lapi.js @@ -488,6 +488,13 @@ const lua_topointer = function(L, idx) {      }  }; +const lua_stringtonumber = function(L, s) { +    let number = parseFloat(s); +    L.stack[L.top++] = new TValue(number % 1 !== 0 ? CT.LUA_TNUMFLT : CT.LUA_TNUMINT, number); +    assert(L.top <= L.ci.top, "stack overflow"); +    return s.length; +}; +  const f_call = function(L, ud) {      ldo.luaD_callnoyield(L, ud.funcOff, ud.nresults);  }; @@ -705,4 +712,5 @@ module.exports.lua_error           = lua_error;  module.exports.lua_insert          = lua_insert;  module.exports.lua_gc              = lua_gc;  module.exports.lua_getallocf       = lua_getallocf; -module.exports.lua_getextraspace   = lua_getextraspace;
\ No newline at end of file +module.exports.lua_getextraspace   = lua_getextraspace; +module.exports.lua_stringtonumber  = lua_stringtonumber;
\ No newline at end of file diff --git a/src/lbaselib.js b/src/lbaselib.js index 19a990e..9cc4fb1 100644 --- a/src/lbaselib.js +++ b/src/lbaselib.js @@ -127,6 +127,33 @@ const luaB_ipairs = function(L) {      return 3;  }; +const luaB_tonumber = function(L) { +    if (lapi.lua_type(L, 2) <= 0) {  /* standard conversion? */ +        lauxlib.luaL_checkany(L, 1); +        if (lapi.lua_type(L, 1) === CT.LUA_TNUMBER) {  /* already a number? */ +            lapi.lua_settop(L, 1); +            return 1; +        } else { +            let s = lapi.lua_tostring(L, 1); +            if (s !== null && lapi.lua_stringtonumber(L, s) === s.length) +                return 1;  /* successful conversion to number */ +        } +    } else { +        let base = lauxlib.luaL_checkinteger(L, 2); +        lauxlib.luaL_checktype(L, 1, CT.LUA_TSTRING);  /* no numbers as strings */ +        let s = lapi.lua_tostring(L, 1); +        lauxlib.luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); +        let n = parseInt(s, base); +        if (!isNaN(n)) { +            lapi.lua_pushinteger(L, n); +            return 1; +        } +    } + +    lapi.lua_pushnil(L); +    return 1; +}; +  const luaB_error = function(L) {      let level = lauxlib.luaL_optinteger(L, 2, 1);      lapi.lua_settop(L, 1); @@ -195,6 +222,7 @@ const base_funcs = {      "collectgarbage": function () {},      "print":          luaB_print,      "tostring":       luaB_tostring, +    "tonumber":       luaB_tonumber,      "getmetatable":   luaB_getmetatable,      "ipairs":         luaB_ipairs,      "select":         luaB_select, diff --git a/tests/lbaselib.js b/tests/lbaselib.js index 73d13a3..6dc6bfb 100644 --- a/tests/lbaselib.js +++ b/tests/lbaselib.js @@ -442,4 +442,51 @@ test('select', function (t) {          [2, 3],          "Correct element(s) on the stack"      ); +}); + + +test('tonumber', function (t) { +    let luaCode = ` +        return tonumber('123'), tonumber('12.3'), tonumber('az', 36), tonumber('10', 2) +    `, L; +     +    t.plan(5); + +    t.doesNotThrow(function () { + +        let bc = toByteCode(luaCode).dataView; + +        L = lauxlib.luaL_newstate(); + +        linit.luaL_openlibs(L); + +        lapi.lua_load(L, bc, "test-tonumber"); + +        lapi.lua_call(L, 0, -1); + +    }, "JS Lua program ran without error"); + +    t.strictEqual( +        lapi.lua_tonumber(L, -4), +        123, +        "Correct element(s) on the stack" +    ); + +    t.strictEqual( +        lapi.lua_tonumber(L, -3), +        12.3, +        "Correct element(s) on the stack" +    ); + +    t.strictEqual( +        lapi.lua_tonumber(L, -2), +        395, +        "Correct element(s) on the stack" +    ); + +    t.strictEqual( +        lapi.lua_tonumber(L, -1), +        2, +        "Correct element(s) on the stack" +    );  });
\ No newline at end of file  | 
