Files
pylisp/core/evaluator/naively_evaluate.py
T

73 lines
2.5 KiB
Python

from core.tokens import (
BinaryOperator,
BinaryPredicate,
SpecialForm,
Lambda,
Pure,
Macro,
)
# debug
import sys
from core.primitives.symbol import (
isSymbol
)
from core.primitives.list import (
cons, car, cdr,
isList,
NIL
)
from core.environment import EVAL_NIL, Environment, RepresentateAST
from core.evaluator.evaluate_binary_operator import evalBinaryOperator
from core.evaluator.evaluate_binary_predicate import evalBinaryPredicate
from core.evaluator.evaluate_special_form import evalSpecialForm
from core.evaluator.evaluate_call import evalCall
from core.evaluator.evaluate_macro import evalMacro
from core.evaluator.utils.getFirstN import getFirstN
from core.exceptions import error, syntaxError, typeError
def naivelyEvaluate(value, localEnvironment, strict):
if isSymbol(value):
return localEnvironment.get(value)
elif isList(value):
if value == NIL:
return EVAL_NIL()
head = naivelyEvaluate(car(value), localEnvironment, True)
tail = cdr(value)
try:
if isinstance(head, (BinaryOperator, BinaryPredicate)):
try:
a, b = getFirstN(tail, 2)
evaledA = naivelyEvaluate(a, localEnvironment, True)
evaledB = naivelyEvaluate(b, localEnvironment, True)
if isinstance(head, BinaryOperator):
return evalBinaryOperator(head, evaledA, evaledB)
return evalBinaryPredicate(head, evaledA, evaledB)
except syntaxError as e:
raise syntaxError(f'wrong args for: {repr(value)}') from e
elif isinstance(head, SpecialForm):
return evalSpecialForm(head, tail, localEnvironment, strict)
elif isinstance(head, (Lambda, Pure)):
if isinstance(head, Lambda):
environment = Environment(head.env)
else:
environment = Environment(parent=localEnvironment)
return evalCall(head, tail, environment, localEnvironment, strict)
elif isinstance(head, Macro):
return evalMacro(head, tail, localEnvironment, strict)
except error as e:
raise syntaxError(f'wrong args for {repr(head)}: {repr(cdr(value))}') from e
raise typeError(f'wrong head form: {RepresentateAST(head)}')
return value