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.operator import BinaryOperator, Operator, UnaryOperator
from smnp.ast.node.unit import UnitParser
from smnp.ast.node.valuable import Valuable
from smnp.ast.parser import Parser
from smnp.token.type import TokenType
class Factor(Valuable):
class NotOperator(UnaryOperator):
pass
class NotOperator(UnaryOperator):
class Power(BinaryOperator):
pass
@@ -66,7 +64,7 @@ def FactorParser(input):
factorOperands,
[TokenType.DOUBLE_ASTERISK],
factorOperands,
lambda left, op, right: Factor.withValue(BinaryOperator.withValues(left, op, right)),
lambda left, op, right: Power.withValues(left, op, right),
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.unit import MinusOperator, Access
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.access import AccessEvaluator
from smnp.runtime.evaluators.negation import NotEvaluator
from smnp.runtime.evaluators.power import PowerEvaluator
result = Evaluator.oneOf(
Evaluator.forNodes(FunctionCallEvaluator.evaluate, FunctionCall),
Evaluator.forNodes(MinusEvaluator.evaluate, MinusOperator),
Evaluator.forNodes(AccessEvaluator.evaluate, Access),
Evaluator.forNodes(NotEvaluator.evaluate, NotOperator),
Evaluator.forNodes(PowerEvaluator.evaluate, Power),
AtomEvaluator.evaluate
)(node, environment)

View File

@@ -11,6 +11,6 @@ class NotEvaluator(Evaluator):
value = expressionEvaluator(doAssert=True)(node.value, environment).value
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)

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