aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-02-05 20:39:12 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-02-05 20:39:12 -0200
commit38b0e6128da7796300e2e8621e87835e16539f5b (patch)
tree5b0a7ad2b0fb850d47f0566fd06b8cda013bbc8b /lparser.c
parentaddbe8c8b0587fd316f33fb013034e035f9217ed (diff)
downloadlua-38b0e6128da7796300e2e8621e87835e16539f5b.tar.gz
lua-38b0e6128da7796300e2e8621e87835e16539f5b.tar.bz2
lua-38b0e6128da7796300e2e8621e87835e16539f5b.zip
simpler implementation for `for' loops
Diffstat (limited to 'lparser.c')
-rw-r--r--lparser.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/lparser.c b/lparser.c
index fe81ed1d..4ddca7a8 100644
--- a/lparser.c
+++ b/lparser.c
@@ -955,17 +955,17 @@ static void exp1 (LexState *ls) {
955} 955}
956 956
957 957
958static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) { 958static void forbody (LexState *ls, int nvar, OpCode loopfor) {
959 /* forbody -> DO block END */ 959 /* forbody -> DO block END */
960 FuncState *fs = ls->fs; 960 FuncState *fs = ls->fs;
961 int basereg = fs->freereg - nvar; 961 int basereg = fs->freereg - nvar;
962 int prep = luaK_codeAsBc(fs, prepfor, basereg, NO_JUMP); 962 int prep = luaK_jump(fs);
963 int blockinit = luaK_getlabel(fs); 963 int blockinit = luaK_getlabel(fs);
964 check(ls, TK_DO); 964 check(ls, TK_DO);
965 adjustlocalvars(ls, nvar); /* scope for control variables */ 965 adjustlocalvars(ls, nvar); /* scope for control variables */
966 block(ls); 966 block(ls);
967 luaK_patchlist(fs, prep, luaK_getlabel(fs));
967 luaK_patchlist(fs, luaK_codeAsBc(fs, loopfor, basereg, NO_JUMP), blockinit); 968 luaK_patchlist(fs, luaK_codeAsBc(fs, loopfor, basereg, NO_JUMP), blockinit);
968 luaK_fixfor(fs, prep, luaK_getlabel(fs));
969 removelocalvars(ls, nvar, 1); 969 removelocalvars(ls, nvar, 1);
970} 970}
971 971
@@ -986,13 +986,15 @@ static void fornum (LexState *ls, TString *varname) {
986 new_localvar(ls, varname, 0); 986 new_localvar(ls, varname, 0);
987 new_localvarstr(ls, "(limit)", 1); 987 new_localvarstr(ls, "(limit)", 1);
988 new_localvarstr(ls, "(step)", 2); 988 new_localvarstr(ls, "(step)", 2);
989 forbody(ls, 3, OP_FORPREP, OP_FORLOOP); 989 luaK_codeABC(fs, OP_SUB, fs->freereg - 3, fs->freereg - 3, fs->freereg - 1);
990 forbody(ls, 3, OP_FORLOOP);
990} 991}
991 992
992 993
993static void forlist (LexState *ls, TString *indexname) { 994static void forlist (LexState *ls, TString *indexname) {
994 /* forlist -> NAME,NAME IN exp1 forbody */ 995 /* forlist -> NAME,NAME IN exp1 forbody */
995 TString *valname; 996 TString *valname;
997 FuncState *fs = ls->fs;
996 check(ls, ','); 998 check(ls, ',');
997 valname = str_checkname(ls); 999 valname = str_checkname(ls);
998 next(ls); /* skip var name */ 1000 next(ls); /* skip var name */
@@ -1002,8 +1004,9 @@ static void forlist (LexState *ls, TString *indexname) {
1002 new_localvarstr(ls, "(index)", 1); 1004 new_localvarstr(ls, "(index)", 1);
1003 new_localvar(ls, indexname, 2); 1005 new_localvar(ls, indexname, 2);
1004 new_localvar(ls, valname, 3); 1006 new_localvar(ls, valname, 3);
1005 luaK_reserveregs(ls->fs, 3); /* registers for control, index and val */ 1007 luaK_reserveregs(fs, 3); /* registers for control, index and val */
1006 forbody(ls, 4, OP_TFORPREP, OP_TFORLOOP); 1008 luaK_codeABc(fs, OP_LOADK, fs->freereg - 3, luaK_numberK(fs, -1));
1009 forbody(ls, 4, OP_TFORLOOP);
1007} 1010}
1008 1011
1009 1012