From 8388f1d2eb85bfc5fdbe1cfeb62e85a7d88403b5 Mon Sep 17 00:00:00 2001 From: Benoit Giannangeli Date: Wed, 15 Mar 2017 08:52:34 +0100 Subject: string.byte --- src/lstrlib.js | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'src') 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) { -- cgit v1.2.3-70-g09d2