Esempio n. 1
0
 public override IEnumerable<MilocInstruction> Div(DivInstruction s, InstructionStream<MilocInstruction> stream)
 {
     var d = constantValue(s, s.RegSource1);
     if (d.HasValue)
     {
         yield return new SraInstruction(s.RegSource0, d.Value, s.RegDest0);
     }
     else
     {
         yield return s;
     }
 }
        private Operand MakeVariableAssignment(VariableAssignmentNode node, ILGenerator generator)
        {
            SymbolOperand leftHandSide  = node.Accessor.Visit(generator) as SymbolOperand;
            Operand       rightHandSide = node.Right.Visit(generator);

            // If right-hand side exists and has a type, do some type checking

            /*if (rightHandSide.Type != leftHandSide.Type)
             *  throw new AstWalkerException($"Cannot convert {rightHandSide.Type} to {leftHandSide.Type} ('{leftHandSide.Name}')");*/

            if (node.Operator.Type == TokenType.Assignment)
            {
                generator.Emmit(new StoreInstruction(leftHandSide, rightHandSide));
                return(leftHandSide);
            }


            Instruction instr = null;

            switch (node.Operator.Type)
            {
            case TokenType.IncrementAndAssign:
                instr = new AddInstruction(leftHandSide, leftHandSide, rightHandSide);
                break;

            case TokenType.DecrementAndAssign:
                instr = new SubInstruction(leftHandSide, leftHandSide, rightHandSide);
                break;

            case TokenType.MultAndAssign:
                instr = new MultInstruction(leftHandSide, leftHandSide, rightHandSide);
                break;

            case TokenType.DivideAndAssign:
                instr = new DivInstruction(leftHandSide, leftHandSide, rightHandSide);
                break;

            default:
                throw new InvalidInstructionException($"Unsupported operation: {node.Operator.Value} ({node.Operator.Type})");
            }

            generator.Emmit(instr);

            return(leftHandSide);
        }
 public void EmitDiv(Type type)
 {
     Emit(DivInstruction.Create(type));
 }
Esempio n. 4
0
        public Operand Visit(ILGenerator generator, BinaryNode binary)
        {
            Operand left  = binary.Left.Visit(generator);
            Operand right = binary.Right.Visit(generator);

            SymbolOperand tmpname = generator.SymbolTable.NewTempSymbol(OperandType.Auto);

            Instruction instr = null;

            switch (binary.Operator.Type)
            {
            case TokenType.Addition:
                instr = new AddInstruction(tmpname, left, right);
                break;

            case TokenType.Minus:
                instr = new SubInstruction(tmpname, left, right);
                break;

            case TokenType.Multiplication:
                instr = new MultInstruction(tmpname, left, right);
                break;

            case TokenType.Division:
                instr = new DivInstruction(tmpname, left, right);
                break;


            case TokenType.Or:
                instr = new OrInstruction(tmpname, left, right);
                break;

            case TokenType.And:
                instr = new AndInstruction(tmpname, left, right);
                break;


            case TokenType.GreatThan:
                instr = new CgtInstruction(tmpname, left, right);
                break;

            case TokenType.GreatThanEqual:
                instr = new CgteInstruction(tmpname, left, right);
                break;

            case TokenType.LessThan:
                instr = new CltInstruction(tmpname, left, right);
                break;

            case TokenType.LessThanEqual:
                instr = new ClteInstruction(tmpname, left, right);
                break;


            case TokenType.Equal:
            case TokenType.NotEqual:     // Use NOT instruction
                instr = new CeqInstruction(tmpname, left, right);
                break;
            }

            generator.Emmit(new VarInstruction(tmpname, null));
            generator.Emmit(instr);

            if (binary.Operator.Type == TokenType.NotEqual)
            {
                SymbolOperand notname = generator.SymbolTable.NewTempSymbol(OperandType.Auto);
                generator.Emmit(new VarInstruction(notname, null));
                generator.Emmit(new NotInstruction(notname, tmpname));
                return(notname);
            }

            return(tmpname);
        }
Esempio n. 5
0
        private bool GenerateNode(out OneOperandNode node)
        {
            node = null;

            InstructionToken instructionToken;

            if (this.ExpectInstructionToken(out instructionToken))
            {
                Instructions instruction = instructionToken.Instruction;
                switch (instruction)
                {
                case Instructions.Mov:
                {
                    Token operand1;
                    Token operand2;
                    if (this.ExpectTwoOperands(out operand1, out operand2))
                    {
                        node = new MovInstruction(this.rawInput, instructionToken, operand1, operand2);
                    }
                    else
                    {
                        this.LogExpectedTwoOperandsError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Add:
                {
                    Token operand1;
                    Token operand2;
                    if (this.ExpectTwoOperands(out operand1, out operand2))
                    {
                        node = new AddInstruction(this.rawInput, instructionToken, operand1, operand2);
                    }
                    else
                    {
                        this.LogExpectedTwoOperandsError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Sub:
                {
                    Token operand1;
                    Token operand2;
                    if (this.ExpectTwoOperands(out operand1, out operand2))
                    {
                        node = new SubInstruction(this.rawInput, instructionToken, operand1, operand2);
                    }
                    else
                    {
                        this.LogExpectedTwoOperandsError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Mul:
                {
                    Token operand1;
                    Token operand2;
                    if (this.ExpectTwoOperands(out operand1, out operand2))
                    {
                        node = new MulInstruction(this.rawInput, instructionToken, operand1, operand2);
                    }
                    else
                    {
                        this.LogExpectedTwoOperandsError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Div:
                {
                    Token operand1;
                    Token operand2;
                    if (this.ExpectTwoOperands(out operand1, out operand2))
                    {
                        node = new DivInstruction(this.rawInput, instructionToken, operand1, operand2);
                    }
                    else
                    {
                        this.LogExpectedTwoOperandsError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Cmp:
                {
                    Token operand1;
                    Token operand2;
                    if (this.ExpectTwoOperands(out operand1, out operand2))
                    {
                        node = new CmpInstruction(this.rawInput, instructionToken, operand1, operand2);
                    }
                    else
                    {
                        this.LogExpectedTwoOperandsError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Inc:
                {
                    Token operand;
                    if (this.ExpectOneOperand(out operand))
                    {
                        node = new IncInstruction(this.rawInput, instructionToken, operand);
                    }
                    else
                    {
                        this.LogExpectedOneOperandError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Dec:
                {
                    Token operand;
                    if (this.ExpectOneOperand(out operand))
                    {
                        node = new DecInstruction(this.rawInput, instructionToken, operand);
                    }
                    else
                    {
                        this.LogExpectedOneOperandError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Jmp:
                {
                    Token operand;
                    if (this.ExpectOneOperand(out operand))
                    {
                        node = new JmpInstruction(this.rawInput, instructionToken, operand);
                    }
                    else
                    {
                        this.LogExpectedOneOperandError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Jeq:
                {
                    Token operand;
                    if (this.ExpectOneOperand(out operand))
                    {
                        node = new JeqInstruction(this.rawInput, instructionToken, operand);
                    }
                    else
                    {
                        this.LogExpectedOneOperandError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Jne:
                {
                    Token operand;
                    if (this.ExpectOneOperand(out operand))
                    {
                        node = new JneInstruction(this.rawInput, instructionToken, operand);
                    }
                    else
                    {
                        this.LogExpectedOneOperandError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Jsm:
                {
                    Token operand;
                    if (this.ExpectOneOperand(out operand))
                    {
                        node = new JsmInstruction(this.rawInput, instructionToken, operand);
                    }
                    else
                    {
                        this.LogExpectedOneOperandError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Jns:
                {
                    Token operand;
                    if (this.ExpectOneOperand(out operand))
                    {
                        node = new JnsInstruction(this.rawInput, instructionToken, operand);
                    }
                    else
                    {
                        this.LogExpectedOneOperandError(instructionToken);
                        return(false);
                    }
                }
                break;
                }
            }

            return(true);
        }