private void CGForInStat(FuncInfo funcInfo, ForInStatNode node) { funcInfo.EnterScope(true); LocalVarDecStatNode varDecStatNode = new LocalVarDecStatNode(); varDecStatNode.ExpList = node.ExpList; varDecStatNode.NameList = new List <ConstExpNode>() { new ConstExpNode(new Token(TokenType.Identifier, "for_generator", -1)), new ConstExpNode(new Token(TokenType.Identifier, "for_state", -1)), new ConstExpNode(new Token(TokenType.Identifier, "for_control", -1)) }; foreach (var name in node.NameList.NameList) { funcInfo.AddLocalVar(name.name); } int jmpToTFCPC = funcInfo.EmitJMP(0, 0); CGBlock(funcInfo, node.DoBlock.Block); funcInfo.FixSBX(jmpToTFCPC, funcInfo.PC() - jmpToTFCPC); var geneartor = funcInfo.VarDic1["for_generator"]; funcInfo.EmitTForCall(geneartor.RegIndex, node.NameList.NameList.Count); funcInfo.EmitTForLoop(geneartor.RegIndex + 2, jmpToTFCPC - funcInfo.PC() - 1); funcInfo.ExitScope(); }
private void CGForNumStat(FuncInfo funcInfo, ForNumStatNode node) { funcInfo.EnterScope(true); LocalVarDecStatNode varDecStatNode = new LocalVarDecStatNode(); varDecStatNode.ExpList = new List <ExpNode>() { node.InitExp, node.LimitExp, node.StepExp }; if (node.StepExp == null) { varDecStatNode.ExpList[2] = new ConstExpNode(new Token(TokenType.Number, "1", -1)); } varDecStatNode.NameList = new List <ConstExpNode>() { new ConstExpNode(new Token(TokenType.Identifier, "for_index", -1)), new ConstExpNode(new Token(TokenType.Identifier, "for_limit", -1)), new ConstExpNode(new Token(TokenType.Identifier, "for_step", -1)) }; CGLocalVarDefStat(funcInfo, varDecStatNode); funcInfo.AddLocalVar(node.VarName.name); int a = funcInfo.UsedReg - 4; int forPrepPC = funcInfo.EmitForPrep(a, 0); CGBlock(funcInfo, node.DoBlock.Block); int forLoopPC = funcInfo.EmitForLoop(a, 0); funcInfo.FixSBX(forPrepPC, forLoopPC - forPrepPC - 1); funcInfo.FixSBX(forLoopPC, forPrepPC - forLoopPC - 1); funcInfo.ExitScope(); }
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); } }
private void CGDoStat(FuncInfo funcInfo, DoStatNode node) { funcInfo.EnterScope(false); CGBlock(funcInfo, node.Block); funcInfo.ExitScope(); }