-(in printer.ps\n) print
-
% requires types.ps to be included first
% ast print_readably -> _pr_str -> string
/_pr_str { 4 dict begin
/print_readably exch def
- dup
- /func? exch xcheck def % executable function
- /obj exch cvlit def
+ dup xcheck { (Cannot print proc: ) print dup == quit } if % assert
+ /obj exch def
obj _sequential? {
obj _list? { (\() (\)) }{ ([) (]) } ifelse
obj /data get ( ) print_readably _pr_str_args
( ) print_readably _pr_str_args
concatenate
(}) concatenate
- }{ obj _mal_function? { % if user defined function
+ }{ obj _function? { % if builtin function
+ (<\(builtin_fn* {)
+ obj /data get dup length array copy cvlit
+ ( ) print_readably _pr_str_args
+ (}>)
+ concatenate concatenate
+ }{ obj _mal_function? { % if user defined mal_function
(<\(fn* )
obj /params get print_readably _pr_str
( )
concatenate concatenate
}{ /arraytype obj type eq { % if list or code block
% accumulate an array of strings
- func? { (<builtin_fn* { ) }{ (\() } ifelse
+ (\()
obj ( ) print_readably _pr_str_args
concatenate
- func? { ( } >) }{ (\)) } ifelse
+ (\))
concatenate
}{ /integertype obj type eq { % if number
- /slen obj 10 add log ceiling cvi def
+ /slen
+ obj abs 1 max log floor cvi 1 add % positive size
+ obj 0 lt { 1 add } if % account for sign
+ def
obj 10 slen string cvrs
}{ /stringtype obj type eq { % if string
- print_readably {
- (") obj (") concatenate concatenate
- }{
- obj
+ obj length 0 gt { % if string length > 0
+ obj 0 get 127 eq { %if starts with 0x7f (keyword)
+ obj dup length string copy
+ dup 0 58 put % 58 is ':'
+ }{ print_readably {
+ (")
+ obj (\\) (\\\\) replace
+ (") (\\") replace
+ (\n) (\\n) replace
+ (") concatenate concatenate
+ }{
+ obj
+ } ifelse } ifelse
+ }{ % else empty string
+ print_readably {
+ ("")
+ }{
+ obj
+ } ifelse
} ifelse
}{ null obj eq { % if nil
(nil)
obj dup length string cvs
}{
(<unknown>)
- } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse
+ } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse } ifelse
end } def
% array delim print_readably -> _pr_str_args -> new_string
args length 0 gt { %if any elements
[
args { %foreach argument in array
- print_readably _pr_str
+ dup xcheck { %if executable
+ 255 string cvs
+ }{
+ print_readably _pr_str
+ } ifelse
} forall
]
{ concatenate delim concatenate } forall
dup length delim length sub 0 exch getinterval % strip off final delim
} if
end } def
+
+% utility function
+/print_dict {
+ (DICT contents:\n) print
+ {
+ ( - ) print
+ exch dup length string cvs print % key
+ (: ) print
+ ==
+ } forall
+} def
+