石原 博の覚書

電子工作に関する日々の覚書を記載します

Forthのコンパイラ(CREATE DOES>)

2021-06-13 13:53:53 | 日記
Forthの面白いところは、CREATE DOES>などのコンパイル用のワードである。

例えば変数定義用のワードは以下のように定義出来る
: VAR CREATE 0 , DOES> ;

使い方は VAR ABC とすれば、ABCというワードが定義されて、
ABC 123(2022/10/1修正) 123 ABC ! で変数ABCに123を代入、 ABC @ で変数ABCから値を取り出すことが出来る。

    : VAR CREATE   0 ,   DOES>   ;
VARコンパイル時     ^^^^
 VAR実行時               ^^^


例えば定数定義用のワードは以下のように定義出来る
: CONST CREATE , DOES> @ ;

使い方は 123 CONST ABC とすれば、ABCというワードが定義されて、
ABC で値を取り出すことが出来る。

    : CONST CREATE   ,   DOES>  @ ;
CONSTコンパイル時     ^^^
 CONST実行時              ^^^


実はF83内部での定義はもっと直接的で、以下のとおり。


: VARIABLE CREATE  0 ,   ;USES DOCREATE , ;
コンパイル時         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                定義しているワードのCFAに DOCREATEを代入

: CONSTANT CREATE    ,    ;USES DOCONSTANT , ;
コンパイル時         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                定義しているワードのCFAに DOCONSTANTを代入



CREATEを使えばもっと色々なことが出来る。
CREATE TEST ' + , ' - , ' * , ' / ,
5 2 0 TEST SWAP 2* + PERFORM 結果⇒7
5 2 1 TEST SWAP 2* + PERFORM 結果⇒3

もっとちゃんとしたコードにすると、
: OP CREATE COMPILE + COMPILE - COMPILE * COMPILE / DOES> SWAP 2* + PERFORM ;
OP TEST
5 2 0 TEST 結果⇒7
5 2 1 TEST 結果⇒3

さらに、面倒なので変形すると
: OP: CREATE ] DOES> SWAP 2* + PERFORM ;
OP: TEST + - * / ;
5 2 0 TEST 結果⇒7
5 2 1 TEST 結果⇒3

F83には、この発展形である CASE: があります。