aboutsummaryrefslogtreecommitdiff
path: root/src/lstrlib.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/lstrlib.js')
-rw-r--r--src/lstrlib.js38
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) {