Category:Initlib: Difference between revisions
(transpose) |
|||
Line 92:
}.
/transpose {
[ exch {
{ {empty? exch pop} map all?} {pop exit} ift
[ exch {} {uncons {exch cons} dip exch} fold counttomark 1 roll] uncons
} loop ] {reverse} map
}.
% [[1 2 3 4 ] [5 6 7 8] [9 10 11 12]] transpose
/all? {
{
|
Revision as of 07:25, 28 March 2011
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}. /zip {
[rup{ dup length 0 eq rdown dup length 0 eq rdown or {exit} if uncons rdown uncons rdown 4 2 roll unit cons rup exch } loop pop pop]
}.
/transpose {
[ exch { { {empty? exch pop} map all?} {pop exit} ift [ exch {} {uncons {exch cons} dip exch} fold counttomark 1 roll] uncons } loop ] {reverse} map
}. % [[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>
Pages in category "Initlib"
The following 27 pages are in this category, out of 27 total.