// Make calls to the classes that does the final calculation
        public override double Evaluate()
        {
            switch (this.Operator)
            {
            case '+':
                AdditionNode add = new AdditionNode('+');
                add.Left  = this.Left;
                add.Right = this.Right;
                return(add.Evaluate());

            case '-':
                SubtractionNode sub = new SubtractionNode('-');
                sub.Left  = this.Left;
                sub.Right = this.Right;
                return(sub.Evaluate());

            case '*':
                MultiplicationNode mul = new MultiplicationNode('*');
                mul.Left  = this.Left;
                mul.Right = this.Right;
                return(mul.Evaluate());

            case '/':
                DivisionNode div = new DivisionNode('/');
                div.Left  = this.Left;
                div.Right = this.Right;
                return(div.Evaluate());

            default:
                break;
            }

            return(0.0);
        }
Пример #2
0
        public override Node VisitInfixValueExpr(ML4DParser.InfixValueExprContext context)
        {
            InfixExpressionNode node;

            switch (context.op.Type)
            {
            case ML4DLexer.PLUS:
                node = new AdditionNode("+");
                break;

            case ML4DLexer.MINUS:
                node = new SubtractionNode("-");
                break;

            case ML4DLexer.MUL:
                node = new MultiplicationNode("*");
                break;

            case ML4DLexer.DIV:
                node = new DivisionNode("/");
                break;

            case ML4DLexer.POW:
                node = new PowerNode("**");
                break;

            default:
                throw new NotSupportedException(
                          $"The operator {context.op.Text}, is not a valid arithmetic operator.");
            }
            node.Left  = (ExpressionNode)Visit(context.left);
            node.Right = (ExpressionNode)Visit(context.right);
            return(node);
        }
Пример #3
0
        private ExpressionNode ParseTerm()
        {
            var lhs = ParseUnary();

            while (true)
            {
                if (_reader.Peek() is Asterisk)
                {
                    Match <Asterisk>();
                    lhs = new MultiplicationNode(lhs, ParseUnary());
                }
                else if (_reader.Peek() is Slash)
                {
                    Match <Slash>();
                    lhs = new DivisionNode(lhs, ParseUnary());
                }
                else if (_reader.Peek() is Percent)
                {
                    Match <Percent>();
                    lhs = new ModNode(lhs, ParseUnary());
                }
                else
                {
                    break;
                }
            }

            return(lhs);
        }
        public override Expression Visit(MultiplicationNode node)
        {
            var left  = Visit(node.Left);
            var right = Visit(node.Right);

            return(new Expression(new Term().Multiply(left, right)));
        }
        private Value Multiplication(MultiplicationNode exp)
        {
            try
            {
                Constant      left      = Eval(exp.Left).GetRValue();
                Constant      right     = Eval(exp.Right).GetRValue();
                Constant.Type leftType  = left.ConstantType;
                Constant.Type rightType = right.ConstantType;
                Constant.Type bt        = Max(leftType, rightType);
                switch (bt)
                {
                case Constant.Type.Complex:
                {
                    ComplexValue l = (ComplexValue)Convert(left, bt);
                    ComplexValue r = (ComplexValue)Convert(right, bt);
                    return(ComplexValue.OpMult(l, r));
                }

                case Constant.Type.Int:
                {
                    IntValue l = (IntValue)Convert(left, bt);
                    IntValue r = (IntValue)Convert(right, bt);
                    return(IntValue.OpMult(l, r));
                }

                case Constant.Type.Float:
                {
                    FloatValue l = (FloatValue)Convert(left, bt);
                    FloatValue r = (FloatValue)Convert(right, bt);
                    return(FloatValue.OpMult(l, r));
                }
                }
                throw new ModelInterpreterException("Некорректная операция для типа \"" + bt.ToString() + "\".")
                      {
                          Line     = exp.Line,
                          Position = exp.Position
                      };
            }
            catch (TypeConversionError exc)
            {
                throw new ModelInterpreterException($"Не удалось преобразование из  \"{exc.Src}\" в \"{exc.Dst}\"")
                      {
                          Line     = exp.Line,
                          Position = exp.Position
                      };
            }
            catch (Exception exc)
            {
                throw new ModelInterpreterException(exc.Message)
                      {
                          Line     = exp.Line,
                          Position = exp.Position
                      };
            }
        }
