diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-02-05 20:39:12 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-02-05 20:39:12 -0200 |
commit | 38b0e6128da7796300e2e8621e87835e16539f5b (patch) | |
tree | 5b0a7ad2b0fb850d47f0566fd06b8cda013bbc8b /lparser.c | |
parent | addbe8c8b0587fd316f33fb013034e035f9217ed (diff) | |
download | lua-38b0e6128da7796300e2e8621e87835e16539f5b.tar.gz lua-38b0e6128da7796300e2e8621e87835e16539f5b.tar.bz2 lua-38b0e6128da7796300e2e8621e87835e16539f5b.zip |
simpler implementation for `for' loops
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 15 |
1 files changed, 9 insertions, 6 deletions
@@ -955,17 +955,17 @@ static void exp1 (LexState *ls) { | |||
955 | } | 955 | } |
956 | 956 | ||
957 | 957 | ||
958 | static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) { | 958 | static 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 | ||
993 | static void forlist (LexState *ls, TString *indexname) { | 994 | static 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 | ||