Merge pull request #362 from bjh21/bjh21-concat-ps
[jackhill/mal.git] / ps / step3_env.ps
CommitLineData
fa64b741
JM
1/runlibfile where { pop }{ /runlibfile { run } def } ifelse %
2(types.ps) runlibfile
3(reader.ps) runlibfile
4(printer.ps) runlibfile
5(env.ps) runlibfile
04517bc8
JM
6
7% read
406761e7 8/_readline { print flush (%stdin) (r) file 1024 string readline } def
950e3c76 9
04517bc8
JM
10/READ {
11 /str exch def
12 str read_str
13} def
14
15
16% eval
17/eval_ast { 2 dict begin
18 /env exch def
19 /ast exch def
20 %(eval_ast: ) print ast ==
8e7e339d 21 ast _symbol? { %if symbol
04517bc8 22 env ast env_get
5ce65382 23 }{ ast _sequential? { %elseif list or vector
04517bc8 24 [
5ce65382 25 ast /data get { %forall items
04517bc8
JM
26 env EVAL
27 } forall
5ce65382
JM
28 ] ast _list? { _list_from_array }{ _vector_from_array } ifelse
29 }{ ast _hash_map? { %elseif list or vector
30 <<
31 ast /data get { %forall entries
32 env EVAL
33 } forall
34 >> _hash_map_from_dict
04517bc8
JM
35 }{ % else
36 ast
5ce65382 37 } ifelse } ifelse } ifelse
04517bc8
JM
38end } def
39
46669c86 40/EVAL { 8 dict begin
04517bc8
JM
41 /env exch def
42 /ast exch def
950e3c76
JM
43
44 %(EVAL: ) print ast true _pr_str print (\n) print
8e7e339d 45 ast _list? not { %if not a list
04517bc8
JM
46 ast env eval_ast
47 }{ %else apply the list
5ce65382 48 /a0 ast 0 _nth def
12e4facd
DM
49 a0 _nil? { %if ()
50 ast
51 }{ /def! a0 eq { %if def!
5ce65382
JM
52 /a1 ast 1 _nth def
53 /a2 ast 2 _nth def
04517bc8
JM
54 env a1 a2 env EVAL env_set
55 }{ /let* a0 eq { %if let*
5ce65382
JM
56 /a1 ast 1 _nth def
57 /a2 ast 2 _nth def
58 /let_env env null null env_new def
59 0 2 a1 _count 1 sub { %for each pair
04517bc8
JM
60 /idx exch def
61 let_env
5ce65382
JM
62 a1 idx _nth
63 a1 idx 1 add _nth let_env EVAL
04517bc8 64 env_set
3da90d39 65 pop % discard the return value
04517bc8
JM
66 } for
67 a2 let_env EVAL
68 }{
69 /el ast env eval_ast def
950e3c76
JM
70 el _rest el _first % stack: ast function
71 exec % apply function to args
12e4facd 72 } ifelse } ifelse } ifelse
04517bc8
JM
73 } ifelse
74end } def
75
76
77% print
78/PRINT {
0a2c6954 79 true _pr_str
04517bc8
JM
80} def
81
82
83% repl
5ce65382 84/repl_env null null null env_new def
04517bc8
JM
85
86/REP { READ repl_env EVAL PRINT } def
04517bc8 87
8cb5cda4 88/_ref { repl_env 3 1 roll env_set pop } def
5ce65382
JM
89(+) { dup 0 _nth exch 1 _nth add } _ref
90(-) { dup 0 _nth exch 1 _nth sub } _ref
91(*) { dup 0 _nth exch 1 _nth mul } _ref
92(/) { dup 0 _nth exch 1 _nth idiv } _ref
04517bc8 93
86b689f3
JM
94% repl loop
95{ %loop
950e3c76 96 (user> ) _readline
04517bc8
JM
97 not { exit } if % exit if EOF
98
aef93ea3
JM
99 { %try
100 REP print (\n) print
101 } stopped {
102 (Error: ) print
0a2c6954 103 get_error_data false _pr_str print (\n) print
950e3c76
JM
104 $error /newerror false put
105 $error /errorinfo null put
aef93ea3 106 clear
950e3c76 107 cleardictstack
aef93ea3 108 } if
04517bc8
JM
109} bind loop
110
111(\n) print % final newline before exit for cleanliness
112quit