diff --git a/smnp/ast/node/factor.py b/smnp/ast/node/factor.py index 72dbb74..afc78e4 100644 --- a/smnp/ast/node/factor.py +++ b/smnp/ast/node/factor.py @@ -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" ) diff --git a/smnp/runtime/evaluators/expression.py b/smnp/runtime/evaluators/expression.py index 8add597..d31429f 100644 --- a/smnp/runtime/evaluators/expression.py +++ b/smnp/runtime/evaluators/expression.py @@ -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) diff --git a/smnp/runtime/evaluators/negation.py b/smnp/runtime/evaluators/negation.py index 4bb4c2e..86206ab 100644 --- a/smnp/runtime/evaluators/negation.py +++ b/smnp/runtime/evaluators/negation.py @@ -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) \ No newline at end of file diff --git a/smnp/runtime/evaluators/power.py b/smnp/runtime/evaluators/power.py new file mode 100644 index 0000000..7168d48 --- /dev/null +++ b/smnp/runtime/evaluators/power.py @@ -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)) \ No newline at end of file