From 8388f1d2eb85bfc5fdbe1cfeb62e85a7d88403b5 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Wed, 15 Mar 2017 08:52:34 +0100 Subject: string.byte --- README.md | 2 +- src/lstrlib.js | 38 +++++++++++++++++++++++++++++++++----- tests/lstrlib.js | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 05daa08..617fd40 100644 --- a/README.md +++ b/README.md @@ -213,13 +213,13 @@ - [x] Math - [x] utf8 - [ ] String + - [x] string.byte - [x] string.char - [x] string.len - [x] string.lower - [x] string.rep - [x] string.reverse - [x] string.upper - - [ ] string.byte - [ ] string.dump - [ ] string.find - [ ] string.format diff --git a/src/lstrlib.js b/src/lstrlib.js index 3db3e5e..376d379 100644 --- a/src/lstrlib.js +++ b/src/lstrlib.js @@ -6,6 +6,13 @@ const lua = require('./lua.js'); const lapi = require('./lapi.js'); const lauxlib = require('./lauxlib.js'); +/* translate a relative string position: negative means back from end */ +const posrelat = function(pos, len) { + if (pos >= 0) return pos; + else if (0 - pos > len) return 0; + else return len + pos + 1; +}; + const str_len = function(L) { lapi.lua_pushinteger(L, lauxlib.luaL_checkstring(L, 1).length); return 1; @@ -47,13 +54,34 @@ const str_rep = function(L) { return 1; }; +const str_byte = function(L) { + let s = lauxlib.luaL_checkstring(L, 1); + s = L.stack[lapi.index2addr_(L, 1)].value; + let l = s.length; + let posi = posrelat(lauxlib.luaL_optinteger(L, 2, 1), l); + let pose = posrelat(lauxlib.luaL_optinteger(L, 3, posi), l); + + if (posi < 1) posi = 1; + if (pose > l) pose = l; + if (posi > pose) return 0; /* empty interval; return no values */ + if (pose - posi >= Number.MAX_SAFE_INTEGER) /* arithmetic overflow? */ + return lauxlib.luaL_error(L, "string slice too long"); + + let n = (pose - posi) + 1; + lauxlib.luaL_checkstack(L, n, "string slice too long"); + for (let i = 0; i < n; i++) + lapi.lua_pushinteger(L, s[posi + i - 1]); + return n; +}; + const strlib = { - "char": str_char, - "len": str_len, - "lower": str_lower, - "rep": str_rep, + "byte": str_byte, + "char": str_char, + "len": str_len, + "lower": str_lower, + "rep": str_rep, "reverse": str_reverse, - "upper": str_upper + "upper": str_upper }; const createmetatable = function(L) { diff --git a/tests/lstrlib.js b/tests/lstrlib.js index d4e8493..b15eecf 100644 --- a/tests/lstrlib.js +++ b/tests/lstrlib.js @@ -177,4 +177,47 @@ test('string.reverse', function (t) { "hello", "Correct element(s) on the stack" ); +}); + + +test('string.byte', function (t) { + let luaCode = ` + return string.byte("hello", 2, 4) + `, L; + + t.plan(5); + + 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, -3), + 101, + "Correct element(s) on the stack" + ); + + t.strictEqual( + lapi.lua_tointeger(L, -2), + 108, + "Correct element(s) on the stack" + ); + + t.strictEqual( + lapi.lua_tointeger(L, -1), + 108, + "Correct element(s) on the stack" + ); }); \ No newline at end of file -- cgit v1.2.3-54-g00ecf