ローカル変数は以下のように定義できます
{: 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 では、コロン定義内のあらゆる場所でローカル変数を定義できます。 これにより、 以下のような疑問が生じます: