private static void block(LexState ls) { /* block . chunk */ FuncState fs = ls.fs; BlockCnt bl = new BlockCnt(); enterblock(fs, bl, 0); chunk(ls); Lua.lua_assert(bl.breaklist == Lua.NO_JUMP); leaveblock(fs); }
private static void enterblock(FuncState fs, BlockCnt bl, lu_byte isbreakable) { bl.breaklist = Lua.NO_JUMP; bl.continuelist = Lua.NO_JUMP; bl.isbreakable = isbreakable; bl.nactvar = fs.nactvar; bl.upval = 0; bl.previous = fs.bl; fs.bl = bl; Lua.lua_assert(fs.freereg == fs.nactvar); }
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 */ Lua.luaX_next(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: Lua.luaX_syntaxerror(ls, Lua.LUA_QL("=") + " or " + Lua.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 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) ? Lua.luaK_codeAsBx(fs, OpCode.OP_FORPREP, base_, Lua.NO_JUMP) : Lua.luaK_jump(fs); enterblock(fs, bl, 0); /* scope for declared variables */ adjustlocalvars(ls, nvars); Lua.luaK_reserveregs(fs, nvars); block(ls); leaveblock(fs); /* end of scope for declared variables */ Lua.luaK_patchtohere(fs, prep); Lua.luaK_patchtohere(fs, bl.previous.continuelist); /* continue, if any, jumps to here */ endfor = (isnum != 0) ? Lua.luaK_codeAsBx(fs, OpCode.OP_FORLOOP, base_, Lua.NO_JUMP) : Lua.luaK_codeABC(fs, OpCode.OP_TFORLOOP, base_, 0, nvars); Lua.luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ Lua.luaK_patchlist(fs, ((isnum != 0) ? endfor : Lua.luaK_jump(fs)), prep + 1); }
private static void repeatstat(LexState ls, int line) { /* repeatstat . REPEAT block UNTIL cond */ int condexit; FuncState fs = ls.fs; int repeat_init = Lua.luaK_getlabel(fs); BlockCnt bl1 = new BlockCnt(), bl2 = new BlockCnt(); enterblock(fs, bl1, 1); /* loop block */ enterblock(fs, bl2, 0); /* scope block */ Lua.luaX_next(ls); /* skip REPEAT */ chunk(ls); Lua.luaK_patchtohere(fs, bl1.continuelist); 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 */ Lua.luaK_patchlist(ls.fs, condexit, repeat_init); /* close the loop */ } else { /* complete semantics when there are upvalues */ breakstat(ls); /* if condition then break */ Lua.luaK_patchtohere(ls.fs, condexit); /* else... */ leaveblock(fs); /* finish scope... */ Lua.luaK_patchlist(ls.fs, Lua.luaK_jump(fs), repeat_init); /* and repeat */ } leaveblock(fs); /* finish loop */ }
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(); Lua.luaX_next(ls); /* skip WHILE */ whileinit = Lua.luaK_getlabel(fs); condexit = cond(ls); enterblock(fs, bl, 1); checknext(ls, (int)RESERVED.TK_DO); block(ls); Lua.luaK_patchlist(fs, Lua.luaK_jump(fs), whileinit); Lua.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); Lua.luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ }