summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-01-29 11:14:49 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-01-29 11:14:49 -0200
commitcaf01b5bfa33617b7bb2c40292f74599f6030eba (patch)
tree7ebc6352b89f9c331d693701aa4824a7320195e5
parentca1f28b829090e99fb82d688dac34b2055d2963e (diff)
downloadlua-caf01b5bfa33617b7bb2c40292f74599f6030eba.tar.gz
lua-caf01b5bfa33617b7bb2c40292f74599f6030eba.tar.bz2
lua-caf01b5bfa33617b7bb2c40292f74599f6030eba.zip
better implementation for list "for"
-rw-r--r--lcode.c6
-rw-r--r--lparser.c9
-rw-r--r--ltable.c11
-rw-r--r--ltable.h5
-rw-r--r--lvm.c28
5 files changed, 39 insertions, 20 deletions
diff --git a/lcode.c b/lcode.c
index 61b1f2ce..30a25a65 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 1.56 2001/01/15 16:13:24 roberto Exp roberto $ 2** $Id: lcode.c,v 1.57 2001/01/19 13:20:30 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -698,8 +698,8 @@ const OpProperties luaK_opproperties[NUM_OPCODES] = {
698 {iO, 0, 0}, /* OP_PUSHNILJMP */ 698 {iO, 0, 0}, /* OP_PUSHNILJMP */
699 {iS, 0, 0}, /* OP_FORPREP */ 699 {iS, 0, 0}, /* OP_FORPREP */
700 {iS, 0, 3}, /* OP_FORLOOP */ 700 {iS, 0, 3}, /* OP_FORLOOP */
701 {iS, 2, 0}, /* OP_LFORPREP */ 701 {iS, 3, 0}, /* OP_LFORPREP */
702 {iS, 0, 3}, /* OP_LFORLOOP */ 702 {iS, 0, 4}, /* OP_LFORLOOP */
703 {iAB, VD, 0} /* OP_CLOSURE */ 703 {iAB, VD, 0} /* OP_CLOSURE */
704}; 704};
705 705
diff --git a/lparser.c b/lparser.c
index d796fabd..83496128 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.124 2001/01/15 16:13:24 roberto Exp roberto $ 2** $Id: lparser.c,v 1.125 2001/01/19 13:20:30 roberto Exp roberto $
3** LL(1) Parser and code generator for Lua 3** LL(1) Parser and code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -890,9 +890,10 @@ static void forlist (LexState *ls, TString *indexname) {
890 next(ls); /* skip `in' */ 890 next(ls); /* skip `in' */
891 exp1(ls); /* table */ 891 exp1(ls); /* table */
892 new_localvarstr(ls, "(table)", 0); 892 new_localvarstr(ls, "(table)", 0);
893 new_localvar(ls, indexname, 1); 893 new_localvarstr(ls, "(index)", 1);
894 new_localvar(ls, valname, 2); 894 new_localvar(ls, indexname, 2);
895 forbody(ls, 3, OP_LFORPREP, OP_LFORLOOP); 895 new_localvar(ls, valname, 3);
896 forbody(ls, 4, OP_LFORPREP, OP_LFORLOOP);
896} 897}
897 898
898 899
diff --git a/ltable.c b/ltable.c
index 5893f629..f8352fe5 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 1.69 2001/01/26 14:16:35 roberto Exp roberto $ 2** $Id: ltable.c,v 1.70 2001/01/26 15:58:50 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -72,6 +72,15 @@ Node *luaH_next (lua_State *L, Hash *t, const TObject *key) {
72} 72}
73 73
74 74
75int luaH_nexti (Hash *t, int i) {
76 for (i++; i<t->size; i++) {
77 if (ttype(val(node(t, i))) != LUA_TNIL) /* a non-nil value? */
78 return i;
79 }
80 return -1; /* no more elements */
81}
82
83
75static void setnodevector (lua_State *L, Hash *t, luint32 size) { 84static void setnodevector (lua_State *L, Hash *t, luint32 size) {
76 int i; 85 int i;
77 if (size > MAX_INT) 86 if (size > MAX_INT)
diff --git a/ltable.h b/ltable.h
index 482f0ee6..cbdcf743 100644
--- a/ltable.h
+++ b/ltable.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.h,v 1.28 2001/01/26 13:18:00 roberto Exp roberto $ 2** $Id: ltable.h,v 1.29 2001/01/26 14:16:35 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -21,7 +21,8 @@
21Hash *luaH_new (lua_State *L, int nhash); 21Hash *luaH_new (lua_State *L, int nhash);
22void luaH_free (lua_State *L, Hash *t); 22void luaH_free (lua_State *L, Hash *t);
23TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); 23TObject *luaH_set (lua_State *L, Hash *t, const TObject *key);
24Node * luaH_next (lua_State *L, Hash *t, const TObject *r); 24Node *luaH_next (lua_State *L, Hash *t, const TObject *r);
25int luaH_nexti (Hash *t, int i);
25TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key); 26TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key);
26TObject *luaH_setstr (lua_State *L, Hash *t, TString *key); 27TObject *luaH_setstr (lua_State *L, Hash *t, TString *key);
27 28
diff --git a/lvm.c b/lvm.c
index 9a2c75f4..1da0ce20 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.157 2001/01/24 16:20:54 roberto Exp roberto $ 2** $Id: lvm.c,v 1.158 2001/01/26 18:43:22 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -644,28 +644,36 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
644 break; 644 break;
645 } 645 }
646 case OP_LFORPREP: { 646 case OP_LFORPREP: {
647 Node *node; 647 int n;
648 Hash *t;
648 if (ttype(top-1) != LUA_TTABLE) 649 if (ttype(top-1) != LUA_TTABLE)
649 luaD_error(L, "`for' table must be a table"); 650 luaD_error(L, "`for' table must be a table");
650 node = luaH_next(L, hvalue(top-1), &luaO_nilobject); 651 t = hvalue(top-1);
651 if (node == NULL) { /* `empty' loop? */ 652 n = luaH_nexti(t, -1);
653 if (n == -1) { /* `empty' loop? */
652 top--; /* remove table */ 654 top--; /* remove table */
653 dojump(pc, i); /* jump to loop end */ 655 dojump(pc, i); /* jump to loop end */
654 } 656 }
655 else { 657 else {
656 top += 2; /* index,value */ 658 Node *node = node(t, n);
659 top += 3; /* index,key,value */
660 setnvalue(top-3, n); /* index */
657 setobj(top-2, key(node)); 661 setobj(top-2, key(node));
658 setobj(top-1, val(node)); 662 setobj(top-1, val(node));
659 } 663 }
660 break; 664 break;
661 } 665 }
662 case OP_LFORLOOP: { 666 case OP_LFORLOOP: {
663 Node *node; 667 Hash *t = hvalue(top-4);
664 lua_assert(ttype(top-3) == LUA_TTABLE); 668 int n = (int)nvalue(top-3);
665 node = luaH_next(L, hvalue(top-3), top-2); 669 lua_assert(ttype(top-3) == LUA_TNUMBER);
666 if (node == NULL) /* end loop? */ 670 lua_assert(ttype(top-4) == LUA_TTABLE);
667 top -= 3; /* remove table, key, and value */ 671 n = luaH_nexti(t, n);
672 if (n == -1) /* end loop? */
673 top -= 4; /* remove table, index, key, and value */
668 else { 674 else {
675 Node *node = node(t, n);
676 setnvalue(top-3, n); /* index */
669 setobj(top-2, key(node)); 677 setobj(top-2, key(node));
670 setobj(top-1, val(node)); 678 setobj(top-1, val(node));
671 dojump(pc, i); /* repeat loop */ 679 dojump(pc, i); /* repeat loop */