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

とする方が短い