Common Lisp: Add documentation
[jackhill/mal.git] / logo / step3_env.lg
1 load "../logo/readline.lg
2 load "../logo/reader.lg
3 load "../logo/printer.lg
4 load "../logo/types.lg
5 load "../logo/env.lg
6
7 to _read :str
8 output read_str :str
9 end
10
11 to eval_ast :ast :env
12 output case (obj_type :ast) [
13 [[symbol] env_get :env :ast]
14 [[list] obj_new "list map [_eval ? :env] obj_val :ast]
15 [[vector] obj_new "vector map [_eval ? :env] obj_val :ast]
16 [[hashmap] obj_new "hashmap map [_eval ? :env] obj_val :ast]
17 [else :ast]
18 ]
19 end
20
21 to _eval :ast :env
22 if (obj_type :ast) <> "list [output eval_ast :ast :env]
23 if emptyp obj_val :ast [output :ast]
24 localmake "a0 nth :ast 0
25 case list obj_type :a0 obj_val :a0 [
26 [[[symbol def!]]
27 localmake "a1 nth :ast 1
28 localmake "a2 nth :ast 2
29 output env_set :env :a1 _eval :a2 :env ]
30
31 [[[symbol let*]]
32 localmake "a1 nth :ast 1
33 localmake "letenv env_new :env [] []
34 localmake "i 0
35 while [:i < _count :a1] [
36 ignore env_set :letenv nth :a1 :i _eval nth :a1 (:i + 1) :letenv
37 make "i (:i + 2)
38 ]
39 output _eval nth :ast 2 :letenv ]
40
41 [else
42 make "el obj_val eval_ast :ast :env
43 output apply first :el butfirst :el ]
44 ]
45 end
46
47 to _print :exp
48 output pr_str :exp "true
49 end
50
51 to rep :str
52 output _print _eval _read :str :repl_env
53 end
54
55 to mal_add :a :b
56 output obj_new "number ((obj_val :a) + (obj_val :b))
57 end
58
59 to mal_sub :a :b
60 output obj_new "number ((obj_val :a) - (obj_val :b))
61 end
62
63 to mal_mul :a :b
64 output obj_new "number ((obj_val :a) * (obj_val :b))
65 end
66
67 to mal_div :a :b
68 output obj_new "number ((obj_val :a) / (obj_val :b))
69 end
70
71 to repl
72 localmake "running "true
73 while [:running] [
74 localmake "line readline word "user> :space_char
75 ifelse :line=[] [
76 print "
77 make "running "false
78 ] [
79 if not emptyp :line [
80 catch "error [print rep :line]
81 localmake "exception error
82 if not emptyp :exception [
83 (print "Error: first butfirst :exception)
84 ]
85 ]
86 ]
87 ]
88 end
89
90 make "repl_env env_new [] [] []
91 ignore env_set :repl_env obj_new "symbol "+ "mal_add
92 ignore env_set :repl_env obj_new "symbol "- "mal_sub
93 ignore env_set :repl_env obj_new "symbol "* "mal_mul
94 ignore env_set :repl_env obj_new "symbol "/ "mal_div
95 repl
96 bye