64 lines
2.9 KiB
Python
64 lines
2.9 KiB
Python
from smnp.ast.node.condition import IfElse
|
|
from smnp.ast.node.expression import Sum, Relation, And, Or, Loop
|
|
from smnp.ast.node.factor import NotOperator, Power
|
|
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
|
|
from smnp.type.model import Type
|
|
|
|
|
|
def expressionEvaluator(doAssert=False):
|
|
def evaluateExpression(node, environment):
|
|
from smnp.runtime.evaluators.function import FunctionCallEvaluator
|
|
from smnp.runtime.evaluators.minus import MinusEvaluator
|
|
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
|
|
from smnp.runtime.evaluators.loop import LoopEvaluator
|
|
from smnp.runtime.evaluators.assignment import AssignmentEvaluator
|
|
from smnp.runtime.evaluators.product import ProductEvaluator
|
|
|
|
from smnp.runtime.evaluators.sum import SumEvaluator
|
|
from smnp.runtime.evaluators.relation import RelationEvaluator
|
|
from smnp.runtime.evaluators.condition import IfElseEvaluator
|
|
from smnp.runtime.evaluators.logic import AndEvaluator
|
|
from smnp.runtime.evaluators.logic import OrEvaluator
|
|
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),
|
|
Evaluator.forNodes(LoopEvaluator.evaluate, Loop),
|
|
Evaluator.forNodes(AssignmentEvaluator.evaluate, Assignment),
|
|
Evaluator.forNodes(ProductEvaluator.evaluate, Product),
|
|
Evaluator.forNodes(SumEvaluator.evaluate, Sum),
|
|
Evaluator.forNodes(RelationEvaluator.evaluate, Relation),
|
|
Evaluator.forNodes(IfElseEvaluator.evaluate, IfElse),
|
|
Evaluator.forNodes(AndEvaluator.evaluate, And),
|
|
Evaluator.forNodes(OrEvaluator.evaluate, Or),
|
|
AtomEvaluator.evaluate
|
|
)(node, environment)
|
|
|
|
if doAssert and result.result and result.value.type == Type.VOID:
|
|
raise RuntimeException(f"Expected expression", node.pos)
|
|
|
|
return result
|
|
|
|
|
|
return evaluateExpression
|
|
|
|
|
|
def expressionEvaluatorWithMatcher(matcher, exceptionProvider, doAssert=True):
|
|
def evaluate(node, environment):
|
|
value = expressionEvaluator(doAssert=doAssert)(node, environment).value
|
|
|
|
if not matcher.match(value):
|
|
raise exceptionProvider(value)
|
|
|
|
return value
|
|
|
|
return evaluate |