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);
        }
示例#2
0
 public override IEnumerable<MilocInstruction> Mult(MultInstruction s, InstructionStream<MilocInstruction> stream)
 {
     var d0 = constantValue(s, s.RegSource0);
     var d1 = constantValue(s, s.RegSource1);
     if (d0.HasValue == d1.HasValue)
     {
         yield return s;
         yield break;
     }
     if (d0.HasValue)
     {
         yield return new SllInstruction(s.RegSource1, d0.Value, s.RegDest0);
     }
     else
     {
         yield return new SllInstruction(s.RegSource0, d1.Value, s.RegDest0);
     }
 }
示例#3
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);
        }