Create evaluator for product (both multiplying and dividing)

This commit is contained in:
Bartłomiej Pluta
2019-07-12 20:45:23 +02:00
parent 13a6dedba6
commit 1094c071fb
3 changed files with 37 additions and 4 deletions

View File

@@ -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)

View File

@@ -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)

View File

@@ -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")