Initial commit - fix problems & refactor code
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
from core.primitives.list import cons, car, cdr, NIL
|
||||
from core.primitives.symbol import symbolName, symbolKey
|
||||
|
||||
from core.tokens import Macro
|
||||
from core.exceptions import syntaxError
|
||||
|
||||
from core.tail_recursion import tailRecursion
|
||||
from core.macro_expand import macroExpand
|
||||
|
||||
# from core.evaluator.naively_evaluate import naivelyEvaluate
|
||||
from core.evaluator.utils.getFirstN import getFirstN
|
||||
|
||||
from core.environment import TCO
|
||||
|
||||
def evalMacro(head, tail, environment, strict):
|
||||
from core.evaluator.naively_evaluate import naivelyEvaluate
|
||||
d = dict()
|
||||
args = head.args
|
||||
|
||||
if args == NIL and tail != NIL:
|
||||
raise syntaxError(f'more than zero args for {repr(head)}')
|
||||
|
||||
while args != NIL:
|
||||
firstArg = car(args)
|
||||
if symbolName(firstArg) == '.':
|
||||
firstArg = getFirstN(args, 2)[1]
|
||||
arg = tail
|
||||
args = NIL
|
||||
tail = NIL
|
||||
else:
|
||||
if tail == NIL:
|
||||
break
|
||||
arg = car(tail)
|
||||
args = cdr(args)
|
||||
tail = cdr(tail)
|
||||
d[symbolKey(firstArg)] = arg
|
||||
|
||||
if tail != NIL:
|
||||
raise syntaxError(f'extra args {repr(tail)}\nfor not variable macro {repr(head)}')
|
||||
expanded = macroExpand(head.body, d)
|
||||
|
||||
if args != NIL:
|
||||
return Macro(args, expanded)
|
||||
|
||||
if not TCO:
|
||||
return naivelyEvaluate(expanded, environment, True)
|
||||
|
||||
ret = tailRecursion(naivelyEvaluate, expanded, environment, False)
|
||||
return tailRecursion.eval(ret) if strict else ret
|
||||
Reference in New Issue
Block a user