first implementation of FOR

This commit is contained in:
Roberto Ierusalimschy
2000-04-12 15:57:19 -03:00
parent 0c3fe2c44b
commit f9cf402fbd
7 changed files with 87 additions and 15 deletions

View File

@@ -1,5 +1,5 @@
/*
** $Id: lparser.c,v 1.80 2000/04/10 19:21:14 roberto Exp roberto $
** $Id: lparser.c,v 1.81 2000/04/11 18:37:18 roberto Exp roberto $
** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -884,7 +884,7 @@ static void whilestat (LexState *ls, int line) {
block(ls);
luaK_patchlist(fs, luaK_jump(fs), while_init);
luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
check_END(ls, TK_WHILE, line);
check_END(ls, TK_WHILE, line); /* trace END when loop ends */
leavebreak(fs, &bl);
}
@@ -906,7 +906,40 @@ static void repeatstat (LexState *ls, int line) {
}
static void test_and_bock (LexState *ls, expdesc *v) {
static void forstat (LexState *ls, int line) {
/* forstat -> FOR NAME '=' expr1 ',' expr1 [',' expr1] DO block END */
FuncState *fs = ls->fs;
int prep;
int blockinit;
Breaklabel bl;
enterbreak(fs, &bl);
setline_and_next(ls); /* skip for */
store_localvar(ls, str_checkname(ls), 0); /* control variable */
check(ls, '=');
exp1(ls); /* initial value */
check(ls, ',');
exp1(ls); /* limit */
if (optional(ls, ','))
exp1(ls); /* optional step */
else
luaK_code1(fs, OP_PUSHINT, 1); /* default step */
adjustlocalvars(ls, 1, 0); /* init scope for control variable */
add_localvar(ls, " limit ");
add_localvar(ls, " step ");
prep = luaK_code0(fs, OP_FORPREP);
blockinit = luaK_getlabel(fs);
check(ls, TK_DO);
block(ls);
luaK_patchlist(fs, prep, luaK_getlabel(fs));
luaK_patchlist(fs, luaK_code0(fs, OP_FORLOOP), blockinit);
check_END(ls, TK_WHILE, line);
leavebreak(fs, &bl);
removelocalvars(ls, 3, fs->lastsetline);
}
static void test_and_block (LexState *ls, expdesc *v) {
/* test_and_block -> [IF | ELSEIF] cond THEN block */
setline_and_next(ls); /* skip IF or ELSEIF */
expr(ls, v); /* cond */
luaK_goiftrue(ls->fs, v, 0);
@@ -921,11 +954,11 @@ static void ifstat (LexState *ls, int line) {
FuncState *fs = ls->fs;
expdesc v;
int escapelist = NO_JUMP;
test_and_bock(ls, &v); /* IF cond THEN block */
test_and_block(ls, &v); /* IF cond THEN block */
while (ls->token == TK_ELSEIF) {
luaK_concat(fs, &escapelist, luaK_jump(fs));
luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
test_and_bock(ls, &v); /* ELSEIF cond THEN block */
test_and_block(ls, &v); /* ELSEIF cond THEN block */
}
if (ls->token == TK_ELSE) {
luaK_concat(fs, &escapelist, luaK_jump(fs));
@@ -1062,6 +1095,10 @@ static int stat (LexState *ls) {
check_END(ls, TK_DO, line);
return 1;
case TK_FOR: /* stat -> forstat */
forstat(ls, line);
return 1;
case TK_REPEAT: /* stat -> repeatstat */
repeatstat(ls, line);
return 1;