Browse Source

new API functions `pop', `insert', and `move'

Roberto Ierusalimschy 25 years ago
parent
commit
f0b3cd1d6f
8 changed files with 62 additions and 35 deletions
  1. 25 13
      lapi.c
  2. 4 4
      lbuiltin.c
  3. 9 9
      liolib.c
  4. 2 2
      lmathlib.c
  5. 2 2
      lstrlib.c
  6. 11 2
      ltests.c
  7. 4 2
      lua.c
  8. 5 1
      lua.h

+ 25 - 13
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 1.90 2000/08/29 20:43:28 roberto Exp roberto $
+** $Id: lapi.c,v 1.91 2000/08/31 14:08:27 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -65,7 +65,25 @@ void lua_settop (lua_State *L, int index) {
   if (index >= 0)
     luaD_adjusttop(L, L->Cbase, index);
   else
-    L->top += index;  /* index is negative */
+    L->top = L->top+index+1;  /* index is negative */
+}
+
+
+void lua_move (lua_State *L, int index) {
+  TObject *p = Index(L, index);
+  TObject temp = *p;
+  while (++p < L->top) *(p-1) = *p;
+  *(L->top-1) = temp;
+}
+
+
+void lua_insert (lua_State *L, int index) {
+  TObject temp = *(L->top-1);
+  TObject *p = Index(L, index);
+  TObject *q;
+  for (q = L->top-1; q>p; q--)
+    *q = *(q-1);
+  *p = temp;
 }
 
 
