diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-04-09 16:47:44 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-04-09 16:47:44 -0300 |
commit | 7b65328c8e89ecc999e47d00288bfa4cf6692cdc (patch) | |
tree | 4bff202763e7389ca40a44003703376d32eeaf78 /lparser.c | |
parent | d2e05589d738c3a1b563879435d5cc0830719fd1 (diff) | |
download | lua-7b65328c8e89ecc999e47d00288bfa4cf6692cdc.tar.gz lua-7b65328c8e89ecc999e47d00288bfa4cf6692cdc.tar.bz2 lua-7b65328c8e89ecc999e47d00288bfa4cf6692cdc.zip |
new semantics for `generic for' (with state)
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 24 |
1 files changed, 13 insertions, 11 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.173 2002/03/25 17:47:14 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.174 2002/04/02 20:34:15 roberto Exp roberto $ |
3 | ** Lua Parser | 3 | ** Lua Parser |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -331,6 +331,7 @@ static void enterblock (FuncState *fs, BlockCnt *bl, int isbreakable) { | |||
331 | bl->upval = 0; | 331 | bl->upval = 0; |
332 | bl->previous = fs->bl; | 332 | bl->previous = fs->bl; |
333 | fs->bl = bl; | 333 | fs->bl = bl; |
334 | lua_assert(fs->freereg == fs->nactloc); | ||
334 | } | 335 | } |
335 | 336 | ||
336 | 337 | ||
@@ -1028,24 +1029,25 @@ static void fornum (LexState *ls, TString *varname, int line) { | |||
1028 | 1029 | ||
1029 | 1030 | ||
1030 | static void forlist (LexState *ls, TString *indexname) { | 1031 | static void forlist (LexState *ls, TString *indexname) { |
1031 | /* forlist -> NAME {,NAME} IN exp1 DO body */ | 1032 | /* forlist -> NAME {,NAME} IN explist1 DO body */ |
1032 | FuncState *fs = ls->fs; | 1033 | FuncState *fs = ls->fs; |
1034 | expdesc e; | ||
1033 | int nvars = 0; | 1035 | int nvars = 0; |
1034 | int prep; | 1036 | int prep; |
1035 | int base = fs->freereg; | 1037 | int base = fs->freereg; |
1036 | new_localvarstr(ls, "(for generator)", 0); | 1038 | new_localvarstr(ls, "(for generator)", nvars++); |
1037 | new_localvar(ls, indexname, ++nvars); | 1039 | new_localvarstr(ls, "(for state)", nvars++); |
1040 | new_localvar(ls, indexname, nvars++); | ||
1038 | while (optional(ls, ',')) { | 1041 | while (optional(ls, ',')) { |
1039 | new_localvar(ls, str_checkname(ls), ++nvars); | 1042 | new_localvar(ls, str_checkname(ls), nvars++); |
1040 | next(ls); | 1043 | next(ls); |
1041 | } | 1044 | } |
1042 | check(ls, TK_IN); | 1045 | check(ls, TK_IN); |
1043 | exp1(ls); /* table */ | 1046 | adjust_assign(ls, 3, explist1(ls, &e), &e); |
1044 | luaK_checkstack(fs, 2); /* at least two slots, to traverse tables */ | 1047 | luaK_reserveregs(fs, nvars - 3); /* registers for other variables */ |
1045 | luaK_reserveregs(fs, nvars); /* registers for vars */ | 1048 | luaK_codeABC(fs, OP_TFORPREP, base, 0, 0); |
1046 | luaK_codeABC(fs, OP_LOADNIL, base+1, base+nvars, 0); | 1049 | luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); |
1047 | adjustlocalvars(ls, nvars+1); /* scope for control variables */ | 1050 | adjustlocalvars(ls, nvars); /* scope for all variables */ |
1048 | luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); | ||
1049 | prep = luaK_jump(fs); | 1051 | prep = luaK_jump(fs); |
1050 | check(ls, TK_DO); | 1052 | check(ls, TK_DO); |
1051 | block(ls); | 1053 | block(ls); |