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*
71 { /user_defined
% mark this as user defined
72 __PARAMS__ __AST__ __ENV__
% closed over variables
74 /ENV
exch def
% closed over above, pos 3
75 /AST
exch def
% closed over above, pos 2
76 /PARAMS
exch def
% closed over above, pos 1
78 %(inside fn*:\n) print
81 %( ENV: ) print ENV ==
82 %( args: ) print args ==
83 AST ENV PARAMS args env_new EVAL
85 dup length array
copy cvx
% make an actual copy/new instance
86 dup 1 a1 put
% insert closed over a1 into position 1
87 dup 2 a2 put
% insert closed over a2 into position 2
88 dup 3 env put
% insert closed over env into position 3
90 /el ast env eval_ast def
92 el _first cvx
% function
93 %(vvv\n) print pstack (^^^\n) print
94 exec % apply function to args
95 } ifelse } ifelse } ifelse } ifelse } ifelse
107 /repl_env null
[ ] [ ] env_new def
109 /RE
{ READ repl_env EVAL
} def
110 /REP
{ READ repl_env EVAL PRINT
} def
111 /_ref
{ repl_env
3 1 roll env_set
pop } def
113 types_ns
{ _ref
} forall
115 (\
(def
! not \
(fn
* \
(a\
) \
(if a
false true\
)\
)\
)) RE
pop
117 /stdin
(%stdin) (r) file def
122 stdin
99 string readline
124 not
{ exit } if % exit if EOF
126 %(\ngot line: ) print dup print (\n) print flush
132 get_error_data
false _pr_str print
(\n) print
137 (\n) print
% final newline before exit for cleanliness