diff options
author | Benoit Giannangeli <benoit.giannangeli@boursorama.fr> | 2017-03-15 08:52:34 +0100 |
---|---|---|
committer | Benoit Giannangeli <benoit.giannangeli@boursorama.fr> | 2017-03-15 08:52:34 +0100 |
commit | 8388f1d2eb85bfc5fdbe1cfeb62e85a7d88403b5 (patch) | |
tree | cded0074e7375415123d8a5b0c2a29494abab746 /src | |
parent | 1a158cc176055a50df492dfa39c1b93e9e5b478a (diff) | |
download | fengari-8388f1d2eb85bfc5fdbe1cfeb62e85a7d88403b5.tar.gz fengari-8388f1d2eb85bfc5fdbe1cfeb62e85a7d88403b5.tar.bz2 fengari-8388f1d2eb85bfc5fdbe1cfeb62e85a7d88403b5.zip |
string.byte
Diffstat (limited to 'src')
-rw-r--r-- | src/lstrlib.js | 38 |
1 files changed, 33 insertions, 5 deletions
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) { |