From 5a5a834975d135054e803b90711fcb9deb6511b8 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 13 May 2014 16:40:28 -0300 Subject: new API function 'lua_rotate' --- lapi.c | 35 ++++++++++++++++++++--------------- liolib.c | 6 ++---- ltests.c | 6 +++++- lua.h | 15 +++++++++------ 4 files changed, 36 insertions(+), 26 deletions(-) diff --git a/lapi.c b/lapi.c index 843e5606..0fdb6bed 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.208 2014/05/01 18:18:06 roberto Exp roberto $ +** $Id: lapi.c,v 2.209 2014/05/01 18:21:32 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -181,26 +181,31 @@ LUA_API void lua_settop (lua_State *L, int idx) { } -LUA_API void lua_remove (lua_State *L, int idx) { - StkId p; - lua_lock(L); - p = index2addr(L, idx); - api_checkstackindex(L, idx, p); - while (++p < L->top) setobjs2s(L, p-1, p); - L->top--; - lua_unlock(L); +/* +** Reverse the stack segment from 'from' to 'to' +** (auxiliar to 'lua_rotate') +*/ +static void reverse (lua_State *L, StkId from, StkId to) { + for (; from < to; from++, to--) { + TValue temp; + setobj(L, &temp, from); + setobj(L, from, to); + setobj(L, to, &temp); + } } -LUA_API void lua_insert (lua_State *L, int idx) { - StkId p; - StkId q; +LUA_API void lua_rotate (lua_State *L, int idx, int n) { + StkId p, t, m; lua_lock(L); + t = L->top - 1; p = index2addr(L, idx); + m = (n >= 0 ? t - n : p - n - 1); api_checkstackindex(L, idx, p); - for (q = L->top; q > p; q--) /* use L->top as a temporary */ - setobjs2s(L, q, q - 1); - setobjs2s(L, p, L->top); + api_check(L, p <= m + 1 && m <= t, "invalid 'n'"); + reverse(L, p, m); + reverse(L, m + 1, t); + reverse(L, p, t); lua_unlock(L); } diff --git a/liolib.c b/liolib.c index 41fa8555..37371401 100644 --- a/liolib.c +++ b/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 2.121 2014/04/15 16:46:45 roberto Exp roberto $ +** $Id: liolib.c,v 2.122 2014/05/11 14:46:19 roberto Exp roberto $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -319,14 +319,12 @@ static int io_readline (lua_State *L); static void aux_lines (lua_State *L, int toclose) { - int i; int n = lua_gettop(L) - 1; /* number of arguments to read */ /* ensure that arguments will fit here and into 'io_readline' stack */ luaL_argcheck(L, n <= LUA_MINSTACK - 3, LUA_MINSTACK - 3, "too many options"); - lua_pushvalue(L, 1); /* file handle */ lua_pushinteger(L, n); /* number of arguments to read */ lua_pushboolean(L, toclose); /* close/not close file when finished */ - for (i = 1; i <= n; i++) lua_pushvalue(L, i + 1); /* copy arguments */ + lua_rotate(L, 2, 2); /* move 'n' and 'toclose' to their positions */ lua_pushcclosure(L, io_readline, 3 + n); } diff --git a/ltests.c b/ltests.c index e5d72650..cc1f72e5 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 2.168 2014/04/14 18:42:44 roberto Exp roberto $ +** $Id: ltests.c,v 2.169 2014/05/08 19:08:46 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -1215,6 +1215,10 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) { } return n; } + else if EQ("rotate") { + int i = getindex; + lua_rotate(L1, i, getnum); + } else if EQ("setfield") { int t = getindex; lua_setfield(L1, t, getstring); diff --git a/lua.h b/lua.h index 464d3717..aa187338 100644 --- a/lua.h +++ b/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.304 2014/05/01 18:21:32 roberto Exp roberto $ +** $Id: lua.h,v 1.305 2014/05/08 13:52:20 roberto Exp roberto $ ** Lua - A Scripting Language ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) ** See Copyright Notice at the end of this file @@ -145,8 +145,7 @@ LUA_API int (lua_absindex) (lua_State *L, int idx); LUA_API int (lua_gettop) (lua_State *L); LUA_API void (lua_settop) (lua_State *L, int idx); LUA_API void (lua_pushvalue) (lua_State *L, int idx); -LUA_API void (lua_remove) (lua_State *L, int idx); -LUA_API void (lua_insert) (lua_State *L, int idx); +LUA_API void (lua_rotate) (lua_State *L, int idx, int n); LUA_API void (lua_replace) (lua_State *L, int idx); LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx); LUA_API int (lua_checkstack) (lua_State *L, int sz); @@ -326,9 +325,9 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); ** =============================================================== */ -#define lua_tonumber(L,i) lua_tonumberx(L,i,NULL) -#define lua_tointeger(L,i) lua_tointegerx(L,i,NULL) -#define lua_tounsigned(L,i) lua_tounsignedx(L,i,NULL) +#define lua_tonumber(L,i) lua_tonumberx(L,(i),NULL) +#define lua_tointeger(L,i) lua_tointegerx(L,(i),NULL) +#define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL) #define lua_pop(L,n) lua_settop(L, -(n)-1) @@ -356,6 +355,10 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); #define lua_tostring(L,i) lua_tolstring(L, (i), NULL) +#define lua_insert(L,idx) lua_rotate(L, (idx), 1) + +#define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1)) + /* ** {====================================================================== -- cgit v1.2.3-55-g6feb