Mopsは様々なデータ(コードも含む)を辞書に書き込んで保存します。辞書は、実行のときにはメモリー内に存在しますから、辞書内に格納された各々はそれが配置されているメモリーの場所で特定します。アドレスとか、ポインタと呼びます。場所を特定する数値ということです。(ここでは、OSの複雑なメモリー管理のことは無視します。)
Mopsに新たにロードしたコードやデータを格納している辞書は、Mopsの終了と同時に捨てられてしまいます。これまでに拡張した辞書を保存して次にはそこからまた始めたい、というときには、Mopsの辞書を保存します。"File"メニューにある"Save Dictionary"という項目で、それが可能となっています。ちなみに、Mopsでは、書類の保存などの典型的なショートカットキーである"Cmd+S"は、この辞書の保存に割り当てられています。
少し話はズレますが、この辞書の保存は、単に辞書だけを保存するではなく、新しくロードした部分を追加した実行ファイルそのものを保存します。ですから、一旦終了した後でまた途中から始めようとするときは、ここで保存した実行ファイルそのものを起動することになります。
ところが、当然のことですが、再び起動した際に辞書がメモリ内の前と全く同じ場所に配置されるとは限りません。この配置はOSがその都度適当に割り当てた場所に実施されるに過ぎないからです。そのため、例えば、辞書内のアドレスで、コンパイル時点で既に値を確定して、その値を保管してしまったような場合には、そのままでは、新しく配置された辞書に対して正しいアドレスを表現していません。この問題は、とくに、XT(エグゼキューショントークン(executinon token))において発生します。
別のところにも書いたように、Forth系言語では、ワードのXT(他の言語の関数のポインタのようなもの)をデータとして保存しておき、適当なところでそのデータからワードを実行するというようなことができますし、ごく普通におこなわれます。このXTを、何らかの他のワードの定義内でではなく、地の部分でとって変数に格納すると、この値は、再起動後には、正しくXTを表現していないものとなってしまいます。
Variable MyXT
' myWord MyXT ! \ この値は終了後はほぼ間違いなく無効になる
....
: word2 MyXT @ EXECUTE ; \ このワードは、再起動後は実行時点でクラッシュする
Mopsはこの問題を回避する方法を持っています。もっとも基本的なのは、"RELOC!"と"@ABS"です。
つまり、次のようにすればよいわけです。
Variable MyXT
' myWord MyXT RELOC! \ この値は再起動後も有効にできる
: word2 MyXT @ABS EXECUTE ; \ このワードは、再起動後も実行できる。
例としてはXTを用いてきましたが、XTだけでなく、例えば、オブジェクトやクラスのポインタなども、辞書内のアドレスを指していますから、なんらかのワード定義の外で値を変数に格納したいときには"RELOC!"を使い、取り出すときには"@ABS"を使わなければなりません。
なお、ワード定義内で、"[']"を用いて取っているXTは、すでに再配置の可能性を織り込み済みなので、上の問題を考える必要はありません。
Mopsはさらにこれらのワードを基盤とした、いくつかのクラスを定義しています。これらについてはページを改めて説明します。
関連項目:
最終更新:2019年06月18日 17:19