98 lines
3.3 KiB
Python
98 lines
3.3 KiB
Python
from smnp.ast.node.block import Block
|
|
from smnp.ast.node.condition import IfElse
|
|
from smnp.ast.node.function import FunctionDefinition
|
|
from smnp.ast.node.imports import Import
|
|
from smnp.ast.node.program import Program
|
|
from smnp.ast.node.ret import Return
|
|
from smnp.error.runtime import RuntimeException
|
|
from smnp.type.model import Type
|
|
|
|
|
|
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(Type.void())
|
|
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 expressionEvaluator
|
|
from smnp.runtime.evaluators.condition import IfElseStatementEvaluator
|
|
from smnp.runtime.evaluators.block import BlockEvaluator
|
|
from smnp.runtime.evaluators.imports import ImportEvaluator
|
|
from smnp.runtime.evaluators.function import FunctionDefinitionEvaluator
|
|
from smnp.runtime.evaluators.function import ReturnEvaluator
|
|
result = Evaluator.oneOf(
|
|
Evaluator.forNodes(ProgramEvaluator.evaluate, Program),
|
|
Evaluator.forNodes(IfElseStatementEvaluator.evaluate, IfElse),
|
|
Evaluator.forNodes(BlockEvaluator.evaluate, Block),
|
|
Evaluator.forNodes(ImportEvaluator.evaluate, Import),
|
|
Evaluator.forNodes(FunctionDefinitionEvaluator.evaluate, FunctionDefinition),
|
|
Evaluator.forNodes(ReturnEvaluator.evaluate, Return),
|
|
#Evaluator.forNodes(ImportEvaluator.evaluate, ImportNode),
|
|
#Evaluator.forNodes(FunctionDefinitionEvaluator.evaluate, FunctionDefinitionNode),
|
|
#Evaluator.forNodes(ExtendEvaluator.evaluate, ExtendNode),
|
|
#Evaluator.forNodes(BlockEvaluator.evaluate, BlockNode),
|
|
#Evaluator.forNodes(ReturnEvaluator.evaluate, ReturnNode),
|
|
expressionEvaluator()
|
|
)(node, environment)
|
|
|
|
if not result.result:
|
|
raise RuntimeException("Cannot evaluate program", node.pos)
|
|
|
|
return result
|
|
|