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 | ||
