2
0
Эх сурвалжийг харах

new API function 'lua_rotate'

Roberto Ierusalimschy 11 жил өмнө
parent
commit
5a5a834975
4 өөрчлөгдсөн 36 нэмэгдсэн , 26 устгасан
  1. 20 15
      lapi.c
  2. 2 4
      liolib.c
  3. 5 1
      ltests.c
  4. 9 6
      lua.h

+ 20 - 15
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);
 }
 

+ 2 - 4
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);
 }
 

+ 5 - 1
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);

+ 9 - 6
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))
+
 
 /*
 ** {======================================================================