PostScript で if を自分で定義したり、switch case 文を作ったり
できる、できるのだ。PostScript って柔軟な言語なんですよ。
まずは if と ifelse と unless
/myifelse{ 2 dict dup false 4 3 roll put dup true 4 3 roll put exch get exec }def /myif{ {}myifelse }def /unless{ {}exch myifelse }def
Ghostscript で実行。
GS> 0 0 eq{(hoge)}{(foo)}myifelse = hoge GS> 1 2 eq{(hoge)}{(foo)}myifelse = foo GS> 1 2 add 3 eq{(fuga) =}myif fuga GS> 1 2 add 3 ne{(fuga) =}myif GS> 1 2 add 3 ne{(fuga) =}unless fuga
switch case はこんな感じ。作った後で気づいたけど 歪 : その6 (2004/09/05〜) で既出です。やり方は違いますけど。追記:/default が無い場合のバグ修正
/switch{ % val [[val0 proc0] [val1 proc1] [val2 proc2]...] switch % val = val_n の時 proc_n を実行 % val と同じ値が無い場合は val_n = /default となる proc_n を実行 % val_n = /default となる n が無い場合は何もしない dup length dict exch { 1 index exch cvx exec put }forall dup 2 index known{ exch get exec }{ exch pop dup /default known{ /default get exec }{ pop }ifelse }ifelse }def
Ghostscript で実行その1。
/a 1 def 0 1 5{ dup =only (:) print [ [0 {(It is 0.)=}] [2 2 mul {(It is 2*2)=}] [a {(It is a)=}] [1 2 add {(It is 1+2)=}] [2 {(It is 2.)=}] [/default {(default)=}] ]switch }for
実行結果その1
0:It is 0. 1:It is a. 2:It is 2. 3:It is 1+2. 4:It is 2*2. 5:default
実行その2。
/a[ [(a) {(string a)=}] [/b {(name /b)=}] ]switch
実行結果その2
string a
実装上の都合により、case の方の文字列 (a) は名前 /a と同じとみなされます。
追記dict ではなく << と >> を使った方が簡単な事に気づいた。myifelse と switch をそれぞれ
/myifelse{ << true 4 3 roll false 5 4 roll >> exch get exec }def /switch{ << exch {cvx exec} forall >> dup 2 index known{ exch get exec }{ exch pop dup /default known{ /default get exec }{ pop }ifelse }ifelse }def
とする方が短い