Explorar el Código

better implementation for list "for"

Roberto Ierusalimschy hace 24 años
padre
commit
caf01b5bfa
Se han modificado 5 ficheros con 39 adiciones y 20 borrados
  1. 3 3
      lcode.c
  2. 5 4
      lparser.c
  3. 10 1
      ltable.c
  4. 3 2
      ltable.h
  5. 18 10
      lvm.c

+ 3 - 3
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 1.56 2001/01/15 16:13:24 roberto Exp roberto $
+** $Id: lcode.c,v 1.57 2001/01/19 13:20:30 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -698,8 +698,8 @@ const OpProperties luaK_opproperties[NUM_OPCODES] = {
   {iO, 0, 0},	/* OP_PUSHNILJMP */
   {iS, 0, 0},	/* OP_FORPREP */
   {iS, 0, 3},	/* OP_FORLOOP */
-  {iS, 2, 0},	/* OP_LFORPREP */
-  {iS, 0, 3},	/* OP_LFORLOOP */
+  {iS, 3, 0},	/* OP_LFORPREP */
+  {iS, 0, 4},	/* OP_LFORLOOP */
   {iAB, VD, 0}	/* OP_CLOSURE */
 };
 

+ 5 - 4
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 1.124 2001/01/15 16:13:24 roberto Exp roberto $
+** $Id: lparser.c,v 1.125 2001/01/19 13:20:30 roberto Exp roberto $
 ** LL(1) Parser and code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -890,9 +890,10 @@ static void forlist (LexState *ls, TString *indexname) {
   next(ls);  /* skip `in' */
   exp1(ls);  /* table */
   new_localvarstr(ls, "(table)", 0);
-  new_localvar(ls, indexname, 1);
-  new_localvar(ls, valname, 2);
-  forbody(ls, 3, OP_LFORPREP, OP_LFORLOOP);
+  new_localvarstr(ls, "(index)", 1);
+  new_localvar(ls, indexname, 2);
+  new_localvar(ls, valname, 3);
+  forbody(ls, 4, OP_LFORPREP, OP_LFORLOOP);
 }
 
 

+ 10 - 1
ltable.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.c,v 1.69 2001/01/26 14:16:35 roberto Exp roberto $
+** $Id: ltable.c,v 1.70 2001/01/26 15:58:50 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -72,6 +72,15 @@ Node *luaH_next (lua_State *L, Hash *t, const TObject *key) {
 }
 
 
+int luaH_nexti (Hash *t, int i) {
+  for (i++; i<t->size; i++) {
+    if (ttype(val(node(t, i))) != LUA_TNIL)  /* a non-nil value? */
+      return i;
+  }
+  return -1;  /* no more elements */
+}
+
+
 static void setnodevector (lua_State *L, Hash *t, luint32 size) {
   int i;
   if (size > MAX_INT)

+ 3 - 2
ltable.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.h,v 1.28 2001/01/26 13:18:00 roberto Exp roberto $
+** $Id: ltable.h,v 1.29 2001/01/26 14:16:35 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -21,7 +21,8 @@
 Hash *luaH_new (lua_State *L, int nhash);
 void luaH_free (lua_State *L, Hash *t);
 TObject *luaH_set (lua_State *L, Hash *t, const TObject *key);
-Node * luaH_next (lua_State *L, Hash *t, const TObject *r);
+Node *luaH_next (lua_State *L, Hash *t, const TObject *r);
+int luaH_nexti (Hash *t, int i);
 TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key);
 TObject *luaH_setstr (lua_State *L, Hash *t, TString *key);
 

+ 18 - 10
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.157 2001/01/24 16:20:54 roberto Exp roberto $
+** $Id: lvm.c,v 1.158 2001/01/26 18:43:22 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -644,28 +644,36 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
         break;
       }
       case OP_LFORPREP: {
-        Node *node;
+        int n;
+        Hash *t;
         if (ttype(top-1) != LUA_TTABLE)
           luaD_error(L, "`for' table must be a table");
-        node = luaH_next(L, hvalue(top-1), &luaO_nilobject);
-        if (node == NULL) {  /* `empty' loop? */
+        t = hvalue(top-1);
+        n = luaH_nexti(t, -1);
+        if (n == -1) {  /* `empty' loop? */
           top--;  /* remove table */
           dojump(pc, i);  /* jump to loop end */
         }
         else {
-          top += 2;  /* index,value */
+          Node *node = node(t, n);
+          top += 3;  /* index,key,value */
+          setnvalue(top-3, n);  /* index */
           setobj(top-2, key(node));
           setobj(top-1, val(node));
         }
         break;
       }
       case OP_LFORLOOP: {
-        Node *node;
-        lua_assert(ttype(top-3) == LUA_TTABLE);
-        node = luaH_next(L, hvalue(top-3), top-2);
-        if (node == NULL)  /* end loop? */
-          top -= 3;  /* remove table, key, and value */
+        Hash *t = hvalue(top-4);
+        int n = (int)nvalue(top-3);
+        lua_assert(ttype(top-3) == LUA_TNUMBER);
+        lua_assert(ttype(top-4) == LUA_TTABLE);
+        n = luaH_nexti(t, n);
+        if (n == -1)  /* end loop? */
+          top -= 4;  /* remove table, index, key, and value */
         else {
+          Node *node = node(t, n);
+          setnvalue(top-3, n);  /* index */
           setobj(top-2, key(node));
           setobj(top-1, val(node));
           dojump(pc, i);  /* repeat loop */