Category:PostScript: Difference between revisions

(Add ghostscript.)
Line 13:
Here is a library of functions tested in ghostscript. It is assumed to be loaded before startup with a command line such as
<lang>
ghostscript -q -dOSTACKPRINT -dESTACKPRINT -dNODISPLAY -c '(initlib.ps) run'
</lang>
 
initlib.ps
<lang postscript>
% given [sym x y z] get sym and [x y z] separately
/getname {dup 0 get exch} bind def
/getbody {dup length 1 sub 1 exch getinterval} bind def
/rup {3 1 roll} bind def
/rdown {3 -1 roll} bind def
% convenience for binding.
/. {bind def} bind def
/' {load} bind def
% .makeoperator is ghostscript specific. But this gives us lexical binding.
/# {exch dup rdown .makeoperator bind def} bind def
% A few lispy words
/first {0 get}.
/car {first}.
/!first {dup first}.
/rest {dup length 1 sub 1 exch getinterval}.
/cdr {rest}.
/!rest {dup rest}.
/head {dup length 1 sub 0 exch getinterval}.
/!head {dup head}.
/tail {dup length 1 sub get}.
/!tail {dup tail}.
/cons {[rup aload pop] }.
/tadd {[rup aload length 1 add -1 roll] }.
/uncons {getname getbody}.
/concat {exch [ rup aload pop counttomark -1 roll aload pop ] }.
% higher order
/map {
[ rup forall ]
}.
% [1 2 3 4] {1 add} map
/fold {rup exch rdown forall}.
% [1 2 3 4 5] 1 {add} fold
 
/let {dup length dict begin reverse {exch def} forall}.
/let* {reverse {exch def} forall}.
% [1 2 3 4] 0 {+} fold
% name - filter is taken so we are left with..
/find {
4 dict begin
/aif {0 /get /if}.
/atox { [ exch cvx {cvx} forall ] cvx}.
[ rup [ /dup rdown /exec /not [{pop}] aif ] atox forall ]
end}.
% ifs with stack invariant predicates.
/ift {
4 dict begin
[/.if /.then] let*
count array astore /.stack exch def
/_restore {clear .stack aload pop}.
.stack aload pop .if {
_restore .then
} {
_restore
} ifelse
end}.
% 2 {1 gt} {=} ift
 
/ifte {
4 dict begin
[/.if /.then /.else] let*
count array astore /.stack exch def
/_restore {count array astore pop .stack aload pop}.
.stack aload pop .if {
_restore .then
} {
_restore .else
} ifelse
end}.
% 1 {2 gt} {3 * =} {2 * =} ifte
/apply {exec}.
/i {cvx exec}.
 
% make a unit list.
/unit {1 array astore cvx}.
/succ {1 add}.
/pred {1 sub}.
% combinators
/linrec {
[/.if /.then /.rec /.join] let
.if {.then} {.rec /.if ' /.then ' /.rec ' /.join ' linrec . join } ifelse
end}.
 
% and convenience
/reverse {{} {exch cons} fold}.
/puts {print (\n) print flush}.
/, {(=============\n)
print pstack
(=============\n) print}.
% set the prompt
/prompt {(>| ) print flush} bind def
</lang>
418

edits