diff options
author | Benoit Giannangeli <benoit.giannangeli@boursorama.fr> | 2017-02-24 11:38:23 +0100 |
---|---|---|
committer | Benoit Giannangeli <benoit.giannangeli@boursorama.fr> | 2017-02-24 11:40:35 +0100 |
commit | 2f9fe378bc341921e1ae259a2fec049663100738 (patch) | |
tree | 64f5f5a5cbc40630c894f5700502d3f757eef1f1 /src/ltablib.js | |
parent | 2ccf4ee80dbbf3e9af8ff006fcc18798e668a413 (diff) | |
download | fengari-2f9fe378bc341921e1ae259a2fec049663100738.tar.gz fengari-2f9fe378bc341921e1ae259a2fec049663100738.tar.bz2 fengari-2f9fe378bc341921e1ae259a2fec049663100738.zip |
table.move
Diffstat (limited to 'src/ltablib.js')
-rw-r--r-- | src/ltablib.js | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/ltablib.js b/src/ltablib.js index 6255761..97ecd65 100644 --- a/src/ltablib.js +++ b/src/ltablib.js @@ -9,6 +9,7 @@ const lauxlib = require('./lauxlib.js'); const lstate = require('./lstate.js'); const ldo = require('./ldo.js'); const ldebug = require('./ldebug.js'); +const llimit = require('./llimit.js'); const CT = lua.constant_types; const TS = lua.thread_status; @@ -98,6 +99,41 @@ const tremove = function(L) { return 1; }; +/* +** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever +** possible, copy in increasing order, which is better for rehashing. +** "possible" means destination after original range, or smaller +** than origin, or copying to another table. +*/ +const tmove = function(L) { + let f = lauxlib.luaL_checkinteger(L, 2); + let e = lauxlib.luaL_checkinteger(L, 3); + let t = lauxlib.luaL_checkinteger(L, 4); + let tt = !lapi.lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ + checktab(L, 1, TAB_R); + checktab(L, tt, TAB_W); + if (e >= f) { /* otherwise, nothing to move */ + lauxlib.luaL_argcheck(L, f > 0 || e < llimit.LUA_MAXINTEGER + f, 3, "too many elements to move"); + let n = e - f + 1; /* number of elements to move */ + lauxlib.luaL_argcheck(L, t <= llimit.LUA_MAXINTEGER - n + 1, 4, "destination wrap around"); + + if (t > e || t <= f || (tt !== 1 && lapi.lua_compare(L, 1, tt, lua.LUA_OPEQ) !== 1)) { + for (let i = 0; i < n; i++) { + lapi.lua_geti(L, 1, f + i); + lapi.lua_seti(L, tt, t + i); + } + } else { + for (let i = n - 1; i >= 0; i--) { + lapi.lua_geti(L, 1, f + i); + lapi.lua_seti(L, tt, t + i); + } + } + } + + lapi.lua_pushvalue(L, tt); /* return destination table */ + return 1; +}; + const tconcat = function(L) { let last = aux_getn(L, 1, TAB_R); let sep = lauxlib.luaL_optlstring(L, 2, ""); @@ -147,6 +183,7 @@ const unpack = function(L) { const tab_funcs = { "concat": tconcat, "insert": tinsert, + "move": tmove, "pack": pack, "remove": tremove, "unpack": unpack |