Local Section (ローカルセクション)
この機能は、簡単に言えば、局所変数と局所インスタンス(
テンポラリオブジェクト)を特定範囲のワード間で共用できるようにすることです。
実際問題としては、よほど特殊なことをしない限り、この機構が必要になることはありません。特殊な状況下でのMops特有の効率化の方法と考えていいでしょう。
Mopsでは、スタックにあまりに多くのデータを積み込むよりも、一部を局所変数にまわした方が実行効率が良くなります。C言語系の
システムコールとの接合のためや、機械に近いレベルで沢山のパラメターが必要なときなどは、このことは強みになります。ところが、同時に、このような局面では、長い間局所変数を保持しておく必要がでてくる場合があります。しかし、局所変数の有効区間は1ワード内限りです。そうすると、いきおい、ひとつのワードの定義が長くなってきます。
しかし、1ワードの定義が長くなると、一般に読みにくくなり、保守が難しくなります。普通は、まとまった処理毎に区分してワードを小分けに定義するのですが、局所変数の共用のためには、それができません。
この難点を回避するのが、Local Sectionです。実質的には、ひとつのワードを小部分に区分けして、それぞれに名前をつけることができるようにしたものという方が正確かもしれません。構文としては、
LOCAL MyLocalSect { parm1 parm2 \ loc1 loc2 -- }
: inword1 [コード1] ;
: inword2 [コード2] ;
: inword3 inword1 inword2 [コード3] ;
: inword4 [コード4] ;
:LOC MyLocalSect inword3 inword4 [コード5] ;LOC
のようになります。
はじめに"LOCAL"と書いてから、主要なワードの名前と局所変数を宣言します。このワードは、セクションの最後に、":LOC"で始まり";LOC"で終わる形で定義され、セクションを締めくくります。通常のワードとしてセクション外から呼び出すことができるのは、このワードだけです。つまり、ここで定義されているのは実質的にはこの名前のワードひとつである、といえます。内容は、セクション内的なワードで定義されます。セクション内では、最後のワード定義内も含めて、セクションはじめに宣言された局所変数を自由に使うことができ、その値は維持されます。反面、セクション内のワードは、固有の局所変数やテンポラリオブジェクトを持つことはできません。内部的ワードはどうしでは、その定義順序に従って(先に定義してあるものじゃないと、未定義なので呼び出せないという意味)自由に呼び出すことができます。その他に、"[コード~]"と書かれた部分では、通常どおりセクションの内外を問わず既定義ワードを呼び出してコードを書くことができます。ちなみに[コード~]の部分がおしまいについているのは偶々で、もちろん途中に混ぜても大丈夫です。ただし、繰り返しになりますが、"inword1~4"をセクションの外から呼び出すことはできません。
局所変数は、"MyLocalSect"の局所変数として宣言したのと同じ扱いで、ワード"MyLocalSect"は二つの名前付きパラメターを持つということになります。局所変数宣言はセクションのはじめでなされるため、長いセクションの場合は、最後に定義される主要ワードと離れてしまい、利用できる局所変数や名前付きパラメターの状態がわかりにくくなる場合があります。そのような場合に備えて、コード内
コメントの形で最後の主要ワードの定義の部分にも局所変数を注記しておくのがよいでしょう。例えば、
...
...
...
:LOC MyLocalSect \ { parm1 parm2 \ loc1 loc2 -- }
inword3 inword4 [コード5] ;LOC
のような感じですね。
テンポラリオブジェクトの定義も簡単で、ローカルセクションを始めるところ、局所変数の宣言の後に、普通のワード定義内でテンポラリオブジェクトを宣言する場合のように"TEMP{ }"で囲って、オブジェクトを宣言すればいいだけです。例えば、
LOCAL MySect2 { \ loc1 -- }
TEMP{ String Str1 }
...
...
:LOC MySect2 ... ;LOC
改行の仕方なども、普通のテンポラリオブジェクトのやり方です。ここで宣言されたオブジェクトは、セクション内では自由にメッセージを送ることができ、値は維持されます。また、このオブジェクトには、このセクションの処理を抜けるときに、"Release:"メッセージが送られます。ですから、このセクション内でヒープデータを動的に生成していたとしても、適切な"Release:"メソッドが定義されているなら(自作のクラスの場合には注意)、領域の解放の有無とかを気に病む必要はありません。つまり、普通のテンポラリオブジェクトと同じですね。
ローカルセクションは、局所変数(含む名前付きパラメター)か、テンポラリオブジェクト(可能として)のどちらか一方だけを持つこともできます。が、どちらも持たないということはできません。コンパイル時にエラーになります。意味がありませんからね、どっちもないんじゃ。
関連項目:
最終更新:2019年06月17日 14:28