12 Val
eval_ast(Val ast
, Env env
)
19 return List(map(ast.data
, lambda(Val e
) { return EVAL(e
, env
); }));
21 return Vector(map(ast.data
, lambda(Val e
) { return EVAL(e
, env
); }));
23 array(Val
) elements
= ({ });
24 foreach(ast.data
; Val k
; Val v
)
26 elements
+= ({ k
, EVAL(v
, env
) });
34 Val
EVAL(Val ast
, Env env
)
38 if(ast.mal_type
!= MALTYPE_LIST
) return eval_ast(ast
, env
);
39 if(ast.
emptyp()) return ast
;
40 if(ast.data
[0].mal_type
== MALTYPE_SYMBOL
) {
41 switch(ast.data
[0].value
)
44 return env.
set(ast.data
[1], EVAL(ast.data
[2], env
));
46 Env let_env
= Env(env
);
47 Val ast1
= ast.data
[1];
48 for(int i
= 0; i
< sizeof(ast1.data
); i
+= 2)
50 let_env.
set(ast1.data
[i
], EVAL(ast1.data
[i
+ 1], let_env
));
57 foreach(ast.data
[1..
(sizeof(ast.data
) - 2)], Val element
)
59 result
= EVAL(element
, env
);
64 Val cond
= EVAL(ast.data
[1], env
);
65 if(cond.mal_type
== MALTYPE_FALSE || cond.mal_type
== MALTYPE_NIL
)
67 if(sizeof(ast.data
) > 3)
76 return Fn(ast.data
[2], ast.data
[1], env
,
77 lambda(Val ... a
) { return EVAL(ast.data
[2], Env(env
, ast.data
[1], List(a
))); });
80 Val evaled_ast
= eval_ast(ast
, env
);
81 Val f
= evaled_ast.data
[0];
84 case MALTYPE_BUILTINFN
:
85 return f(@evaled_ast.data
[1..
]);
88 env
= Env(f.env
, f.params
, List(evaled_ast.data
[1..
]));
91 throw("Unknown function type");
98 return pr_str(exp, true
);
101 string rep(string str
, Env env
)
103 return PRINT(EVAL(READ(str
), env
));
106 int main(int argc
, array argv
)
108 Env repl_env
= Env(0);
109 foreach(.Core.
NS(); Val k
; Val v
) repl_env.
set(k
, v
);
110 repl_env.
set(Symbol("eval"), BuiltinFn("eval", lambda(Val a
) { return EVAL(a
, repl_env
); }));
111 repl_env.
set(Symbol("*ARGV*"), List(map(argv
[2..
], String
)));
112 rep("(def! not (fn* (a) (if a false true)))", repl_env
);
113 rep("(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \"\nnil)\")))))", repl_env
);
116 rep("(load-file \"" + argv
[1] + "\")", repl_env
);
121 string line
= readline("user> ");
123 if(strlen(line
) == 0) continue;
124 if(mixed err
= catch { write(({ rep(line
, repl_env
), "\n" })); } )
126 if(arrayp(err
)) err
= err
[0];
127 write(({ "Error: ", err
, "\n" }));