diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-01-29 11:14:49 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-01-29 11:14:49 -0200 |
commit | caf01b5bfa33617b7bb2c40292f74599f6030eba (patch) | |
tree | 7ebc6352b89f9c331d693701aa4824a7320195e5 | |
parent | ca1f28b829090e99fb82d688dac34b2055d2963e (diff) | |
download | lua-caf01b5bfa33617b7bb2c40292f74599f6030eba.tar.gz lua-caf01b5bfa33617b7bb2c40292f74599f6030eba.tar.bz2 lua-caf01b5bfa33617b7bb2c40292f74599f6030eba.zip |
better implementation for list "for"
-rw-r--r-- | lcode.c | 6 | ||||
-rw-r--r-- | lparser.c | 9 | ||||
-rw-r--r-- | ltable.c | 11 | ||||
-rw-r--r-- | ltable.h | 5 | ||||
-rw-r--r-- | lvm.c | 28 |
5 files changed, 39 insertions, 20 deletions
@@ -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 | ||
@@ -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 | ||
@@ -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 | ||
75 | int 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 | |||
75 | static void setnodevector (lua_State *L, Hash *t, luint32 size) { | 84 | static 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) |
@@ -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 @@ | |||
21 | Hash *luaH_new (lua_State *L, int nhash); | 21 | Hash *luaH_new (lua_State *L, int nhash); |
22 | void luaH_free (lua_State *L, Hash *t); | 22 | void luaH_free (lua_State *L, Hash *t); |
23 | TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); | 23 | TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); |
24 | Node * luaH_next (lua_State *L, Hash *t, const TObject *r); | 24 | Node *luaH_next (lua_State *L, Hash *t, const TObject *r); |
25 | int luaH_nexti (Hash *t, int i); | ||
25 | TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key); | 26 | TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key); |
26 | TObject *luaH_setstr (lua_State *L, Hash *t, TString *key); | 27 | TObject *luaH_setstr (lua_State *L, Hash *t, TString *key); |
27 | 28 | ||
@@ -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 */ |