From d792a7dad54039074890d9d379eec8676cb9fa5a Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Mon, 6 Mar 2017 07:34:00 +0100 Subject: string.char --- README.md | 23 +++++++++++++--- src/lapi.js | 3 +-- src/lauxlib.js | 13 ++++++++- src/ldo.js | 2 +- src/linit.js | 8 +++--- src/lstate.js | 1 - src/lstrlib.js | 22 ++++++++++++--- tests/lstrlib.js | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 138 insertions(+), 15 deletions(-) create mode 100644 tests/lstrlib.js diff --git a/README.md b/README.md index 2cd5d93..a6e11df 100644 --- a/README.md +++ b/README.md @@ -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; diff --git a/src/ldo.js b/src/ldo.js index 1d5c81b..e9bc9eb 100644 --- a/src/ldo.js +++ b/src/ldo.js @@ -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 -- cgit v1.2.3-70-g09d2