掴んだ物(技術)はちゃんと食べる記録帳

興味を持ったものに対する足跡を残していくために作成しました。勉強しながら書いているので、間違いや短絡もあると思います。ご指摘いただけると喜びます。

Let's PostScript(5) 手続きObjectと制御オペレータ

手続きオブジェクト

{.....}は実行可能の属性持つ配列のObjectです。手続きObjectと呼ばれます。 手続きObjectは今まで見てきた”dup”や"copy"といった実行可能の属性を持つオブジェクトとは大きな相違があります。 それは、インタプリタがObjectを検出した時に現れます。

属性 配列 インタプリタ動作
実行可能 yes Operand StackにPushされる
実行可能 no インタープリタによって直ちに実行される
Literal Operand StackにPushされる

手続きObjectは実行可能であるにも関わらず、即実行せずにいったんOperandStackに格納します。このような動作を遅延実行と呼びます。 一方で、"dup"や"copy"といった単一の実行可能Objectの即実行される動作を即時実行と呼びます。

OperandStackの手続きオブジェクトを直接実行するにはexecオペレータなどを使用しますが、一般的には後述する制御オペレータによって実行するのが一般的ではないかと思います。

GS>{1 2 3 4 5 exch}
GS<1>exec
GS<5>stack
4
5
3
2
1

制御オペレータ

論理値(true,false)から、次に実行する手続きObjectを制御するオペレータを制御オペレータと呼びます。例えば、以下のようなスクリプトです。

ex.1
GS>true {(I'm True)} if
GS<1>=
I'm True

ex.2
GS>false {(I'm True)} if

ex.3
GS>true {(I'm True)} {(I'm False)} ifelse
GS<1>=
I'm True

ex.4
GS>false {(I'm True)} {(I'm False)} ifelse
GS<1>=
I'm False

ex.1では trueと{(I'm True)}}の2つのObjectがOperandStackに格納され、ifオペレータは論理値を受け取ります。今回はtrueだったため、手続きObjcet{(I'm True)}を実行しその結果(I'm True)ObjectがOperandStackに格納されます。

ex.2では falseと{(I'm True)}}の2つのObjectがOperandStackに格納され、ifオペレータは論理値を受け取ります。今回はfalseだったため、手続きObjcet{(I'm True)}は破棄されます。

ex.3では、trueと{(I'm True)}と{(I'm False)}の3つのObjectがOperandStackに格納され、ifelseオペレータは論理値を受け取ります。今回はtrueだったため、1つ目の手続きObjectである{(I'm True)}を実行しその結果(I'm True)ObjectがOperandStackに格納されます。2つ目の手続きObject{(I'm False)}は破棄されます。

ex.4では、falseと{(I'm True)}と{(I'm False)}の3つのObjectがOperandStackに格納され、ifelseオペレータは論理値を受け取ります。今回はfalseだったため、1つ目の手続きObjectである{(I'm True)}は破棄されます。2つ目の手続きObject{(I'm False)}を実行しその結果(I'm False)ObjectがOperandStackに格納されます。

これらの例では、論理値を直書きしていますが、実際には関係オペレータの結果の論理値を制御オペレータに渡すパターンが多くなります。以下のようなスクリプトになります。

ex.5
GS>1 1 eq {(Equal Object!)} if
GS<1>=
Equal Object!

ex.6
GS>1 0 eq {(Equal Object!)} if

ex.7
GS>1 1 eq {(Equal Object!)} {(Non Equal Object!)} ifelse
GS<1>=
Equal Object!

ex.8
GS>1 0 eq {(Equal Object!)} {(Non Equal Object!)} ifelse
GS<1>=
Non Equal Object!

ex.4~8はex.1~4までとほぼ変わらないのですが、ようやくスクリプトっぽい動作に見えてくるのが不思議。

次回は、繰り返し処理を見ていこうと思います。