12 /eval_ast
{ 2 dict begin
15 %(eval_ast: ) print ast ==
16 /nametype ast type eq
{ %if symbol
18 }{ /arraytype ast type eq
{ %elseif list
32 %(EVAL: ) print ast ==
33 /arraytype ast type ne
{ %if not a list
35 }{ %else apply the list
37 /def
! a0 eq
{ %if def!
40 env a1 a2 env EVAL env_set
41 }{ /let
* a0 eq
{ %if let*
44 /let_env env
[ ] [ ] env_new def
45 0 2 a1 length
1 sub { %for each pair
49 a1 idx
1 add get let_env EVAL
54 /el ast _rest env eval_ast def
55 el el length
1 sub get
% return last value
59 cond null eq cond
false eq or
{ % if cond is nil or false
60 ast length
3 gt
{ %if false branch (a3) provided
61 ast
3 get env EVAL
% EVAL false branch (a3)
66 ast
2 get env EVAL
% EVAL true branch (a2)
68 }{ /fn
* a0 eq
{ %if fn*
72 /A1 __a1__ def
% close over positino 4
73 /A2 __a2__ def
% close over position 7
74 /ENV __env__ def
% close over position 10
76 %(inside fn*:\n) print
79 %( ENV: ) print ENV ==
80 %( args: ) print args ==
81 A2 ENV A1 args env_new EVAL
83 dup length array
copy cvx
% make an actual copy/new instance
84 dup 4 a1 put
% insert closed over a1 into position 4
85 dup 7 a2 put
% insert closed over a1 into position 7
86 dup 10 env put
% insert closed over a1 into position 10
88 /el ast env eval_ast def
90 el _first cvx
% function
91 %(vvv\n) print pstack (^^^\n) print
92 exec % apply function to args
93 } ifelse } ifelse } ifelse } ifelse } ifelse
105 /repl_env null
[ ] [ ] env_new def
107 /RE
{ READ repl_env EVAL
} def
108 /REP
{ READ repl_env EVAL PRINT
} def
109 /_ref
{ repl_env
3 1 roll env_set
pop } def
111 types_ns
{ _ref
} forall
113 (\
(def
! not \
(fn
* \
(a\
) \
(if a
false true\
)\
)\
)) RE
pop
115 /stdin
(%stdin) (r) file def
120 %(%lineedit) (r) file 99 string readline
121 stdin
99 string readline
123 not
{ exit } if % exit if EOF
125 %(\ngot line: ) print dup print (\n) print flush
131 get_error_data
false _pr_str print
(\n) print
136 (\n) print
% final newline before exit for cleanliness