STATEの切り替え

"State"というのは、Mopsの実行モードのことです。既出ですが、一応説明すると、コンパイル状態か、解釈状態かを識別するものです。具体的には、コロン定義とメソッド定義の中はコンパイル状態、その外、とくに地の部分が解釈状態です。

通常は、コロンやセミコロンを通じて自動的に状態は切り替わりますが、例えば、コロン定義の中であっても、定義を終了させることなく、一時的にコンパイル状態を解釈状態に切り替えたいというときが、場合によっては起こりえます(どのような場合かは、別のページに現れるでしょう)。

この状態を切り替えるワードとして、"["と"]"があります。角括弧は、メソッドの動的束縛のときなど、色々な場面で使われていますが、もっとも正式な(つまり、Forth標準の)意味は、状態の切り替えです。Mopsでは文脈によって働きが変わるように仕組まれているのです。このように、ひとつのワード(名前)や記号に複数の働きを結びつけることは、一般に、オーバーロードといいます。直訳すると"超過負担"とか、まあ、更に追加して荷を背負わせるというような語感ですかね。オーバーライドと紛らわしいというのがよく話題になります(^^;;)。

左角括弧"["はコンパイル状態を解釈状態に切り替えます。右角括弧"]"はその逆、つまり、解釈状態をコンパイル状態に切り替えます。そんなわけで、例えばコロン定義の中で、"[ ]"で囲った部分をつくると、そのワード定義をコンパイルしているとき、その括弧中は解釈状態になるわけです。あまり意味の無い例ですが、
: WORD1  dup [ 3 4 + . ] *   ;
というようなワード定義をロード(Mopsに書いてENTER)すると、コンパイル終了後、7がプリントされるはずです。"WORD1"自体の定義内容は、スタック上の数値を2乗するだけです。つまり、角括弧で囲まれた部分は、解釈状態になりますから、ロード時に実行され、完了してしまうわけで、WORD1の定義内容にはならない、ということです。ワード定義の"ハラキリ"みたいなもんでしょうか…

数値をプリントしたのは、ワード定義のコロンとセミコロンがきちんとかみ合っているかどうかを検証するためにコロンがワードコンパイル時にスタックを使っているので、スタックに勝手な値を残してしまうと対応が確認できなくなるからです。Mops/Forthでは、コンパイルもそれ用のワードの解釈実行として行われることを想起しましょう。つまり、言いたいことは、複雑なコード(特に条件構造内など)の中で状態を切り替えて値を操作するのは、マーカー値などを攪乱してしまう危険があるので、控えましょう、ということです。普通、この状態の切り替えは、コンパイル時点でのある変数の値を取っておいて実行時に使うという目的のために利用されます。その際には、"LITERAL"というワードと一緒に使われることになります。"LITERAL"というワードの動作は、少し変わっていて、コンパイル時には、その時点でのトップスタックの値をひとつ消費して格納し(Immediate)、実行時には、その値をスタックに置きます。例えば、
5 value myvalue
: WORD2   [ myvalue 4 + ] LITERAL  ;
と定義すると、WORD2は実行時には、"9"をスタックに残すでしょう。つまり、"WORD2"のコンパイル時に"[]"内の計算は実施され、それが"LITERAL"によって格納されます。実行時には、その格納された値が、"LITERAL"によって返されるのです。

"STATE"はMopsでは普通のValue変数ですから、自分で"True"や"false"を格納して操作することも可能です。しかし、それはすべきではないと思います。大域変数なわけですから、勝手にいじって戻すのを忘れたりするとおかしなことになりかねません。アプリケーションプログラミングのレベルでは切り替えのためのワードを経由して自動的に変更するようにし、"STATE"を直接使うにしてもせいぜい値を参照するに止めるのが適切な使い方であると思われます。

補遺:条件コンパイル


角括弧を用いてワードの定義内容の一部を条件に応じて変えることができます。例えば、
: WORD2  コード1
  [ 条件値 ]
  [IF]
     コード2
  [ELSE]
     コード3
  [THEN]
  コード4   ;
のようにすると、"WORD2"の内容は、条件値が真(非0)であるときには、"コード1 コード2 コード4"となり、条件値が偽であるときには、"コード1 コード3 コード4"となります。


関連項目:






最終更新:2018年12月25日 14:41