@@ -218,8 +236,7 @@ void lua_gettable (lua_State *L) {
 
 
 void lua_rawget (lua_State *L) {
-  if (ttype(L->top - 2) != TAG_TABLE)
-    lua_error(L, "indexed expression not a table");
+  LUA_ASSERT(ttype(L->top-2) == TAG_TABLE, "not a table");
   *(L->top - 2) = *luaH_get(L, hvalue(L->top - 2), L->top - 1);
   L->top--;
 }
@@ -278,8 +295,7 @@ void lua_settable (lua_State *L) {
 
 
 void lua_rawset (lua_State *L) {
-  if (ttype(L->top-3) != TAG_TABLE)
-    lua_error(L, "indexed expression not a table");
+  LUA_ASSERT(ttype(L->top-3) == TAG_TABLE, "not a table");
   *luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1);
   L->top -= 3;
 }
@@ -287,8 +303,7 @@ void lua_rawset (lua_State *L) {
 
 void lua_setglobals (lua_State *L) {
   TObject *newtable = --L->top;
-  if (ttype(newtable) != TAG_TABLE)
-    lua_error(L, "Lua API error - invalid value for global table");
+  LUA_ASSERT(ttype(newtable) == TAG_TABLE, "not a table");
   L->gt = hvalue(newtable);
 }
 
@@ -350,9 +365,7 @@ void lua_settag (lua_State *L, int tag) {
 
 void lua_unref (lua_State *L, int ref) {
   if (ref >= 0) {
-    if (ref >= L->refSize || L->refArray[ref].st >= 0)
-      lua_error(L, "Lua API error - "
-                   "invalid argument for function `lua_unref'");
+    LUA_ASSERT(ref < L->refSize && L->refArray[ref].st < 0, "invalid ref");
     L->refArray[ref].st = L->refFree;
     L->refFree = ref;
   }
@@ -362,8 +375,7 @@ void lua_unref (lua_State *L, int ref) {
 int lua_next (lua_State *L) {
   const TObject *t = Index(L, -2);
   Node *n;
-  if (ttype(t) != TAG_TABLE)
-    lua_error(L, "Lua API error - object is not a table in `lua_next'"); 
+  LUA_ASSERT(ttype(t) == TAG_TABLE, "object is not a table in `lua_next'");
   n = luaH_next(L, hvalue(t), Index(L, -1));
   if (n) {
     *(L->top-1) = *key(n);

+ 4 - 4
lbuiltin.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lbuiltin.c,v 1.125 2000/08/31 14:08:27 roberto Exp roberto $
+** $Id: lbuiltin.c,v 1.126 2000/08/31 16:52:06 roberto Exp roberto $
 ** Built-in functions
 ** See Copyright Notice in lua.h
 */
@@ -92,7 +92,7 @@ int luaB_print (lua_State *L) {
       lua_error(L, "`tostring' must return a string to `print'");
     if (i>1) fputs("\t", stdout);
     fputs(s, stdout);
-    lua_settop(L, -1);  /* pop result */
+    lua_pop(L, 1);  /* pop result */
   }
   fputs("\n", stdout);
   return 0;
@@ -201,7 +201,7 @@ int luaB_settagmethod (lua_State *L) {
   lua_pushnil(L);  /* to get its tag */
   if (strcmp(event, "gc") == 0 && tag != lua_tag(L, -1))
     lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua");
-  lua_settop(L, -1);  /* remove the nil */
+  lua_pop(L, 1);  /* remove the nil */
   lua_settagmethod(L, tag, event);
   return 1;
 }
@@ -501,7 +501,7 @@ static int luaB_foreach (lua_State *L) {
     if (lua_call(L, 2, 1) != 0) lua_error(L, NULL);
     if (!lua_isnil(L, -1))
       return 1;
-    lua_settop(L, -2);  /* remove value and result */
+    lua_pop(L, 2);  /* remove value and result */
   }
 }
 

+ 9 - 9
liolib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: liolib.c,v 1.74 2000/08/29 20:43:28 roberto Exp roberto $
+** $Id: liolib.c,v 1.75 2000/08/31 13:30:10 roberto Exp roberto $
 ** Standard I/O (and system) library
 ** See Copyright Notice in lua.h
 */
@@ -150,14 +150,14 @@ static int closefile (lua_State *L, IOCtrl *ctrl, FILE *f) {
 
 static int io_close (lua_State *L) {
   IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
-  lua_settop(L, -1);  /* remove upvalue */
+  lua_pop(L, 1);  /* remove upvalue */
   return pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 1)));
 }
 
 
 static int file_collect (lua_State *L) {
   IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
-  lua_settop(L, -1);  /* remove upvalue */
+  lua_pop(L, 1);  /* remove upvalue */
   if (ctrl == (IOCtrl *)lua_touserdata(L, 1)) {
     /* collecting `ctrl' itself */
     lua_unref(L, ctrl->ref[INFILE]);
@@ -176,7 +176,7 @@ static int file_collect (lua_State *L) {
 static int io_open (lua_State *L) {
   IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
   FILE *f;
-  lua_settop(L, -1);  /* remove upvalue */
+  lua_pop(L, 1);  /* remove upvalue */
   f = fopen(luaL_check_string(L, 1), luaL_check_string(L, 2));
   if (f) {
     lua_pushusertag(L, f, ctrl->iotag);
@@ -191,7 +191,7 @@ static int io_open (lua_State *L) {
 static int io_fromto (lua_State *L, int inout, const char *mode) {
   IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
   FILE *current;
-  lua_settop(L, -1);  /* remove upvalue */
+  lua_pop(L, 1);  /* remove upvalue */
   if (lua_isnull(L, 1)) {
     closefile(L, ctrl, getfilebyref(L, ctrl, inout));
     current = (inout == 0) ? stdin : stdout;    
@@ -219,7 +219,7 @@ static int io_writeto (lua_State *L) {
 static int io_appendto (lua_State *L) {
   IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
   FILE *current;
-  lua_settop(L, -1);  /* remove upvalue */
+  lua_pop(L, 1);  /* remove upvalue */
   current = fopen(luaL_check_string(L, 1), "a");
   return setreturn(L, ctrl, current, OUTFILE);
 }
@@ -366,7 +366,7 @@ static int io_read (lua_State *L) {
   int n;
   if (f) firstarg++;
   else f = getfilebyref(L, ctrl, INFILE);  /* get _INPUT */
-  lua_settop(L, -1);
+  lua_pop(L, 1);
   if (firstarg > lastarg) {  /* no arguments? */
     lua_settop(L, 0);  /* erase upvalue and other eventual garbage */
     firstarg = lastarg = 1;  /* correct indices */
@@ -447,7 +447,7 @@ static int io_seek (lua_State *L) {
   FILE *f;
   int op;
   long offset;
-  lua_settop(L, -1);  /* remove upvalue */
+  lua_pop(L, 1);  /* remove upvalue */
   f = getnonullfile(L, ctrl, 1);
   op = luaL_findstring(luaL_opt_string(L, 2, "cur"), modenames);
   offset = luaL_opt_long(L, 3, 0);
@@ -465,7 +465,7 @@ static int io_seek (lua_State *L) {
 static int io_flush (lua_State *L) {
   IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
   FILE *f;
-  lua_settop(L, -1);  /* remove upvalue */
+  lua_pop(L, 1);  /* remove upvalue */
   f = gethandle(L, ctrl, 1);
   luaL_arg_check(L, f || lua_isnull(L, 1), 1, "invalid file handle");
   return pushresult(L, fflush(f) == 0);

+ 2 - 2
lmathlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lmathlib.c,v 1.26 2000/08/09 19:16:57 roberto Exp roberto $
+** $Id: lmathlib.c,v 1.27 2000/08/28 17:57:04 roberto Exp roberto $
 ** Standard mathematical library
 ** See Copyright Notice in lua.h
 */
@@ -233,7 +233,7 @@ void lua_mathlibopen (lua_State *L) {
   lua_pushnumber(L, 0);  /* to get its tag */
   lua_pushcfunction(L, math_pow);
   lua_settagmethod(L, lua_tag(L, -2), "pow");
-  lua_settop(L, -1);  /* remove number */
+  lua_pop(L, 1);  /* remove number */
   lua_pushnumber(L, PI); lua_setglobal(L, "PI");
 }
 

+ 2 - 2
lstrlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstrlib.c,v 1.48 2000/08/29 20:43:28 roberto Exp roberto $
+** $Id: lstrlib.c,v 1.49 2000/08/31 13:30:22 roberto Exp roberto $
 ** Standard library for string operations and pattern-matching
 ** See Copyright Notice in lua.h
 */
@@ -481,7 +481,7 @@ static void add_s (lua_State *L, struct Capture *cap) {
     s = lua_tostring(L, -1);
     if (s)
       addnchar(L, lua_tostring(L, -1), lua_strlen(L, -1));
-    lua_settop(L, -1);  /* pop function result */
+    lua_pop(L, 1);  /* pop function result */
   }
 }
 

+ 11 - 2
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 1.37 2000/08/29 19:05:11 roberto Exp roberto $
+** $Id: ltests.c,v 1.38 2000/08/31 13:29:47 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -341,7 +341,7 @@ static int getnum (lua_State *L, const char **pc) {
   skip(pc);
   if (**pc == '.') {
     res = (int)lua_tonumber(L, -1);
-    lua_settop(L, -1);
+    lua_pop(L, 1);
     (*pc)++;
     return res;
   }
@@ -384,12 +384,21 @@ static int testC (lua_State *L) {
     else if EQ("settop") {
       lua_settop(L, getnum);
     }
+    else if EQ("pop") {
+      lua_pop(L, getnum);
+    }
     else if EQ("pushnum") {
       lua_pushnumber(L, getnum);
     }
     else if EQ("pushobject") {
       lua_pushobject(L, getnum);
     }
+    else if EQ("move") {
+      lua_move(L, getnum);
+    }
+    else if EQ("insert") {
+      lua_insert(L, getnum);
+    }
     else if EQ("next") {
       lua_next(L);
     }

+ 4 - 2
lua.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.c,v 1.47 2000/08/29 14:33:31 roberto Exp roberto $
+** $Id: lua.c,v 1.48 2000/08/31 14:28:17 roberto Exp roberto $
 ** Lua stand-alone interpreter
 ** See Copyright Notice in lua.h
 */
@@ -87,7 +87,9 @@ static void laction (int i) {
 static int ldo (int (*f)(lua_State *l, const char *), const char *name) {
   int res;
   handler h = lreset();
+  int top = lua_gettop(L);
   res = f(L, name);  /* dostring | dofile */
+  lua_settop(L, top);  /* remove eventual results */
   signal(SIGINT, h);  /* restore old action */
   if (res == LUA_ERRMEM) {
     /* Lua gives no message in such case, so lua.c provides one */
@@ -177,9 +179,9 @@ static void manual_input (int version, int prompt) {
       const char *s;
       lua_getglobal(L, "_PROMPT");
       s = lua_tostring(L, -1);
-      lua_settop(L, -1);  /* remove global */
       if (!s) s = PROMPT;
       fputs(s, stdout);
+      lua_pop(L, 1);  /* remove global */
     }
     for(;;) {
       int c = getchar();

+ 5 - 1
lua.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.h,v 1.62 2000/08/29 20:43:28 roberto Exp roberto $
+** $Id: lua.h,v 1.63 2000/08/31 14:08:27 roberto Exp roberto $
 ** Lua - An Extensible Extension Language
 ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
 ** e-mail: [email protected]
@@ -62,6 +62,8 @@ void           lua_close (lua_State *L);
 int            lua_gettop (lua_State *L);
 void           lua_settop (lua_State *L, int index);
 void           lua_pushobject (lua_State *L, int index);
+void           lua_move (lua_State *L, int index);
+void           lua_insert (lua_State *L, int index);
 int            lua_stackspace (lua_State *L);
 
 
@@ -152,6 +154,8 @@ int            lua_next (lua_State *L);
 ** ===============================================================
 */
 
+#define lua_pop(L,n)		lua_settop(L, -(n)-1)
+
 #define lua_register(L,n,f)	(lua_pushcfunction(L, f), lua_setglobal(L, n))
 #define lua_pushuserdata(L,u)	lua_pushusertag(L, u, 0)
 #define lua_pushcfunction(L,f)	lua_pushcclosure(L, f, 0)