Create evaluators for literals, list and identifier nodes
This commit is contained in:
@@ -1,2 +1,78 @@
|
||||
def evaluate(input, environment):
|
||||
pass
|
||||
from smnp.ast.node.program import Program
|
||||
from smnp.error.runtime import RuntimeException
|
||||
from smnp.type.model import Type
|
||||
from smnp.type.value import Value
|
||||
|
||||
|
||||
class Evaluator:
|
||||
|
||||
|
||||
@classmethod
|
||||
def evaluator(cls, node, environment):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def evaluate(cls, node, environment):
|
||||
result = cls.evaluator(node, environment)
|
||||
if result is None:
|
||||
return EvaluationResult.OK(Value(Type.VOID, None))
|
||||
return EvaluationResult.OK(result)
|
||||
|
||||
@staticmethod
|
||||
def forNodes(evaluator, *nodes):
|
||||
def nodeEvaluator(node, environment):
|
||||
if type(node) in nodes:
|
||||
return evaluator(node, environment)
|
||||
|
||||
return EvaluationResult.FAIL()
|
||||
|
||||
return nodeEvaluator
|
||||
|
||||
@staticmethod
|
||||
def oneOf(*evaluators):
|
||||
def combinedEvaluator(node, environment):
|
||||
for evaluator in evaluators:
|
||||
result = evaluator(node, environment)
|
||||
if result.result:
|
||||
return result
|
||||
|
||||
return EvaluationResult.FAIL()
|
||||
|
||||
return combinedEvaluator
|
||||
|
||||
|
||||
class EvaluationResult():
|
||||
def __init__(self, result, value):
|
||||
if result and value is None:
|
||||
raise RuntimeError("Value musn't be None if result is set to True for EvaluationResult")
|
||||
if type(value) == EvaluationResult:
|
||||
raise RuntimeError(f"Nested EvaluationResult detected. Trying to create EvaluationResult with value = {value}")
|
||||
self.result = result
|
||||
self.value = value
|
||||
|
||||
@staticmethod
|
||||
def FAIL():
|
||||
return EvaluationResult(False, None)
|
||||
|
||||
@staticmethod
|
||||
def OK(value):
|
||||
return EvaluationResult(True, value)
|
||||
|
||||
def __str__(self):
|
||||
return f"{'OK' if self.result else 'FAILED'}[{self.value}]"
|
||||
|
||||
|
||||
def evaluate(node, environment):
|
||||
from smnp.runtime.evaluators.program import ProgramEvaluator
|
||||
from smnp.runtime.evaluators.expression import evaluateExpression
|
||||
|
||||
result = Evaluator.oneOf(
|
||||
Evaluator.forNodes(ProgramEvaluator.evaluate, Program),
|
||||
evaluateExpression
|
||||
)(node, environment)
|
||||
|
||||
if not result.result:
|
||||
raise RuntimeException("Cannot evaluate program", node.pos)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
Reference in New Issue
Block a user