はじめに
古典的なFORTH と GNU gforth との違いについてなんとなく思いつくままにつまみ食いしていきます。
GNU gforth は OS 上で動くようデザインされている
まぁ、いまどきだと OS 上で動くほうが当たり前ですが、 昔のFORTHはOSを介さず直接FORTHが走るスタンドアロンなタイプもあり、今でも組み込み用のはOSを介さないものが多いです。
そのために、フロッピーディスク I/O もFORTHからフロッピーディスクコントローラーを叩いて直接入出力する仕組みとして、 スクリーン/ブロックモードを備えています。 このスクリーン/ブロックモードはGNU gforth 上でもエミュレートされています。
文字列の扱いがマシになった機能が追加された
counted string
古典的なFORTHの文字列(string)は counted string と言います。長さ用に1バイト、続けて長さ分のバイト領域が続くものです。
例えば "counted" (7文字) を C言語風に書くと
unsigned char cstr[8] = { 7,'c','o','u','n','t','e','d'}
で、注意して欲しいのは C言語と違って \0 で終端しないことです。
また、 スタックに積む場合は cstr[1] 文字列本体へのポインタと、長さ cstr[0] を積みます。 スタック効果としては ( -- c-addr u ) です。
文字列処理するときは最初に文字数が分かるので処理しやすいという利点はあります。
しかし、 unsigned char にしても文字列の最大長は255文字までなので、 大変つかいにくいものでした。
gforth の $tring
gforth では改良した 文字列が追加されています(昔からの counted string も依然として使用可能)
s" GNU gforth manual" ok 2
.s <2> 108942773656848 17 ok 2
drop 32 dump
631537531D10: 47 4E 55 20 67 66 6F 72 - 74 68 20 6D 61 6E 75 61 GNU gforth manua
631537531D20: 6C 63 72 65 61 74 65 5F - 31 00 00 00 00 00 00 00 lcreate_1.......
文字列本体をヒープに自動で取得した領域に格納し、 そのアドレスと文字数(セル単位なのでそこそこの長さまでOK)
$tring
$tring (なんと読むのか知らん) は 1クッション置く感じで間接的に扱うものです。
文字列の長さと文字列本体を置いたヒープのエリアへのアドレスだけをスタックに積みます。$tring 専用の $hogehoge なワード群が用意されています。
s\" GNU\ngforth\nmanual\n"
C言語風のエスケープシーケンスが使えるワード。 printf みたいに置換とかできないのでいまいち。
Recognizer(認識器)
※実験的機能です。
テキスト・インタープリター(外部インタープリター)を拡張し Recognizer 群を組み込んであるので、シンタックス・シュガーっぽい機能が使えます。
使い始めると古典的FORTHの「ワードは空白で区切って書く」から少々外れてきます。
ワードを切り出し、当該ワードを実行する時の前処理として走るので、
ワード自体を(空白をあけずに)装飾することが可能になっています。
- s" hogehoge" は "hogehoge" と書けます。 区切りの空白不要
- ' hoge は `hoge
- 環境変数へのアクセス ${HOME}
- etc.
ヘッダー構造の大幅拡張
オブジェクト指向を意識したヘッダー構造に変わっています。
ローカル変数
ワードの先頭で引数プロトタイプのようにして使うこともできますし、単純にローカル変数を定義して使うこともできます。
他の言語で慣れ親しんだローカル変数使いまくりな記述も可能にではあります。
オブジェクト指向
オブジェクト指向化するパッケージは数種類あって統一されていません。目的に応じて使い分ける形になります。
正規表現
一応サポートしてるけど日本語対応してないっぽい。
C Interface
GNU gforth の大部分は C言語 (gcc) で記述されているのでワードのクリティカルな部分は C言語で書くことも可能です。
クリティカルな部分を知るためにはプロファイラが役に立つでしょう。
アセンブラ・逆アセンブラ
アセンブラと逆アセンブラを装備しています。プリミティブ・ワードがどのように実行されているか確認できる(が、 その多くはC言語で書かれているので対応するC言語のソース探した方がいいかも)
エンジン
エンジン名=実行ファイル名になっています。 通常は gforth で開発します。 gforth-fast はゼロ割とかのエラー処理を省略して高速化を図ったもの、 gforth-itc は内部インタプリタ動作を古典的FORTHに合わせたものです。 デバッグなど用途に応じてエンジンを使い分けます。
vmgen
別途 vmgen というアプリが付属しています。これは gforth のVM(Virtual Machine)を生成するためのツールです。
既に生成済の gforth 等は vmgen で生成した VM の上に構築されています(たぶん)。
今回はここまで。