private void CGRepeatStat(FuncInfo funcInfo, RepeatStatNode node) { funcInfo.EnterScope(true); int blockPC = funcInfo.PC(); CGBlock(funcInfo, node.Block); int r = funcInfo.AllocReg(); CGExp(funcInfo, node.Exp, r, 1); funcInfo.FreeReg(); funcInfo.EmitTest(r, 0); funcInfo.EmitJMP(0, blockPC - funcInfo.PC() - 1); funcInfo.ExitScope(); }
private void CGWhileStat(FuncInfo funcInfo, WhileStatNode node) { int beforePc = funcInfo.PC(); int r = funcInfo.AllocReg(); CGExp(funcInfo, node.Exp, r, 1); funcInfo.FreeReg(); funcInfo.EmitTest(r, 0); int jumPC = funcInfo.EmitJMP(0, 0); funcInfo.EnterScope(true); CGBlock(funcInfo, node.DoStatNode.Block); funcInfo.EmitJMP(0, beforePc - funcInfo.PC()); funcInfo.ExitScope(); funcInfo.FixSBX(jumPC, funcInfo.PC() - jumPC); }
private void CGIfStat(FuncInfo funcInfo, IfStatNode node) { var jmpToEndsPC = new int[node.Exp.Count]; int jmpToNextExpPc = -1; int i = 0; foreach (var exp in node.Exp) { if (jmpToNextExpPc > 0) { funcInfo.FixSBX(jmpToNextExpPc, funcInfo.PC() - jmpToNextExpPc); } int r = funcInfo.AllocReg(); CGExp(funcInfo, exp, r, 1); funcInfo.FreeReg(); funcInfo.EmitTest(r, 0); jmpToNextExpPc = funcInfo.EmitJMP(0, 0); funcInfo.EnterScope(false); CGBlock(funcInfo, node.Block); funcInfo.ExitScope(); if (i < node.Exp.Count - 1) { jmpToEndsPC[i] = funcInfo.EmitJMP(0, 0); } else { jmpToEndsPC[i] = jmpToNextExpPc; } i++; } foreach (int j in jmpToEndsPC) { funcInfo.FixSBX(j, funcInfo.PC() - j); } }