[雑談] May the FORTH be with you
ということで、5月4日。
80年代にCQ出版社からマイコンピュータというムックが出ていました。
毎号一つのソフトウエア技術に焦点を当て、初歩から深いところまでを一気に特集した本で、その一冊にFORTHを特集したものがありました。
内容はうろ覚えですが、FIG-FORTHのソースコード、日本語が使えるRgy-FORTH (のちのfifth、Mind) の解説などが掲載されていたと思います。
FORTHはCやJavaなどの手続き型言語と異なり、データスタックを介して処理を行っていきます。
例えば3+4を計算する場合、「+」というデータスタックのスタックトップとスタックの2番目の値を取り出して加算し、スタックトップに結果をプッシュするワードを使用して、以下のように書きます。
3 4 +
すべてのワードは、自分で作成したワードも含め、すべてデータスタック上の値を取り出して処理を行い、結果をデータスタック上に積むという形式となっています。
処理に必要なデータはデータスタック上にあることが前提なので一時変数や引数といった概念はなく、メモリ管理は容易です。
また、ワードは入力された順に実行されるので、構文解析も (原則として) 必要ありません。
例えば、「3 + 4 * 5」という式は手続き型言語では式全体を調べて、演算子順序に基づいて「4 * 5」を実行した後、3にその結果を足すといった処理を行う必要があります。
これがFORTHでは「3 4 5 * +」と記述され、左から順に評価していくだけで処理が行えます。
※ なお「(3 + 4) *5」は「3 4 + 5 *」というように記述自体が変わります。
※ Rgy-FORTHでは「を足す」を「+」に、「をかける」を「*」に定義し、「と」を何もしないワードとして定義することで上の二つの式を「3と4と5をかけるを足す」、「3と4を足すと5をかける」のように日本語風に書けるようにしていました。
こういったメモリ管理や処理の容易さからFORTHはSun microsystems社のワークステーション、サーバーで電源投入時などにインタフェースカードなどの周辺機器を初期化するファームウエアに採用されていました。
ところで、FORTHはインタプリタ形式で動作するもので、起動するとコマンドラインインタプリタが動作し、数値や文字列などのリテラルが入力されるとそれをデータスタックに積む、ワードが入力されるとワードが実行されます。
複雑な処理を行う場合にはワード定義を行います。
ワード定義は「:名前 ... ;」という形式で記述し、コマンドラインインタプリタは「:」を受け取るとワード定義モードに遷移して「;」までのワードやリテラルを記録し、名前を付けてワードリストに保存します。
以降は定義した名前をワードとして入力することで保存されたワード列が実行されて処理が行われます。
また、条件判断は「条件 if ... else ... then」のように記述します。
条件が成立していればifは実行モードになって順次実行を行い、不成立であれば読み飛ばしモードで引き続くワードやリテラルを読み飛ばします。
elseは実行モードで実行されると読み飛ばしモードに移行し、読み飛ばしモードで検出されると実行モードに移行します。
thenは実行モード、読み飛ばしモードのいずれであっても通常モードに移行します。
このように条件判断もほぼワード単位の解釈で動作できるようになっています。
しかし、一貫性という観点では動作モードが必要な点がちょっと惜しいところです。
さて、PostScriptというページ記述言語があります。
一般的には印刷用データとしてしか認識されていませんが、PostScriptもFORTHと同様のスタックベースのプログラミング言語になっています。
大昔、まだネットワーク回線が細く、コンピュータも非力だった時代に大容量となる高解像度印刷データをどのようにプリンタに送ればいいかという課題に対する答えとして、プログラムとして送信すればデータ量を抑えることができる、スタックベースのプログラミング言語を使用すればプリンタの処理負荷も大きくならないという見通しからPostScriptが作られました。
PostScriptの特徴的な点の一つとして、手続きリテラルを導入したことが挙げられます。
FORTHでは動作モードを切り替えることでワード定義や条件判断を実現していましたが、PostScriptでは手続きオブジェクトを導入したことで動作モードという考え方が不要になりました。
具体的には「{ ... }」というように中かっこでくくると、その中身は手続きオブジェクトとしてデータスタック上に積まれます。
その後オブジェクトに名前を付けて実行辞書に登録するdefオペレータを使用すればオペレータとして使用できるようになるし、条件とオブジェクトを受け取るifやifelseオペレータを使用すれば条件に従った実行ができます。
ここでのポイントは手続きオブジェクトが数値や文字列と同等に扱われるということです。
例えば「/a 3 def」と書けば「a」を入力すれば「3」を入力したときと同様に3がデータスタックに積まれ、「/a { add } def」と書くと「a」を入力すれば「add」が入力されたのと同様に実行されます。
このようにPostScriptは手続きと数値、文字列などを同様に扱えるようにしている点が特徴となっています。
スタックベースのプログラミング言語を使用する機会は少ないと思いますが、一度調べてみるのも面白いかと思います。
[追記]
こんなの見つけました
0コメント