Beispiel #1
0
 public override void Process(ScriptBuilder sb)
 {
     sb.EmitLabel(Name);
 }
Beispiel #2
0
        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);
            }
        }