Пример #6
0
        private object MultiplicationNode(MultiplicationNode mn)
        {
            var l = Evaluate(mn.l);
            var r = Evaluate(mn.r);

            if (l is decimal && r is decimal)
            {
                return((decimal)l * (decimal)r);
            }
            throw(new Exception($"Can't multiply {l.GetType()} and {r.GetType()}"));
        }
Пример #7
0
        public void IllegalTensorMultiplicationTest()
        {
            // tensor a[2][1] = { [2.4], [5.1] }
            // tensor b[5][2] = { [1, 1],
            //                    [1, 1],
            //                    [1, 1],
            //                    [1, 1],
            //                    [1, 1] }
            // tensor c[2][2] = a*b;

            TensorInitNode aInit = new TensorInitNode();

            aInit.FirstRowElements = new List <ExpressionNode>()
            {
                new DoubleNode(2.4)
            };
            aInit.Elements = new List <ExpressionNode>()
            {
                new DoubleNode(5.1)
            };
            TensorDCLNode a = new TensorDCLNode("tensor", "a", 2, 1, aInit);

            TensorInitNode bInit = new TensorInitNode();

            bInit.FirstRowElements = new List <ExpressionNode>()
            {
                new DoubleNode(1), new DoubleNode(1)
            };
            bInit.Elements = new List <ExpressionNode>()
            {
                new DoubleNode(1), new DoubleNode(1),
                new DoubleNode(1), new DoubleNode(1),
                new DoubleNode(1), new DoubleNode(1),
                new DoubleNode(1), new DoubleNode(1)
            };
            TensorDCLNode b = new TensorDCLNode("tensor", "b", 5, 2, bInit);

            MultiplicationNode mulNode = new MultiplicationNode("*");

            mulNode.Left  = new IDNode("a");
            mulNode.Right = new IDNode("b");

            SymbolTable symbolTable             = new SymbolTable();
            TypeCheckSymbolTableVisitor visitor = new TypeCheckSymbolTableVisitor(symbolTable);

            visitor.Visit(a);
            visitor.Visit(b);
            Assert.ThrowsException <InvalidOperandsException>(() =>
            {
                visitor.Visit(mulNode);
            });
        }
Пример #8
0
        public void Visit_MultiplicationNode_EmitsCorrectCode()
        {
            // Arrange
            MultiplicationNode multiplicationNode = new MultiplicationNode(DummySrcPos);
            IntegerLiteral     left  = new IntegerLiteral("3", DummySrcPos);
            IntegerLiteral     right = new IntegerLiteral("3", DummySrcPos);

            multiplicationNode.Left  = left;
            multiplicationNode.Right = right;

            string expectedResult = "3 * 3";

            // Act
            string actualResult = CodeGenerator.Visit(multiplicationNode);

            // Assert
            Assert.AreEqual(expectedResult, actualResult);
        }
Пример #9
0
        public void CalculateCorrectly()
        {
            var multiplicationNode = new MultiplicationNode(new NumberNode(6), new NumberNode(7));

            multiplicationNode.Calculate().Should().Be(42);
        }
Пример #10
0
        public void PrintCorrectly()
        {
            var multiplicationNode = new MultiplicationNode(new NumberNode(6), new NumberNode(7));

            multiplicationNode.Print().Should().Be("(* 6 7)");
        }
