private static void forstat(LexState ls, int line) { /* forstat . FOR (fornum | forlist) END */ FuncState fs = ls.fs; TString varname; BlockCnt bl = new BlockCnt(); enterblock(fs, bl, 1); /* scope for loop and control variables */ LuaXNext(ls); /* skip `for' */ varname = str_checkname(ls); /* first variable name */ switch (ls.t.token) { case '=': fornum(ls, varname, line); break; case ',': case (int)RESERVED.TK_IN: forlist(ls, varname); break; default: LuaXSyntaxError(ls, LUA_QL("=") + " or " + LUA_QL("in") + " expected"); break; } check_match(ls, (int)RESERVED.TK_END, (int)RESERVED.TK_FOR, line); leaveblock(fs); /* loop scope (`break' jumps to this point) */ }
private static void enterblock(FuncState fs, BlockCnt bl, lu_byte isbreakable) { bl.breaklist = NO_JUMP; bl.isbreakable = isbreakable; bl.nactvar = fs.nactvar; bl.upval = 0; bl.previous = fs.bl; fs.bl = bl; LuaAssert(fs.freereg == fs.nactvar); }
private static void forbody(LexState ls, int base_, int line, int nvars, int isnum) { /* forbody . DO block */ BlockCnt bl = new BlockCnt(); FuncState fs = ls.fs; int prep, endfor; adjustlocalvars(ls, 3); /* control variables */ checknext(ls, (int)RESERVED.TK_DO); prep = (isnum != 0) ? LuaKCodeAsBx(fs, OpCode.OP_FORPREP, base_, NO_JUMP) : LuaKJump(fs); enterblock(fs, bl, 0); /* scope for declared variables */ adjustlocalvars(ls, nvars); LuaKReserveRegs(fs, nvars); block(ls); leaveblock(fs); /* end of scope for declared variables */ LuaKPatchToHere(fs, prep); endfor = (isnum!=0) ? LuaKCodeAsBx(fs, OpCode.OP_FORLOOP, base_, NO_JUMP) : LuaKCodeABC(fs, OpCode.OP_TFORLOOP, base_, 0, nvars); LuaKFixLine(fs, line); /* pretend that `OP_FOR' starts the loop */ LuaKPatchList(fs, ((isnum!=0) ? endfor : LuaKJump(fs)), prep + 1); }
private static void block(LexState ls) { /* block . chunk */ FuncState fs = ls.fs; BlockCnt bl = new BlockCnt(); enterblock(fs, bl, 0); chunk(ls); LuaAssert(bl.breaklist == NO_JUMP); leaveblock(fs); }
private static void whilestat(LexState ls, int line) { /* whilestat . WHILE cond DO block END */ FuncState fs = ls.fs; int whileinit; int condexit; BlockCnt bl = new BlockCnt(); LuaXNext(ls); /* skip WHILE */ whileinit = LuaKGetLabel(fs); condexit = cond(ls); enterblock(fs, bl, 1); checknext(ls, (int)RESERVED.TK_DO); block(ls); LuaKPatchList(fs, LuaKJump(fs), whileinit); check_match(ls, (int)RESERVED.TK_END, (int)RESERVED.TK_WHILE, line); leaveblock(fs); LuaKPatchToHere(fs, condexit); /* false conditions finish the loop */ }
private static void repeatstat(LexState ls, int line) { /* repeatstat . REPEAT block UNTIL cond */ int condexit; FuncState fs = ls.fs; int repeat_init = LuaKGetLabel(fs); BlockCnt bl1 = new BlockCnt(), bl2 = new BlockCnt(); enterblock(fs, bl1, 1); /* loop block */ enterblock(fs, bl2, 0); /* scope block */ LuaXNext(ls); /* skip REPEAT */ chunk(ls); check_match(ls, (int)RESERVED.TK_UNTIL, (int)RESERVED.TK_REPEAT, line); condexit = cond(ls); /* read condition (inside scope block) */ if (bl2.upval==0) { /* no upvalues? */ leaveblock(fs); /* finish scope */ LuaKPatchList(ls.fs, condexit, repeat_init); /* close the loop */ } else { /* complete semantics when there are upvalues */ breakstat(ls); /* if condition then break */ LuaKPatchToHere(ls.fs, condexit); /* else... */ leaveblock(fs); /* finish scope... */ LuaKPatchList(ls.fs, LuaKJump(fs), repeat_init); /* and repeat */ } leaveblock(fs); /* finish loop */ }
private static void forbody(LexState ls, int base_, int line, int nvars, int isnum) { /* forbody . DO block */ BlockCnt bl = new BlockCnt(); FuncState fs = ls.fs; int prep, endfor; adjustlocalvars(ls, 3); /* control variables */ checknext(ls, (int)RESERVED.TK_DO); prep = (isnum != 0) ? luaK_codeAsBx(fs, OpCode.OP_FORPREP, base_, NO_JUMP) : luaK_jump(fs); enterblock(fs, bl, 0); /* scope for declared variables */ adjustlocalvars(ls, nvars); luaK_reserveregs(fs, nvars); block(ls); leaveblock(fs); /* end of scope for declared variables */ luaK_patchtohere(fs, prep); luaK_patchtohere(fs, bl.previous.continuelist); /* continue, if any, jumps to here */ endfor = (isnum != 0) ? luaK_codeAsBx(fs, OpCode.OP_FORLOOP, base_, NO_JUMP) : luaK_codeABC(fs, OpCode.OP_TFORLOOP, base_, 0, nvars); luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ luaK_patchlist(fs, ((isnum != 0) ? endfor : luaK_jump(fs)), prep + 1); }
private static void whilestat(LexState ls, int line) { /* whilestat . WHILE cond DO block END */ FuncState fs = ls.fs; int whileinit; int condexit; BlockCnt bl = new BlockCnt(); luaX_next(ls); /* skip WHILE */ whileinit = luaK_getlabel(fs); condexit = cond(ls); enterblock(fs, bl, 1); checknext(ls, (int)RESERVED.TK_DO); block(ls); luaK_patchlist(fs, luaK_jump(fs), whileinit); luaK_patchlist(fs, bl.continuelist, whileinit); /* continue goes to start, too */ check_match(ls, (int)RESERVED.TK_END, (int)RESERVED.TK_WHILE, line); leaveblock(fs); luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ }