public override void Process(ScriptBuilder sb) { sb.EmitLabel(Name); }
public void TranslateInstruction(Instruction i) { switch (i.op) { case Instruction.Opcode.Label: { _output.EmitLabel(i.target); break; } case Instruction.Opcode.Push: { var reg = FetchRegister(i.target); _output.EmitPush(reg); break; } case Instruction.Opcode.Pop: { var reg = FetchRegister(i.target); _output.Emit(VM.Opcode.POP, new byte[] { reg }); break; } case Instruction.Opcode.Assign: { if (i.literal != null) { switch (i.literal.kind) { case LiteralKind.String: { var reg = FetchRegister(i.target); _output.EmitLoad(reg, (string)i.literal.value); break; } case LiteralKind.Boolean: { var reg = FetchRegister(i.target); _output.EmitLoad(reg, (bool)i.literal.value); break; } case LiteralKind.Integer: { var reg = FetchRegister(i.target); BigInteger val; if (i.literal.value is BigInteger) { val = (BigInteger)i.literal.value; } else if (i.literal.value is int) { val = new BigInteger((int)i.literal.value); } else { throw new Exception($"Could not convert {i.literal.value.GetType().Name} to BigInteger"); } _output.EmitLoad(reg, val); break; } default: throw new Exception("Unsuported " + i.literal.kind); } } else { var src = i.varName != null?FetchRegister(i.varName) : FetchRegister(i.a.target); var dst = FetchRegister(i.target); _output.EmitMove(src, dst); } break; } case Instruction.Opcode.Add: { InsertOp(i, VM.Opcode.ADD); break; } case Instruction.Opcode.Sub: { InsertOp(i, VM.Opcode.SUB); break; } case Instruction.Opcode.Mul: { InsertOp(i, VM.Opcode.MUL); break; } case Instruction.Opcode.Div: { InsertOp(i, VM.Opcode.DIV); break; } case Instruction.Opcode.Mod: { InsertOp(i, VM.Opcode.MOD); break; } case Instruction.Opcode.Shr: { InsertOp(i, VM.Opcode.SHR); break; } case Instruction.Opcode.Shl: { InsertOp(i, VM.Opcode.SHL); break; } case Instruction.Opcode.Equals: { InsertOp(i, VM.Opcode.EQUAL); break; } case Instruction.Opcode.LessThan: { InsertOp(i, VM.Opcode.LT); break; } case Instruction.Opcode.GreaterThan: { InsertOp(i, VM.Opcode.GT); break; } case Instruction.Opcode.LessOrEqualThan: { InsertOp(i, VM.Opcode.LTE); break; } case Instruction.Opcode.GreaterOrEqualThan: { InsertOp(i, VM.Opcode.GTE); break; } case Instruction.Opcode.Jump: InsertJump(i, VM.Opcode.JMP); break; case Instruction.Opcode.JumpIfFalse: InsertJump(i, VM.Opcode.JMPNOT); break; case Instruction.Opcode.JumpIfTrue: InsertJump(i, VM.Opcode.JMPIF); break; case Instruction.Opcode.Call: _output.EmitCall(i.target, 8); // TODO remove hardcoded register count break; case Instruction.Opcode.Return: _output.Emit(VM.Opcode.RET); break; case Instruction.Opcode.Negate: { var src = FetchRegister(i.a.target); var dst = FetchRegister(i.target); _output.Emit(VM.Opcode.NEGATE, new byte[] { src, dst }); break; } case Instruction.Opcode.Not: { var src = FetchRegister(i.a.target); var dst = FetchRegister(i.target); _output.Emit(VM.Opcode.NOT, new byte[] { src, dst }); break; } default: throw new Exception("Unsupported Opcode: " + i.op); } }