Category:Initlib

From Rosetta Code
Revision as of 07:30, 28 March 2011 by Rahul (talk | contribs)

Library

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 -dNODISPLAY -c '(initlib.ps) run' </lang>

initlib.ps <lang postscript> %!PS % conventions: parameter names with let begins with .

% basic definition, makes the definitions less verbose. /. {bind def} bind def /' {load} bind def /reverse {{} exch {exch [3 1 roll aload pop]} forall}. /let {dup length dict begin reverse {exch def} forall}. /let* {reverse {exch def} forall}.

% some predicates. /eq? {eq}. /list? {dup type /arraytype eq?}. /leaf? {list? not}. /empty? {dup length 0 eq?}. /zero? {dup 0 eq?}. % stack invariant, execute any predicate and leave stack untouched % except for answer. /? { 4 dict begin

   [/.pred] let*
   count array astore /.stack exch def
   /_restore {clear .stack aload pop}.
   .stack aload pop .pred /.top exch def
   _restore .top

end}.


% stacky functions /rup {3 1 roll}. /rdown {3 -1 roll}. /# {exch dup rdown .makeoperator bind def} bind def

/getname {dup 0 get exch}. /getbody {dup length 1 sub 1 exch getinterval}.

% convenience arithmetic /+ {add}. /- {sub}. /* {mul}. /\ {div}.

% lispy functions /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 ] }. % make a unit list. /unit {1 array astore cvx}. /succ {1 add}. /pred {1 sub}. /range {[rup exch aload pop rup exch rdown {} for]}.

% higher order thingies. /map { [ rup forall ] }. % [1 2 3 4] {1 add} map /fold {rup exch rdown forall}. %/reverse {{} {exch cons} fold}. % {} [1 2 3 4 5] {exch cons} 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}.

/transpose {

   [ exch {
       { {empty? exch pop} map all?} {pop exit} ift
       [ exch {} {uncons {exch cons} dip exch} fold counttomark 1 roll] uncons
   } loop ] {reverse} map

}. /zip {transpose}.

% [[1 2 3 4 ] [5 6 7 8] [9 10 11 12]] transpose /all? {

   {
       {empty?} ? {pop true exit} if
       uncons {?} dip exch not {pop false exit} if
   } loop

}. % 1 {{10 gt} {5 gt} {0 gt}} any? /any? {

   {
       {empty?} ? {pop false exit} if
       uncons {?} dip exch {pop true exit} if
   } loop

}. /pipe {

   {
       {empty?} ? {pop exit} if
       uncons {i} dip
   } loop

}. % 1 {{2 *} {3 *} {5 *}} pipe /collect {

   {
       {empty?} ? {pop exit} if
       uncons {?} dip
   } loop

}. % 1 {{2 *} {3 *} {5 *}} collect

% do on all elements of a tree. /treemap { [/.tree /.rec] let

   /.tree '
   {leaf?} /.rec '
       {{empty?} {}
           {dup
               {first /.rec ' treemap} dip
               {rest /.rec ' treemap} i cons}
       ifte}
   ifte

end}.

% control structures % ift - allow stack invariant if condition /ift { [/.if /.then] let

   /.if ' ?  /.then ' if

end}. % ift - allow stack invariant ifelse condition /ifte { [/.if /.then /.else] let

   /.if ' ?  /.then ' /.else ' ifelse

end}. % switch statement. /is? {{exit} concat cvx ift}. /cond {{exit} concat cvx loop}.

% combinators /dip { [/.v /.q] let

   .q /.v '

end}. /apply {exec}. /i {cvx exec}.

/linrec { [/.if /.then /.rec1 /.rec2] let

   /.if ' /.then '
       {.rec1
           {/.if ' /.then ' /.rec1 ' /.rec2 ' linrec} i
       .rec2}
   ifte

end}.

/binrec { [/.if /.then /.rec1 /.rec2] let

   /.if ' /.then '
       { .rec1
           {/.if ' /.then ' /.rec1 ' /.rec2 ' binrec} dip
           {/.if ' /.then ' /.rec1 ' /.rec2 ' binrec} i
         .rec2 }
   ifte

end}.

/genrec { [/.if /.then /.rec1 /.rec2] let

   /.if ' /.then '
       {.rec1
           {/.if ' /.then ' /.rec1 ' /.rec2 ' genrec}
        .rec2}
   ifte

end}.

/tailrec {{} linrec}.

/primrec { 5 dict begin

   /lzero? {
       {list?} {empty?}
               {zero?}
       ifte}.
   /lnext {
       {list?} {rest}
               {pred}
       ifte}.

[/.param /.then /.rec] let*

   {/.param ' lzero?} /.then '
       {.param
           {/.param ' lnext /.then ' /.rec ' primrec} i
       .rec}
   ifte

end}.

/cvstr {

   4 dict begin
       /elements exch def
       /len elements length def
       /str len string def
       /i 0 def
       {
       i len ge { exit } if
       str i
       %The element of the array, as a hexadecimal string.
       %If it exceeds 16#FF, this will fail with a rangecheck.
       elements i get cvi
       put
       /i i 1 add def
   } loop
   str

end } def


% debug /puts {= (\n) print flush}. /, {(=============\n)

   print pstack
   (=============\n) print}.

% set the prompt to something else so that we know initlib is loaded. /prompt {(>| ) print flush} bind def

</lang>