From af19d556355b6e79296811cb18fe511f8784b8f1 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 13 May 2002 10:09:00 -0300 Subject: generic for also coded to make test at the end of the loop --- lparser.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'lparser.c') diff --git a/lparser.c b/lparser.c index c24b5412..19b605bd 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.180 2002/05/10 17:02:32 roberto Exp roberto $ +** $Id: lparser.c,v 1.181 2002/05/10 19:22:11 roberto Exp roberto $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -979,15 +979,16 @@ static void whilestat (LexState *ls, int line) { int whileinit, blockinit, expinit; expdesc v; BlockCnt bl; - next(ls); - whileinit = luaK_jump(fs); + next(ls); /* skip WHILE */ + whileinit = luaK_jump(fs); /* jump to condition (which will be moved) */ expinit = luaK_getlabel(fs); - expr(ls, &v); + expr(ls, &v); /* parse condition */ if (v.k == VK) v.k = VTRUE; /* `trues' are all equal here */ lineexp = ls->linenumber; luaK_goiffalse(fs, &v); - luaK_dischargejpc(fs); - sizeexp = fs->pc - expinit; + luaK_concat(fs, &v.f, fs->jpc); + fs->jpc = NO_JUMP; + sizeexp = fs->pc - expinit; /* size of expression code */ if (sizeexp > MAXEXPWHILE) luaX_syntaxerror(ls, "while condition too complex"); for (i = 0; i < sizeexp; i++) /* save `exp' code */ @@ -998,14 +999,15 @@ static void whilestat (LexState *ls, int line) { blockinit = luaK_getlabel(fs); block(ls); luaK_patchtohere(fs, whileinit); /* initial jump jumps to here */ + /* move `exp' back to code */ if (v.t != NO_JUMP) v.t += fs->pc - expinit; if (v.f != NO_JUMP) v.f += fs->pc - expinit; for (i=0; if->lineinfo[endfor] = line; /* pretend that `OP_FOR' starts the loop */ } @@ -1070,6 +1072,7 @@ static void forlist (LexState *ls, TString *indexname) { /* forlist -> NAME {,NAME} IN explist1 DO body */ FuncState *fs = ls->fs; expdesc e; + int line; int nvars = 0; int prep; int base = fs->freereg; @@ -1081,16 +1084,19 @@ static void forlist (LexState *ls, TString *indexname) { next(ls); } check(ls, TK_IN); + line = ls->linenumber; adjust_assign(ls, 3, explist1(ls, &e), &e); luaK_reserveregs(fs, nvars - 3); /* registers for other variables */ - luaK_codeABC(fs, OP_TFORPREP, base, 0, 0); - luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); + luaK_codeAsBx(fs, OP_TFORPREP, base, NO_JUMP); adjustlocalvars(ls, nvars); /* scope for all variables */ - prep = luaK_jump(fs); check(ls, TK_DO); + prep = luaK_getlabel(fs); block(ls); - luaK_patchlist(fs, luaK_jump(fs), prep-1); - luaK_patchtohere(fs, prep); + luaK_patchtohere(fs, prep-1); + removevars(fs->ls, fs->nactvar - nvars); /* deactivate locals for next op. */ + luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars - 3); + luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ + luaK_patchlist(fs, luaK_jump(fs), prep); } -- cgit v1.2.3-55-g6feb