private static void CgDoStat(FuncInfo fi, DoStat node) { fi.EnterScope(false); CgBlock(fi, node.Block); fi.CloseOpenUpvals(); fi.ExitScope(); }
private static void CgForInStat(FuncInfo fi, ForInStat node) { fi.EnterScope(true); CgLocalVarDeclStat(fi, new LocalVarDeclStat { NameList = new List <string> { "(for generator)", "(for state)", "(for control)" }, ExpList = node.ExpList }); foreach (var name in node.NameList) { fi.AddLocVar(name); } var pcJmpToTfc = fi.EmitJmp(0, 0); CgBlock(fi, node.Block); fi.CloseOpenUpvals(); fi.FixsBx(pcJmpToTfc, fi.PC() - pcJmpToTfc); var rGenerator = fi.SlotOfLocVar("(for generator)"); fi.EmitTForCall(rGenerator, node.NameList.Count); fi.EmitTForLoop(rGenerator + 2, pcJmpToTfc - fi.PC() - 1); fi.ExitScope(); }
private static void CgForNumStat(FuncInfo fi, ForNumStat node) { fi.EnterScope(true); CgLocalVarDeclStat(fi, new LocalVarDeclStat { NameList = new List <string> { "(for index)", "(for limit)", "(for step)" }, ExpList = new List <Exp> { node.InitExp, node.LimitExp, node.StepExp } }); fi.AddLocVar(node.VarName); var a = fi.UsedRegs - 4; var pcForPrep = fi.EmitForPrep(a, 0); CgBlock(fi, node.Block); fi.CloseOpenUpvals(); var pcForLoop = fi.EmitForLoop(a, 0); fi.FixsBx(pcForPrep, pcForLoop - pcForPrep - 1); fi.FixsBx(pcForLoop, pcForPrep - pcForLoop); fi.ExitScope(); }
private static void CgRepeatStat(FuncInfo fi, RepeatStat node) { fi.EnterScope(true); var pcBeforeBlock = fi.PC(); CgBlock(fi, node.Block); var r = fi.AllocReg(); CgExp(fi, node.Exp, r, 1); fi.FreeReg(); fi.EmitTest(r, 0); fi.EmitJmp(fi.GetJmpArgA(), pcBeforeBlock - fi.PC() - 1); fi.CloseOpenUpvals(); fi.ExitScope(); }
private static void CgWhileStat(FuncInfo fi, WhileStat node) { var pcBeforeExp = fi.PC(); var r = fi.AllocReg(); CgExp(fi, node.Exp, r, 1); fi.FreeReg(); fi.EmitTest(r, 0); var pcJmpToEnd = fi.EmitJmp(0, 0); fi.EnterScope(true); CgBlock(fi, node.Block); fi.CloseOpenUpvals(); fi.EmitJmp(0, pcBeforeExp - fi.PC() - 1); fi.ExitScope(); fi.FixsBx(pcJmpToEnd, fi.PC() - pcJmpToEnd); }
private static void CgIfStat(FuncInfo fi, IfStat node) { var pcJmpToEnds = new int[node.Exps.Count]; var pcJmpToNextExp = -1; for (var i = 0; i < node.Exps.Count; i++) { var exp = node.Exps[i]; if (pcJmpToNextExp >= 0) { fi.FixsBx(pcJmpToNextExp, fi.PC() - pcJmpToNextExp); } var r = fi.AllocReg(); CgExp(fi, exp, r, 1); fi.FreeReg(); fi.EmitTest(r, 0); pcJmpToNextExp = fi.EmitJmp(0, 0); fi.EnterScope(false); CgBlock(fi, node.Blocks[i]); fi.CloseOpenUpvals(); fi.ExitScope(); if (i < node.Exps.Count - 1) { pcJmpToEnds[i] = fi.EmitJmp(0, 0); } else { pcJmpToEnds[i] = pcJmpToNextExp; } } foreach (var pc in pcJmpToEnds) { fi.FixsBx(pc, fi.PC() - pc); } }