/runlibfile where { pop }{ /runlibfile { run } def } ifelse % (types.ps) runlibfile (reader.ps) runlibfile (printer.ps) runlibfile % read /_readline { print flush (%stdin) (r) file 1024 string readline } def /READ { /str exch def str read_str } def % eval /eval_ast { 2 dict begin /env exch def /ast exch def %(eval_ast: ) print ast == ast _symbol? { %if symbol env ast known { env ast get }{ (') ast false _pr_str (' not found) concatenate concatenate _throw } ifelse }{ ast _sequential? { %elseif list or vector [ ast /data get { %forall items env EVAL } forall ] ast _list? { _list_from_array }{ _vector_from_array } ifelse }{ ast _hash_map? { %elseif list or vector << ast /data get { %forall entries env EVAL } forall >> _hash_map_from_dict }{ % else ast } ifelse } ifelse } ifelse end } def /EVAL { 3 dict begin /env exch def /ast exch def %(EVAL: ) print ast true _pr_str print (\n) print ast _list? not { %if not a list ast env eval_ast }{ %else apply the list ast _count 0 eq { ast }{ /el ast env eval_ast def el _rest el _first % stack: ast function exec % apply function to args } ifelse } ifelse end } def % print /PRINT { true _pr_str } def % repl /repl_env << (+) { dup 0 _nth exch 1 _nth add } (-) { dup 0 _nth exch 1 _nth sub } (*) { dup 0 _nth exch 1 _nth mul } (/) { dup 0 _nth exch 1 _nth idiv } >> def /REP { READ repl_env EVAL PRINT } def % repl loop { %loop (user> ) _readline not { exit } if % exit if EOF { %try REP print (\n) print } stopped { (Error: ) print get_error_data false _pr_str print (\n) print $error /newerror false put $error /errorinfo null put clear cleardictstack } if } bind loop (\n) print % final newline before exit for cleanliness quit