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.factor import FactorParser
from smnp.ast.node.operator import BinaryOperator from smnp.ast.node.operator import BinaryOperator
from smnp.ast.node.valuable import Valuable
from smnp.ast.parser import Parser from smnp.ast.parser import Parser
from smnp.token.type import TokenType from smnp.token.type import TokenType
class Term(Valuable): class Product(BinaryOperator):
pass pass
@@ -14,5 +13,5 @@ def TermParser(input):
FactorParser, FactorParser,
[TokenType.ASTERISK, TokenType.SLASH], [TokenType.ASTERISK, TokenType.SLASH],
FactorParser, FactorParser,
lambda left, op, right: Term.withValue(BinaryOperator.withValues(left, op, right)) lambda left, op, right: Product.withValues(left, op, right)
)(input) )(input)

View File

@@ -1,5 +1,6 @@
from smnp.ast.node.factor import NotOperator, Power, Loop from smnp.ast.node.factor import NotOperator, Power, Loop
from smnp.ast.node.identifier import FunctionCall, Assignment 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.ast.node.unit import MinusOperator, Access
from smnp.error.runtime import RuntimeException from smnp.error.runtime import RuntimeException
from smnp.runtime.evaluator import Evaluator 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.access import AccessEvaluator
from smnp.runtime.evaluators.negation import NotEvaluator from smnp.runtime.evaluators.negation import NotEvaluator
from smnp.runtime.evaluators.power import PowerEvaluator from smnp.runtime.evaluators.power import PowerEvaluator
from smnp.runtime.evaluators.loop import LoopEvaluator from smnp.runtime.evaluators.loop import LoopEvaluator
from smnp.runtime.evaluators.assignment import AssignmentEvaluator from smnp.runtime.evaluators.assignment import AssignmentEvaluator
from smnp.runtime.evaluators.product import ProductEvaluator
result = Evaluator.oneOf( result = Evaluator.oneOf(
Evaluator.forNodes(FunctionCallEvaluator.evaluate, FunctionCall), Evaluator.forNodes(FunctionCallEvaluator.evaluate, FunctionCall),
Evaluator.forNodes(MinusEvaluator.evaluate, MinusOperator), Evaluator.forNodes(MinusEvaluator.evaluate, MinusOperator),
@@ -25,6 +27,7 @@ def expressionEvaluator(doAssert=False):
Evaluator.forNodes(PowerEvaluator.evaluate, Power), Evaluator.forNodes(PowerEvaluator.evaluate, Power),
Evaluator.forNodes(LoopEvaluator.evaluate, Loop), Evaluator.forNodes(LoopEvaluator.evaluate, Loop),
Evaluator.forNodes(AssignmentEvaluator.evaluate, Assignment), Evaluator.forNodes(AssignmentEvaluator.evaluate, Assignment),
Evaluator.forNodes(ProductEvaluator.evaluate, Product),
AtomEvaluator.evaluate AtomEvaluator.evaluate
)(node, environment) )(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")