- 追加された行はこのように表示されます。
- 削除された行は
このように表示されます。
前回、[[Forthを作ってみる / 変数を実装する]]によって、変数の番地をスタックにPUSHできるようになった。
次は、変数の実体に対してアクセスできるようにする。
変数へのアクセスには、"@"と"!"を用いる。
@ 変数の値の参照 (addr -- x)
! 変数への値の代入 (x addr -- )
変数yの値を参照するには、
y @
変数yへ値5を代入するには、
5 y !
のように書く。
まず@の(実行時の)実装について考える。
プログラム実行時、@の中間コード(CODE_AT)が現れたら、
*すでにスタックに積まれているはずの、変数の番地addrを取り出す
*その値は、var[ ]のインデックスであるので、var[addr]の値をスタックに積む
次に!の(実行時の)実装について考える。
プログラム実行時、!の中間コード(CODE_EXCL)が現れたら、
*すでにスタックに積まれているはずの、変数の番地addrを取り出す
*すでにスタックに積まれているはずの、代入値valを取り出す
*addrは、var[ ]のインデックスであるので、var[addr]にvalを代入する
プログラムを書いてみよう。
コードに"@"と"!"が現れたときの処理をparse()に追加する。
} else if (strcmp(token, "@") == 0) {
prog[parse_idx] = CODE_AT;
parse_idx++;
} else if (strcmp(token, "!") == 0) {
prog[parse_idx] = CODE_EXCL;
parse_idx++;
参照と代入の処理関数。
/**
* 変数を参照し、スタックに積む
*/
void call_var_load(void)
{
/* 変数の番地を取り出す */
long addr = pop();
/* 変数の値をスタックに積む */
push(var[addr]);
}
/**
* 変数に値を代入する
*/
void call_var_store(void)
{
/* 変数の番地を取り出す */
long addr = pop();
/* 代入値を取り出す */
long val = pop();
/* 変数に値を代入する */
var[addr] = val;
}
関数ポインタ配列に上記関数を追加する。
void (*jump_table[])(void) = { /**< ワードのジャンプ先テーブル */
NULL, call_push, plus, print, word_if, word_else, word_then, call_do, call_loop, call_i,
call_cr, call_word, proc_ret, call_dotquote, call_varadr, call_var_load, call_var_store
};
テストコードで動作を確認する。
variable x
5 x !
x @ . cr
variable y
10 y !
y @ . cr
実行する。
$ ./moiforth.exe testfile/test10
5
10
できた。
[ソースコード|http://www.moi2.sakura.ne.jp/fswiki/wiki.cgi?page=Forth%A4%F2%BA%EE%A4%C3%A4%C6%A4%DF%A4%EB+%2F+%CA%D1%BF%F4%A4%F2%BC%C2%C1%F5%A4%B9%A4%EB2&file=moiforth%2D0%2E11%2Ezip&action=ATTACH]
(2011.01.10)
[[戻る|Forthを作ってみる]] [[前へ|Forthを作ってみる / 変数を実装する]] [[次へ|Forthを作ってみる / 最後に]]
:Amazonリンク:[Thinking Forth|http://www.amazon.co.jp/gp/product/0976458705?ie=UTF8&tag=moi0e-22&linkCode=as2&camp=247&creative=7399&creativeASIN=0976458705]
{{adsence}}
:姉妹サイト:[moiのコンピュータを作る|http://moi5.wiki.fc2.com/]