PS: add step7_quote
[jackhill/mal.git] / ps / step3_env.ps
1 (types.ps) run
2 (reader.ps) run
3
4 % read
5 /READ {
6 /str exch def
7 str read_str
8 } def
9
10
11 % eval
12 /eval_ast { 2 dict begin
13 /env exch def
14 /ast exch def
15 %(eval_ast: ) print ast ==
16 ast _symbol? { %if symbol
17 env ast env_get
18 }{ ast _list? { %elseif list
19 [
20 ast {
21 env EVAL
22 } forall
23 ]
24 }{ % else
25 ast
26 } ifelse } ifelse
27 end } def
28
29 /EVAL { 8 dict begin
30 /env exch def
31 /ast exch def
32 %(EVAL: ) print ast ==
33 ast _list? not { %if not a list
34 ast env eval_ast
35 }{ %else apply the list
36 /a0 ast 0 get def
37 /def! a0 eq { %if def!
38 /a1 ast 1 get def
39 /a2 ast 2 get def
40 env a1 a2 env EVAL env_set
41 }{ /let* a0 eq { %if let*
42 /a1 ast 1 get def
43 /a2 ast 2 get def
44 /let_env env [ ] [ ] env_new def
45 0 2 a1 length 1 sub { %for each pair
46 /idx exch def
47 let_env
48 a1 idx get
49 a1 idx 1 add get let_env EVAL
50 env_set
51 } for
52 a2 let_env EVAL
53 }{
54 /el ast env eval_ast def
55 el _rest % args array
56 el _first cvx % function
57 exec % apply function to args
58 } ifelse } ifelse
59 } ifelse
60 end } def
61
62
63 % print
64 /PRINT {
65 true _pr_str
66 } def
67
68
69 % repl
70 /repl_env null [ ] [ ] env_new def
71
72 /REP { READ repl_env EVAL PRINT } def
73 /_ref { repl_env 3 1 roll env_set pop } def
74
75 (+) { dup 0 get exch 1 get add } _ref
76 (-) { dup 0 get exch 1 get sub } _ref
77 (*) { dup 0 get exch 1 get mul } _ref
78 (/) { dup 0 get exch 1 get idiv } _ref
79
80 /stdin (%stdin) (r) file def
81
82 { % loop
83 (user> ) print flush
84
85 stdin 99 string readline
86
87 not { exit } if % exit if EOF
88
89 %(\ngot line: ) print dup print (\n) print flush
90
91 { %try
92 REP print (\n) print
93 } stopped {
94 (Error: ) print
95 get_error_data false _pr_str print (\n) print
96 clear
97 } if
98 } bind loop
99
100 (\n) print % final newline before exit for cleanliness
101 quit