PS: add step4_if_fn_do
[jackhill/mal.git] / ps / step2_eval.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 /nametype ast type eq { %if symbol
17 env ast known {
18 env ast get
19 }{
20 (') ast pr_str (' not found)
21 concatenate concatenate throw
22 } ifelse
23 }{ /arraytype ast type eq { %elseif list
24 [
25 ast {
26 env EVAL
27 } forall
28 ]
29 }{ % else
30 ast
31 } ifelse } ifelse
32 end } def
33
34 /EVAL { 3 dict begin
35 /env exch def
36 /ast exch def
37 %(EVAL: ) print ast ==
38 /arraytype ast type ne { %if not a list
39 ast env eval_ast
40 }{ %else apply the list
41 /el ast env eval_ast def
42 el _rest % args array
43 el _first % function
44 %(vvv\n) print pstack (^^^\n) print
45 exec % apply function to args
46 } ifelse
47 end } def
48
49
50 % print
51 /PRINT {
52 true _pr_str
53 } def
54
55
56 % repl
57 /repl_env <<
58 (+) { dup 0 get exch 1 get add }
59 (-) { dup 0 get exch 1 get sub }
60 (*) { dup 0 get exch 1 get mul }
61 (/) { dup 0 get exch 1 get idiv }
62 >> def
63
64 /REP { READ repl_env EVAL PRINT } def
65
66 /stdin (%stdin) (r) file def
67
68 { % loop
69 (user> ) print flush
70
71 %(%lineedit) (r) file 99 string readline
72 stdin 99 string readline
73
74 not { exit } if % exit if EOF
75
76 %(\ngot line: ) print dup print (\n) print flush
77
78 { %try
79 REP print (\n) print
80 } stopped {
81 (Error: ) print
82 get_error_data false _pr_str print (\n) print
83 clear
84 } if
85 } bind loop
86
87 (\n) print % final newline before exit for cleanliness
88 quit