Create evaluators for literals, list and identifier nodes

This commit is contained in:
Bartłomiej Pluta
2019-07-08 13:39:07 +02:00
parent fd9f240ce5
commit 6e42ac0f91
10 changed files with 166 additions and 53 deletions

View File

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