4 import types
.MalException
16 eval_ast
= { ast
, env
->
18 case MalSymbol
: return env
.get(ast
);
19 case List
: return types
.vector_Q(ast
) ?
20 types
.vector(ast
.collect
{ EVAL(it
,env
) }) :
21 ast
.collect
{ EVAL(it
,env
) }
22 case Map
: def new_hm
= [:]
24 new_hm
[EVAL(k
, env
)] = EVAL(v
, env
)
33 //println("EVAL: ${printer.pr_str(ast,true)}")
34 if (! types
.list_Q(ast
)) return eval_ast(ast
, env
)
35 if (ast
.size() == 0) return ast
38 case { it
instanceof MalSymbol
&& it
.value
== "def!" }:
39 return env
.set(ast
[1], EVAL(ast
[2], env
))
40 case { it
instanceof MalSymbol
&& it
.value
== "let*" }:
41 def let_env
= new Env(env
)
42 for (int i
=0; i
< ast
[1].size(); i
+= 2) {
43 let_env
.set(ast
[1][i
], EVAL(ast
[1][i
+1], let_env
))
48 case { it
instanceof MalSymbol
&& it
.value
== "do" }:
49 ast
.size() > 2 ?
eval_ast(ast
[1..-2], env
) : null
52 case { it
instanceof MalSymbol
&& it
.value
== "if" }:
53 def cond
= EVAL(ast
[1], env
)
54 if (cond
== false || cond
== null) {
65 case { it
instanceof MalSymbol
&& it
.value
== "fn*" }:
66 return new MalFunc(EVAL
, ast
[2], env
, ast
[1])
68 def el
= eval_ast(ast
, env
)
69 def (f
, args
) = [el
[0], el
.size() > 1 ? el
[1..-1] : []]
70 if (f
instanceof MalFunc
) {
71 env
= new Env(f
.env
, f
.params
, args
)
83 printer
.pr_str exp
, true
89 PRINT(EVAL(READ(str
), repl_env
))
92 // core.EXT: defined using Groovy
94 repl_env
.set(new MalSymbol(k
), v
)
97 // core.mal: defined using mal itself
98 REP("(def! not (fn* (a) (if a false true)))")
102 line
= System
.console().readLine
'user> '
108 } catch(MalException ex
) {
109 println
"Error: ${printer.pr_str(ex.obj, true)}"
110 } catch(StackOverflowError ex
) {
111 println
"Error: ${ex}"