aboutsummaryrefslogtreecommitdiff
path: root/lparser.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-04-09 16:47:44 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-04-09 16:47:44 -0300
commit7b65328c8e89ecc999e47d00288bfa4cf6692cdc (patch)
tree4bff202763e7389ca40a44003703376d32eeaf78 /lparser.c
parentd2e05589d738c3a1b563879435d5cc0830719fd1 (diff)
downloadlua-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.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/lparser.c b/lparser.c
index 6b0234f5..9e723f0d 100644
--- a/lparser.c
+++ b/lparser.c
@@ -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
1030static void forlist (LexState *ls, TString *indexname) { 1031static 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);