-(types.ps) run
-(reader.ps) run
+/runlibfile where { pop }{ /runlibfile { run } def } ifelse %
+(types.ps) runlibfile
+(reader.ps) runlibfile
+(printer.ps) runlibfile
% read
+/_readline { print flush (%stdin) (r) file 99 string readline } def
+
/READ {
/str exch def
str read_str
/env exch def
/ast exch def
%(eval_ast: ) print ast ==
- /nametype ast type eq { %if symbol
- env ast get
- }{ /arraytype ast type eq { %elseif list
+ 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 {
+ 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 } ifelse } ifelse
end } def
/EVAL { 3 dict begin
/env exch def
/ast exch def
- %(EVAL: ) print ast ==
- /arraytype ast type ne { %if not a list
+
+ %(EVAL: ) print ast true _pr_str print (\n) print
+ ast _list? not { %if not a list
ast env eval_ast
}{ %else apply the list
/el ast env eval_ast def
- el _rest % args array
- el _first % function
- %(vvv\n) print pstack (^^^\n) print
+ el _rest el _first % stack: ast function
exec % apply function to args
} ifelse
end } def
% print
/PRINT {
- /exp exch def
- %(printing: ) print exp ==
- exp pr_str
+ true _pr_str
} def
% repl
/repl_env <<
- (+) { dup 0 get exch 1 get add }
- (-) { dup 0 get exch 1 get sub }
- (*) { dup 0 get exch 1 get mul }
- (/) { dup 0 get exch 1 get idiv }
+ (+) { 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
-/stdin (%stdin) (r) file def
-
-{ % loop
- (user> ) print flush
-
- %(%lineedit) (r) file 99 string readline
- stdin 99 string readline
-
+% repl loop
+{ %loop
+ (user> ) _readline
not { exit } if % exit if EOF
- %(\ngot line: ) print dup print (\n) print flush
- REP print (\n) print
+ { %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