From 1094c071fb3ac519af58dd61d17b77f016e951b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Pluta?= Date: Fri, 12 Jul 2019 20:45:23 +0200 Subject: [PATCH] Create evaluator for product (both multiplying and dividing) --- smnp/ast/node/term.py | 5 ++--- smnp/runtime/evaluators/expression.py | 5 ++++- smnp/runtime/evaluators/product.py | 31 +++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 smnp/runtime/evaluators/product.py diff --git a/smnp/ast/node/term.py b/smnp/ast/node/term.py index 50bd5ae..e0012cf 100644 --- a/smnp/ast/node/term.py +++ b/smnp/ast/node/term.py @@ -1,11 +1,10 @@ from smnp.ast.node.factor import FactorParser from smnp.ast.node.operator import BinaryOperator -from smnp.ast.node.valuable import Valuable from smnp.ast.parser import Parser from smnp.token.type import TokenType -class Term(Valuable): +class Product(BinaryOperator): pass @@ -14,5 +13,5 @@ def TermParser(input): FactorParser, [TokenType.ASTERISK, TokenType.SLASH], FactorParser, - lambda left, op, right: Term.withValue(BinaryOperator.withValues(left, op, right)) + lambda left, op, right: Product.withValues(left, op, right) )(input) \ No newline at end of file diff --git a/smnp/runtime/evaluators/expression.py b/smnp/runtime/evaluators/expression.py index 0f641e5..88abfd0 100644 --- a/smnp/runtime/evaluators/expression.py +++ b/smnp/runtime/evaluators/expression.py @@ -1,5 +1,6 @@ from smnp.ast.node.factor import NotOperator, Power, Loop from smnp.ast.node.identifier import FunctionCall, Assignment +from smnp.ast.node.term import Product from smnp.ast.node.unit import MinusOperator, Access from smnp.error.runtime import RuntimeException from smnp.runtime.evaluator import Evaluator @@ -14,9 +15,10 @@ def expressionEvaluator(doAssert=False): from smnp.runtime.evaluators.access import AccessEvaluator from smnp.runtime.evaluators.negation import NotEvaluator from smnp.runtime.evaluators.power import PowerEvaluator - from smnp.runtime.evaluators.loop import LoopEvaluator from smnp.runtime.evaluators.assignment import AssignmentEvaluator + from smnp.runtime.evaluators.product import ProductEvaluator + result = Evaluator.oneOf( Evaluator.forNodes(FunctionCallEvaluator.evaluate, FunctionCall), Evaluator.forNodes(MinusEvaluator.evaluate, MinusOperator), @@ -25,6 +27,7 @@ def expressionEvaluator(doAssert=False): Evaluator.forNodes(PowerEvaluator.evaluate, Power), Evaluator.forNodes(LoopEvaluator.evaluate, Loop), Evaluator.forNodes(AssignmentEvaluator.evaluate, Assignment), + Evaluator.forNodes(ProductEvaluator.evaluate, Product), AtomEvaluator.evaluate )(node, environment) diff --git a/smnp/runtime/evaluators/product.py b/smnp/runtime/evaluators/product.py new file mode 100644 index 0000000..ecf513f --- /dev/null +++ b/smnp/runtime/evaluators/product.py @@ -0,0 +1,31 @@ +from smnp.error.runtime import RuntimeException +from smnp.runtime.evaluator import Evaluator +from smnp.runtime.evaluators.expression import expressionEvaluator +from smnp.type.model import Type + + +class ProductEvaluator(Evaluator): + + @classmethod + def evaluator(cls, node, environment): + left = expressionEvaluator(doAssert=True)(node.left, environment).value + right = expressionEvaluator(doAssert=True)(node.right, environment).value + + if left.type != Type.INTEGER: + raise RuntimeException( + f"Operator '{node.operator.value}' is supported only by {Type.INTEGER.name.lower()} type", node.left.pos) + + if right.type != Type.INTEGER: + raise RuntimeException( + f"Operator '{node.operator.value}' is supported only by {Type.INTEGER.name.lower()} type", node.right.pos) + + if node.operator.value == "*": + return Type.integer(int(left.value * right.value)) + + if node.operator.value == "/": + if right.value == 0: + raise RuntimeException("Attempt to divide by 0", node.right.pos) + return Type.integer(int(left.value / right.value)) + + raise RuntimeError("This line should never be reached") +