Пример #11
0
        protected SyntaxNode buildSyntaxTree(List <ISyntaxUnit> postfixForm)
        {
            Queue <ISyntaxUnit> inputQueue   = new Queue <ISyntaxUnit>(postfixForm);
            Stack <SyntaxNode>  operandStack = new Stack <SyntaxNode>();

            while (inputQueue.Count > 0)
            {
                ISyntaxUnit input = inputQueue.Dequeue();
                if (input is Lexeme)
                {
                    Lexeme            token = input as Lexeme;
                    Lexeme.LexemeType ttype = token.Type;
                    if (properties.IsVariable(token.Value))
                    {
                        VariableIdentifierNode variable = new VariableIdentifierNode(token.Value);
                        operandStack.Push(variable);
                    }
                    else if (properties.IsConstant(token.Value))
                    {
                        double constantValue            = properties.getConstantValue(token.Value);
                        ConstantIdentifierNode constant = new ConstantIdentifierNode(token.Value, constantValue);
                        operandStack.Push(constant);
                    }
                    else if (properties.IsFunctionName(token.Value))
                    {
                        int nArguments = properties.getFunctionArgumentsCount(token.Value);
                        FunctionApplyNode.FunctionBody funcBody = properties.getFunctionDefinition(token.Value);
                        ArgumentListNode argumentList           = new ArgumentListNode();
                        try
                        {
                            for (int i = 0; i < nArguments; i++)
                            {
                                argumentList.addArgument(operandStack.Pop());
                            }
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Not enough operands on operand stack for function call.");
                        }

                        FunctionApplyNode functionCall = new FunctionApplyNode(argumentList, funcBody, token.Value);
                        operandStack.Push(functionCall);
                    }
                    else if (ttype == Lexeme.LexemeType.REAL_VALUE)
                    {
                        double value;
                        if (!double.TryParse(token.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out value))
                        {
                            throw new ParseException("Couldn't parse literal value: " + token.Value);
                        }
                        LiteralNode literal = new LiteralNode(value);
                        operandStack.Push(literal);
                    }
                    else if (ttype == Lexeme.LexemeType.OP_PLUS)
                    {
                        try
                        {
                            SyntaxNode   right    = operandStack.Pop();
                            SyntaxNode   left     = operandStack.Pop();
                            AdditionNode addition = new AdditionNode(left, right);
                            operandStack.Push(addition);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand(s) for addition.");
                        }
                    }
                    else if (ttype == Lexeme.LexemeType.OP_MINUS)
                    {
                        try
                        {
                            SyntaxNode      right       = operandStack.Pop();
                            SyntaxNode      left        = operandStack.Pop();
                            SubtractionNode subtraction = new SubtractionNode(left, right);
                            operandStack.Push(subtraction);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand(s) for subtraction.");
                        }
                    }
                    else if (ttype == Lexeme.LexemeType.OP_MUL)
                    {
                        try
                        {
                            SyntaxNode         right          = operandStack.Pop();
                            SyntaxNode         left           = operandStack.Pop();
                            MultiplicationNode multiplication = new MultiplicationNode(left, right);
                            operandStack.Push(multiplication);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand(s) for multiplication.");
                        }
                    }
                    else if (ttype == Lexeme.LexemeType.OP_DIV)
                    {
                        try
                        {
                            SyntaxNode   right    = operandStack.Pop();
                            SyntaxNode   left     = operandStack.Pop();
                            DivisionNode division = new DivisionNode(left, right);
                            operandStack.Push(division);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand(s) for division.");
                        }
                    }
                    else if (ttype == Lexeme.LexemeType.OP_POW)
                    {
                        try
                        {
                            SyntaxNode exponent = operandStack.Pop();
                            SyntaxNode baseNode = operandStack.Pop();
                            PowerNode  power    = new PowerNode(baseNode, exponent);
                            operandStack.Push(power);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand(s) for exponentiation.");
                        }
                    }
                    else if (ttype == Lexeme.LexemeType.EQ_SIGN)
                    {
                        try
                        {
                            SyntaxNode right  = operandStack.Pop();
                            SyntaxNode left   = operandStack.Pop();
                            EqualsNode eqNode = new EqualsNode(left, right);
                            operandStack.Push(eqNode);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand(s) for assignment.");
                        }
                    }
                    else if (ttype == Lexeme.LexemeType.OP_PLUS_UNARY)
                    {
                        try
                        {
                            SyntaxNode    child     = operandStack.Pop();
                            UnaryPlusNode unaryPlus = new UnaryPlusNode(child);
                            operandStack.Push(unaryPlus);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand for unary plus.");
                        }
                    }
                    else if (ttype == Lexeme.LexemeType.OP_MINUS_UNARY)
                    {
                        try
                        {
                            SyntaxNode     child      = operandStack.Pop();
                            UnaryMinusNode unaryMinus = new UnaryMinusNode(child);
                            operandStack.Push(unaryMinus);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand for unary minus.");
                        }
                    }
                    else
                    {
                        throw new ParseException("Unexpected token in postfix expression: " + token.simpleRepresentation());
                    }
                }
                else if (input is SyntaxNode)
                {
                    operandStack.Push(input as SyntaxNode);
                }
                else
                {
                    throw new ParseException("Unexpected object type in postfix expression.");
                }
            }

            if (operandStack.Count == 1)
            {
                return(operandStack.Pop());
            }
            else
            {
                throw new ParseException("Too many operands in postfix expression.");
            }
        }
Пример #12
0
 public abstract T Visit(MultiplicationNode node);
Пример #13
0
        public BinaryExpressionNode ParseBinaryExpresssion(Token operatorToken, AstNode leftOperand, AstNode rightOperand)
        {
            BinaryExpressionNode expression = null;

            switch (operatorToken.Type)
            {
            case TokenType.Plus:
                expression = new AdditionNode(operatorToken.SourceLine);
                break;

            case TokenType.Minus:
                expression = new SubstractionNode(operatorToken.SourceLine);
                break;

            case TokenType.Asterisk:
                expression = new MultiplicationNode(operatorToken.SourceLine);
                break;

            case TokenType.Slash:
                expression = new DivisionNode(operatorToken.SourceLine);
                break;

            case TokenType.Equals:
                expression = new EqualsComparisonNode(operatorToken.SourceLine);
                break;

            case TokenType.NotEquals:
                expression = new NotEqualsComparisonNode(operatorToken.SourceLine);
                break;

            case TokenType.Less:
                expression = new LessComparisonNode(operatorToken.SourceLine);
                break;

            case TokenType.EqualsOrLess:
                expression = new EqualsOrLessComparisonNode(operatorToken.SourceLine);
                break;

            case TokenType.Greater:
                expression = new GreaterComparisonNode(operatorToken.SourceLine);
                break;

            case TokenType.EqualsOrGreater:
                expression = new EqualsOrGreaterComparisonNode(operatorToken.SourceLine);
                break;

            case TokenType.And:
                expression = new LogicalAndNode(operatorToken.SourceLine);
                break;

            case TokenType.Or:
                expression = new LogicalOrNode(operatorToken.SourceLine);
                break;

            default:
                throw new CompilerException($"`{MethodBase.GetCurrentMethod().Name}` called with a bad token. Expected a binary operator, token has type `{operatorToken.Type}` instead.");
            }
            expression.LeftOperand  = leftOperand;
            expression.RightOperand = rightOperand;
            return(expression);
        }
Пример #14
0
 /// <summary>
 /// 乗算ノードの評価
 /// </summary>
 /// <param name="node">乗算ノード</param>
 /// <returns>演算後の数値(Double)</returns>
 public override object Visit(MultiplicationNode node)
 {
     return((double)Visit(node.Left) * (double)Visit(node.Right));
 }
 public override int Visit(MultiplicationNode node)
 => Visit(node.Left) * Visit(node.Right);