private void CompileRepeat(GMLToken _tok) { VMLabel vMLabel = new VMLabel("End", VMB); VMLabel vMLabel2 = new VMLabel("Repeat", VMB); CompileExpression(_tok.Children[0]); eVM_Type eVM_Type = TypeStack.Pop(); if (eVM_Type != eVM_Type.eVMT_Int) { Emit(eVM_Instruction.eVMI_CONV, eVM_Type, eVM_Type.eVMT_Int); } Emit(eVM_Instruction.eVMI_DUP, eVM_Type.eVMT_Int); EmitI(eVM_Instruction.eVMI_PUSH, 0); Emit(eVM_Instruction.eVMI_SET_LE, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int); Emit(eVM_Instruction.eVMI_BTRUE, vMLabel); LoopEnv.Push(vMLabel2); LoopEndEnv.Push(vMLabel); vMLabel2.Mark(VMB.Buffer.Position); CompileStatement(_tok.Children[1]); EmitI(eVM_Instruction.eVMI_PUSH, 1); Emit(eVM_Instruction.eVMI_SUB, eVM_Type.eVMT_Int, eVM_Type.eVMT_Int); Emit(eVM_Instruction.eVMI_DUP, eVM_Type.eVMT_Int); Emit(eVM_Instruction.eVMI_CONV, eVM_Type.eVMT_Int, eVM_Type.eVMT_Bool); Emit(eVM_Instruction.eVMI_BTRUE, vMLabel2); vMLabel.Mark(VMB.Buffer.Position); Emit(eVM_Instruction.eVMI_POPNULL, eVM_Type.eVMT_Int); LoopEnv.Pop(); LoopEndEnv.Pop(); }
private void Emit(eVM_Instruction _inst, VMLabel _label) { if (!_label.Marked) { _label.Patches.Add((int)VMB.Buffer.Position); VMB.Add(VMBuffer.EncodeInstructionBranch((int)_inst, 0)); } else { long num = _label.Address - VMB.Buffer.Position; VMB.Add(VMBuffer.EncodeInstructionBranch((int)_inst, (int)num)); } }