Create evaluator for power operator

This commit is contained in:
Bartłomiej Pluta
2019-07-12 19:54:29 +02:00
parent 35eb38076f
commit 65fccda989
4 changed files with 27 additions and 7 deletions

View File

@@ -3,16 +3,14 @@ from smnp.ast.node.model import Node
from smnp.ast.node.none import NoneNode from smnp.ast.node.none import NoneNode
from smnp.ast.node.operator import BinaryOperator, Operator, UnaryOperator from smnp.ast.node.operator import BinaryOperator, Operator, UnaryOperator
from smnp.ast.node.unit import UnitParser from smnp.ast.node.unit import UnitParser
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 NotOperator(UnaryOperator):
class Factor(Valuable):
pass pass
class NotOperator(UnaryOperator): class Power(BinaryOperator):
pass pass
@@ -66,7 +64,7 @@ def FactorParser(input):
factorOperands, factorOperands,
[TokenType.DOUBLE_ASTERISK], [TokenType.DOUBLE_ASTERISK],
factorOperands, factorOperands,
lambda left, op, right: Factor.withValue(BinaryOperator.withValues(left, op, right)), lambda left, op, right: Power.withValues(left, op, right),
name="power operator" name="power operator"
) )

View File

@@ -1,4 +1,4 @@
from smnp.ast.node.factor import NotOperator from smnp.ast.node.factor import NotOperator, Power
from smnp.ast.node.identifier import FunctionCall from smnp.ast.node.identifier import FunctionCall
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
@@ -14,11 +14,13 @@ def expressionEvaluator(doAssert=False):
from smnp.runtime.evaluators.atom import AtomEvaluator from smnp.runtime.evaluators.atom import AtomEvaluator
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
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),
Evaluator.forNodes(AccessEvaluator.evaluate, Access), Evaluator.forNodes(AccessEvaluator.evaluate, Access),
Evaluator.forNodes(NotEvaluator.evaluate, NotOperator), Evaluator.forNodes(NotEvaluator.evaluate, NotOperator),
Evaluator.forNodes(PowerEvaluator.evaluate, Power),
AtomEvaluator.evaluate AtomEvaluator.evaluate
)(node, environment) )(node, environment)

View File

@@ -11,6 +11,6 @@ class NotEvaluator(Evaluator):
value = expressionEvaluator(doAssert=True)(node.value, environment).value value = expressionEvaluator(doAssert=True)(node.value, environment).value
if value.type != Type.BOOL: if value.type != Type.BOOL:
raise RuntimeException(f"Operator '{node.operator.value}' is supported only by {Type.BOOL.name.lower()} type", node.pos) raise RuntimeException(f"Operator '{node.operator.value}' is supported only by {Type.BOOL.name.lower()} type", node.value.pos)
return Type.bool(not value.value) return Type.bool(not value.value)

View File

@@ -0,0 +1,20 @@
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 PowerEvaluator(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)
return Type.integer(int(left.value ** right.value))