Pārlūkot izejas kodu

new implementation for `next'

Roberto Ierusalimschy 25 gadi atpakaļ
vecāks
revīzija
100bfec39a
9 mainītis faili ar 76 papildinājumiem un 75 dzēšanām
  1. 16 19
      lapi.c
  2. 1 2
      lapi.h
  3. 13 18
      lbuiltin.c
  4. 3 3
      lcode.c
  5. 4 5
      lparser.c
  6. 19 5
      ltable.c
  7. 2 2
      ltable.h
  8. 4 3
      lua.h
  9. 14 18
      lvm.c

+ 16 - 19
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 1.89 2000/08/29 14:52:27 roberto Exp roberto $
+** $Id: lapi.c,v 1.90 2000/08/29 20:43:28 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -327,7 +327,7 @@ int lua_ref (lua_State *L,  int lock) {
 
 
 /*
-** miscelaneous functions
+** miscellaneous functions
 */
 
 
@@ -359,24 +359,21 @@ void lua_unref (lua_State *L, int ref) {
 }
 
 
-int luaA_next (lua_State *L, const Hash *t, int i) {
-  int tsize = t->size;
-  for (; i<tsize; i++) {
-    Node *n = node(t, i);
-    if (ttype(val(n)) != TAG_NIL) {
-      luaA_pushobject(L, key(n));
-      luaA_pushobject(L, val(n));
-      return i+1;  /* index to be used next time */
-    }
-  }
-  return 0;  /* no more elements */
-}
-
-
-int lua_next (lua_State *L, int index, int i) {
-  const TObject *t = Index(L, index);
+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'"); 
-  return luaA_next(L, hvalue(t), i);
+  n = luaH_next(L, hvalue(t), Index(L, -1));
+  if (n) {
+    *(L->top-1) = *key(n);
+    *L->top = *val(n);
+    api_incr_top(L);
+    return 1;
+  }
+  else {  /* no more elements */
+    L->top -= 2;  /* remove key and table */
+    return 0;
+  }
 }
 

+ 1 - 2
lapi.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.h,v 1.18 2000/05/08 20:49:05 roberto Exp roberto $
+** $Id: lapi.h,v 1.19 2000/08/28 17:57:04 roberto Exp roberto $
 ** Auxiliary functions from Lua API
 ** See Copyright Notice in lua.h
 */
@@ -13,6 +13,5 @@
 
 TObject *luaA_index (lua_State *L, int index);
 void luaA_pushobject (lua_State *L, const TObject *o);
-int luaA_next (lua_State *L, const Hash *t, int i);
 
 #endif

+ 13 - 18
lbuiltin.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lbuiltin.c,v 1.123 2000/08/29 14:33:31 roberto Exp roberto $
+** $Id: lbuiltin.c,v 1.124 2000/08/29 14:41:56 roberto Exp roberto $
 ** Built-in functions
 ** See Copyright Notice in lua.h
 */
@@ -267,6 +267,18 @@ int luaB_type (lua_State *L) {
   return 1;
 }
 
+
+int luaB_next (lua_State *L) {
+  luaL_checktype(L, 1, "table");
+  lua_settop(L, 2);  /* create a 2nd argument if there isn't one */
+  if (lua_next(L))
+    return 2;
+  else {
+    lua_pushnil(L);
+    return 1;
+  }
+}
+
 /* }====================================================== */
 
 
@@ -355,23 +367,6 @@ int luaB_call (lua_State *L) {
 }
 
 
-int luaB_next (lua_State *L) {
-  const Hash *a = gettable(L, 1);
-  int i;  /* `luaA_next' gets first element after `i' */
-  if (lua_isnull(L, 2) || lua_isnil(L, 2))  /* no index or nil index? */
-    i = 0;  /* get first */
-  else {
-    i = luaH_pos(L, a, luaA_index(L, 2))+1;
-    luaL_arg_check(L, i != 0, 2, "key not found");
-  }
-  if (luaA_next(L, a, i) != 0)
-    return 2;  /* `luaA_next' left them on the stack */
-  else {
-    lua_pushnil(L);
-    return 1;
-  }
-}
-
 
 int luaB_tostring (lua_State *L) {
   char buff[64];

+ 3 - 3
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 1.48 2000/08/14 17:46:27 roberto Exp roberto $
+** $Id: lcode.c,v 1.49 2000/08/15 13:18:28 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -693,8 +693,8 @@ const struct OpProperties luaK_opproperties[NUM_OPCODES] = {
   {iO, 0, 0},	/* OP_PUSHNILJMP */
   {iS, 0, 0},	/* OP_FORPREP */
   {iS, 0, 3},	/* OP_FORLOOP */
-  {iS, 3, 0},	/* OP_LFORPREP */
-  {iS, 0, 4},	/* OP_LFORLOOP */
+  {iS, 2, 0},	/* OP_LFORPREP */
+  {iS, 0, 3},	/* OP_LFORLOOP */
   {iAB, VD, 0}	/* OP_CLOSURE */
 };
 

+ 4 - 5
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 1.109 2000/08/15 13:18:28 roberto Exp roberto $
+** $Id: lparser.c,v 1.110 2000/08/22 17:44:17 roberto Exp roberto $
 ** LL(1) Parser and code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -877,10 +877,9 @@ static void forlist (LexState *ls, TString *indexname) {
   next(ls);  /* skip `in' */
   exp1(ls);  /* table */
   new_localvarstr(ls, "*table*", 0);
-  new_localvarstr(ls, "*counter*", 1);
-  new_localvar(ls, indexname, 2);
-  new_localvar(ls, valname, 3);
-  forbody(ls, 4, OP_LFORPREP, OP_LFORLOOP);
+  new_localvar(ls, indexname, 1);
+  new_localvar(ls, valname, 2);
+  forbody(ls, 3, OP_LFORPREP, OP_LFORLOOP);
 }
 
 

+ 19 - 5
ltable.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.c,v 1.52 2000/08/07 20:21:34 roberto Exp roberto $
+** $Id: ltable.c,v 1.53 2000/08/09 19:16:57 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -114,12 +114,26 @@ const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key) {
 }
 
 
