ローカル変数は以下のように定義できます
{: local1 local2 ... -- comment :}
or
{: local1 local2 ... :}
or
{: local1 local2 ... | ulocal0 ulocal1 -- comment :}
例えば、 以下のように使います
: max {: n1 n2 -- n3 :} n1 n2 > if n1 else n2 endif ;
ローカル変数定義とスタック・コメントは、 類似するよう意図しています。 ローカル変数定義は、 多くの場合、 ワードのスタック・コメントを置き換えます。
ローカル変数の順序はスタック・コメント内の順序に対応し、 --
以降はすべて実際はコメントです。
この類似性には 1 つ欠点があります。 ローカル変数宣言とスタック・コメントを混同しやすく、 バグが発生し、 見つけにくくなります。 ただし、 この問題は適切なコーディング規約によって回避できます。 同じプログラム内で両方の表記法を使用しないでください。 そうする場合は、 追加の手段を使用して区別する必要があります。 例えば、 場所によって区別します。
ローカルの名前の前に型指定子を付けることができます。 たとえば、浮動小数点値の場合は F:
です:
: CX* {: F: Ar F: Ai F: Br F: Bi -- Cr Ci :} \ 複素数の掛け算 Ar Br f* Ai Bi f* f- Ar Bi f* Ai Br f* f+ ;
Gforth は現在、 セル型指定子(W:
, WA:
, W^
)や、 2倍長整数型指定子(D:
,
DA:
, D^
)や、 浮動小数点数型指定子(F:
, FA:
, F^
)と、
さまざまなフレーバーの xt 型指定子(xt:
, xta:
)、 をサポートしています:
(see Values) valueフレーバーのローカル変数(W:
、 D:
などで定義)はその値を生成し、
TO
で変更できます。
(see Varues) varueフレーバーのローカル変数 foo (WA:
などで定義) は、 addr
foo
を使用してアドレスを取得できること(変数のスコープを離れると無効になります)を除いて、
valueフレーバーのローカル変数とまったく同じように振る舞います。 現時点ではパフォーマンスに違いはありませんが、 長期的には、
valueフレーバーのローカル変数はレジスターに常駐できるため、 大幅に高速になるでしょう。
(see Variables) variableフレーバーのローカル変数(W^
などで定義)はそのアドレスを生成します(変数のスコープを離れると無効になります)。 たとえば、 標準のワード emit
は、
以下のように variableフレーバーのローカル変数(C^ char*
) と type
で定義できます:
: emit {: C^ char* -- :} char* 1 type ;
(see Deferred Words) (XT:
または XTA:
と指定した) defer
フレーバーのローカル変数 xt を execute
します。 action-of
を使用すると、 defer
フレーバーのローカル変数から xt を取得できます。 ローカル変数が xta:
で定義されている場合、 addr
を使用して、 xt が保存されているアドレス(ローカル変数のスコープの終わりまで有効)を取得できます。 たとえば、 標準のワード
execute
は、 以下のように defer フレーバーのローカル変数で定義できます:
: execute {: xt: x -- :} x ;
型指定子のないローカル変数は W:
ローカル変数として扱われます。 以下を使用して addr
の使用を許可または禁止できます:
default-wa:
( – ) gforth-experimental “default-wa:”
型指定子なしで定義されたローカル変数で addr
を許可します。 言い換えれば、 型指定子無しでローカル変数定義したときは
wa:
型指定子を指定したのと同じです
default-w:
( – ) gforth-experimental “default-w:”
型指定子なしで定義されたローカル変数では addr
を禁止します。 言い換えれば、 型指定子なしで定義されたローカル変数は
w:
型指定子を指定してローカル変数を定義したのと同じです。
|
の後ろで定義されたローカル変数を除いて、 ローカル変数の全てのフレーバーは、 データ・スタックの値または、 (FP
ローカル変数の場合) FP スタックの値で初期化されます。 Gforth は |
の後ろで定義されたローカル変数を 0 に初期化します。
一部の Forth システムでは初期化されないままになっています。
Gforth は、 ローカル・バッファーとデータ構造体のための角括弧(square bracket)表記をサポートしています。 これらのローカル変数は
variableフレーバーのローカル変数に似ており、 サイズは定数式として指定します。 宣言は name[ size ]
のようになります。 Forth の式 size
は宣言中に評価され、 サイズをバイト単位で指定するスタック効果 (
-- +n )
が必要です。 なお、 角括弧 [
は定義された名前の一部です。
ローカルのデータ構造体は、 データ・スタックに渡されたアドレスから size バイトをコピーすることによって初期化されます。 (宣言内の
|
の後の、)初期化されていないローカルのデータ構造体は消去されず、 以前にローカル・スタックにあったデータをすべて含むだけです。
Example:
begin-structure test-struct field: a1 field: a2 end-structure : test-local {: foo[ test-struct ] :} foo[ a1 ! foo[ a2 ! foo[ test-struct dump ;
Gforth では、コロン定義内のあらゆる場所でローカル変数を定義できます。 これにより、 以下のような疑問が生じます: