// 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); }
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); }
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 }; } }
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()}")); }
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); }); }
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); }
public void CalculateCorrectly() { var multiplicationNode = new MultiplicationNode(new NumberNode(6), new NumberNode(7)); multiplicationNode.Calculate().Should().Be(42); }
public void PrintCorrectly() { var multiplicationNode = new MultiplicationNode(new NumberNode(6), new NumberNode(7)); multiplicationNode.Print().Should().Be("(* 6 7)"); }
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."); } }
public abstract T Visit(MultiplicationNode node);
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); }
/// <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);