-int luaH_pos (lua_State *L, const Hash *t, const TObject *key) {
-  const TObject *v = luaH_get(L, t, key);
-  return (v == &luaO_nilobject) ?  -1 :  /* key not found */
-      (int)(((const char *)v - (const char *)(&t->node[0].val))/sizeof(Node));
+Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) {
+  int i;
+  if (ttype(key) == TAG_NIL)
+    i = 0;  /* first iteration */
+  else {
+    const TObject *v = luaH_get(L, t, key);
+    if (v == &luaO_nilobject)
+      lua_error(L, "invalid key for `next'");
+    i = (int)(((const char *)v -
+               (const char *)(&t->node[0].val)) / sizeof(Node)) + 1;
+  }
+  for (; i<t->size; i++) {
+    Node *n = node(t, i);
+    if (ttype(val(n)) != TAG_NIL)
+      return n;
+  }
+  return NULL;  /* no more elements */
 }
 
+
 /*
 ** try to remove a key without value from a table. To avoid problems with
 ** hash, change `key' for a number with the same hash.

+ 2 - 2
ltable.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.h,v 1.22 2000/06/05 20:15:33 roberto Exp roberto $
+** $Id: ltable.h,v 1.23 2000/06/06 16:31:41 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -21,7 +21,7 @@ const TObject *luaH_getnum (const Hash *t, Number key);
 const TObject *luaH_getstr (const Hash *t, TString *key);
 void luaH_remove (Hash *t, TObject *key);
 TObject *luaH_set (lua_State *L, Hash *t, const TObject *key);
-int luaH_pos (lua_State *L, const Hash *t, const TObject *r);
+Node * luaH_next (lua_State *L, const Hash *t, const TObject *r);
 TObject *luaH_setint (lua_State *L, Hash *t, int key);
 void luaH_setstrnum (lua_State *L, Hash *t, TString *key, Number val);
 unsigned long luaH_hash (lua_State *L, const TObject *key);

+ 4 - 3
lua.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.h,v 1.61 2000/08/29 14:33:31 roberto Exp roberto $
+** $Id: lua.h,v 1.62 2000/08/29 20:43:28 roberto Exp roberto $
 ** Lua - An Extensible Extension Language
 ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
 ** e-mail: [email protected]
@@ -29,6 +29,7 @@
 #define LUA_REFNIL	(-1)
 
 #define LUA_ANYTAG	(-1)
+#define LUA_NOTAG	(-2)
 
 #define LUA_MULTRET	(-1)
 
@@ -129,7 +130,7 @@ int            lua_dobuffer (lua_State *L, const char *buff, size_t size,
 
 
 /*
-** miscelaneous functions
+** miscellaneous functions
 */
 int            lua_newtag (lua_State *L);
 int            lua_copytagmethods (lua_State *L, int tagto, int tagfrom);
@@ -141,7 +142,7 @@ void	       lua_unref (lua_State *L, int ref);
 
 long	       lua_collectgarbage (lua_State *L, long limit);
 
-int            lua_next (lua_State *L, int index, int i);
+int            lua_next (lua_State *L);
 
 
 

+ 14 - 18
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.130 2000/08/29 14:41:56 roberto Exp roberto $
+** $Id: lvm.c,v 1.131 2000/08/29 14:48:16 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -656,34 +656,30 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
         break;
       }
       case OP_LFORPREP: {
+        Node *node;
         if (ttype(top-1) != TAG_TABLE)
           lua_error(L, "`for' table must be a table");
-        top++;  /* counter */
-        L->top = top;
-        ttype(top-1) = TAG_NUMBER;
-        nvalue(top-1) = (Number)luaA_next(L, hvalue(top-2), 0);  /* counter */
-        if (nvalue(top-1) == 0) {  /* `empty' loop? */
-          top -= 2;  /* remove table and counter */
+        node = luaH_next(L, hvalue(top-1), &luaO_nilobject);
+        if (node == NULL) {  /* `empty' loop? */
+          top--;  /* remove table */
           pc += GETARG_S(i)+1;  /* jump to loop end */
         }
         else {
           top += 2;  /* index,value */
-          LUA_ASSERT(top==L->top, "bad top");
+          *(top-2) = *key(node);
+          *(top-1) = *val(node);
         }
         break;
       }
       case OP_LFORLOOP: {
-        int n;
-        top -= 2;  /* remove old index,value */
-        LUA_ASSERT(ttype(top-2) == TAG_TABLE, "invalid table");
-        LUA_ASSERT(ttype(top-1) == TAG_NUMBER, "invalid counter");
-        L->top = top;
-        n = luaA_next(L, hvalue(top-2), (int)nvalue(top-1));
-        if (n == 0)  /* end loop? */
-          top -= 2;  /* remove table and counter */
+        Node *node;
+        LUA_ASSERT(ttype(top-3) == TAG_TABLE, "invalid table");
+        node = luaH_next(L, hvalue(top-3), top-2);
+        if (node == NULL)  /* end loop? */
+          top -= 3;  /* remove table, key, and value */
         else {
-          nvalue(top-1) = (Number)n;
-          top += 2;  /* new index,value */
+          *(top-2) = *key(node);
+          *(top-1) = *val(node);
           pc += GETARG_S(i);  /* repeat loop */
         }
         break;