1 load "../logo/readline.lg
2 load "../logo/reader.lg
3 load "../logo/printer.lg
13 output case (obj_type :ast) [
14 [[symbol] env_get :env :ast]
15 [[list] obj_new "list map [_eval ? :env] obj_val :ast]
16 [[vector] obj_new "vector map [_eval ? :env] obj_val :ast]
17 [[hashmap] obj_new "hashmap map [_eval ? :env] obj_val :ast]
23 if (obj_type :ast) <> "list [output eval_ast :ast :env]
24 if emptyp obj_val :ast [output :ast]
25 localmake "a0 nth :ast 0
26 case list obj_type :a0 obj_val :a0 [
28 localmake "a1 nth :ast 1
29 localmake "a2 nth :ast 2
30 output env_set :env :a1 _eval :a2 :env ]
33 localmake "a1 nth :ast 1
34 localmake "letenv env_new :env [] []
36 while [:i < _count :a1] [
37 ignore env_set :letenv nth :a1 :i _eval nth :a1 (:i + 1) :letenv
40 output _eval nth :ast 2 :letenv ]
43 output last obj_val eval_ast rest :ast :env ]
46 localmake "a1 nth :ast 1
47 localmake "cond _eval :a1 :env
48 output case obj_type :cond [
49 [[nil false] ifelse (_count :ast) > 3 [
54 [else _eval nth :ast 2 :env]
58 output fn_new nth :ast 1 :env nth :ast 2 ]
61 localmake "el eval_ast :ast :env
62 localmake "f nth :el 0
65 output apply obj_val :f butfirst obj_val :el ]
67 localmake "funcenv env_new fn_env :f fn_args :f rest :el
68 output _eval fn_body :f :funcenv ]
70 (throw "error [Wrong type for apply])]
76 output pr_str :exp "true
80 output _eval _read :str :repl_env
88 localmake "running "true
90 localmake "line readline word "user> :space_char
96 catch "error [print rep :line]
97 localmake "exception error
98 if not emptyp :exception [
99 (print "Error: first butfirst :exception)
106 make "repl_env env_new [] [] []
108 ignore env_set :repl_env first ? first butfirst ?
110 ; core.mal: defined using the language itself
111 ignore re "|(def! not (fn* (a) (if a false true)))|