2
2
import mal_readline
3
3
import mal_types as types
4
4
from mal_types import (MalSym , MalInt , MalStr ,
5
- nil , true , false , _symbol , _keywordu ,
5
+ nil , true , false , _symbol , _keywordu , throw_str ,
6
6
MalList , _list , MalVector , MalHashMap , MalFunc )
7
7
import reader , printer
8
8
from env import Env
@@ -13,15 +13,12 @@ def READ(str):
13
13
return reader .read_str (str )
14
14
15
15
# eval
16
- def eval_ast (ast , env ):
16
+ def EVAL (ast , env ):
17
+ while True :
18
+ if env .get ("DEBUG-EVAL" ) not in (None , nil , false ):
19
+ print ("EVAL " + printer ._pr_str (ast ))
17
20
if types ._symbol_Q (ast ):
18
- assert isinstance (ast , MalSym )
19
- return env .get (ast )
20
- elif types ._list_Q (ast ):
21
- res = []
22
- for a in ast .values :
23
- res .append (EVAL (a , env ))
24
- return MalList (res )
21
+ return env .get (ast .value ) or throw_str ("'" + ast .value + "' not found" )
25
22
elif types ._vector_Q (ast ):
26
23
res = []
27
24
for a in ast .values :
@@ -32,15 +29,9 @@ def eval_ast(ast, env):
32
29
for k in ast .dct .keys ():
33
30
new_dct [k ] = EVAL (ast .dct [k ], env )
34
31
return MalHashMap (new_dct )
35
- else :
32
+ elif not types . _list_Q ( ast ) :
36
33
return ast # primitive value, return unchanged
37
-
38
- def EVAL (ast , env ):
39
- while True :
40
- #print("EVAL %s" % printer._pr_str(ast))
41
- if not types ._list_Q (ast ):
42
- return eval_ast (ast , env )
43
-
34
+ else :
44
35
# apply list
45
36
if len (ast ) == 0 : return ast
46
37
a0 = ast [0 ]
@@ -63,8 +54,8 @@ def EVAL(ast, env):
63
54
elif u"do" == a0sym :
64
55
if len (ast ) == 0 :
65
56
return nil
66
- elif len (ast ) > 1 :
67
- eval_ast (ast . slice2 ( 1 , len ( ast ) - 1 ) , env )
57
+ for i in range ( 1 , len (ast ) - 1 ) :
58
+ EVAL (ast [ i ] , env )
68
59
ast = ast [- 1 ] # Continue loop (TCO)
69
60
elif u"if" == a0sym :
70
61
a1 , a2 = ast [1 ], ast [2 ]
@@ -78,14 +69,16 @@ def EVAL(ast, env):
78
69
a1 , a2 = ast [1 ], ast [2 ]
79
70
return MalFunc (None , a2 , env , a1 , EVAL )
80
71
else :
81
- el = eval_ast (ast , env )
82
- f = el .values [0 ]
72
+ f = EVAL (a0 , env )
73
+ args = []
74
+ for i in range (1 , len (ast )):
75
+ args .append (EVAL (ast [i ], env ))
83
76
if isinstance (f , MalFunc ):
84
77
if f .ast :
85
78
ast = f .ast
86
- env = f .gen_env (el . rest ()) # Continue loop (TCO)
79
+ env = f .gen_env (args ) # Continue loop (TCO)
87
80
else :
88
- return f .apply (el . rest () )
81
+ return f .apply (args )
89
82
else :
90
83
raise Exception ("%s is not callable" % f )
91
84
0 commit comments