• 沒有找到結果。

第四章 解碼器相關指令

4.5 編碼器(COMPILER)相關指令

編碼器指令

FORTH ENGINE 中的解碼器和編碼器是一對孿生兄弟,他們用相同的 QUIT 機制,接受終端機輸入的文字序列。用相同的解讀指令 PARSE 分解出 指令字串,再由指令字串去查字典。不同的是當解碼器找到了指令時即去 執行,而編碼器找到指令時,不會直接執行,而是將指令的執行碼欄地址,

編入字典邊界頂端所正在定義的新指令中。新指令建造完成後,在被點名 執行時,編入的執行碼就會被依序執行了。

在 EVAL 的迴路中有一段是 'EVAL @EXECUTE,即將 'EVAL 變數中所存的地址 叫出來執行。解碼器工作時,'EVAL 中所存的是 $INTERPRET 指令的執行碼 欄地址,若是編碼器在工作,'EVAL 中存的則是 $COMPILE 的執行碼欄地址。

改變 'EVAL 中所存的地址,就會讓 FORTH ENGINE 或做編碼的工作,或做解 碼的工作。

$COMPILE ( a -- )

根據 a 區中的名稱字串查字典。若找到與名稱字串相符的指令,即將此指 令的執行碼地址,編入字典邊界頂端正在定義的新指令中。但假若此指令 名稱欄中最高位($800000)不是零,這個指令即屬立即執行【Immediate】

類,這類指令會隨即被執行而不被編碼。若字串不是一個指令,則將它當 作數值轉換,而將數值以 Literal 形式編入新指令。若不是指令,也不是 數字,則跳到 ERROR,處理此錯誤情況。

LITERAL( n -- )

是數碼指令,在新指令中編入 LIT 機器碼,然後接著編入數碼。當新 指令執行到 LIT 時,會將其後編入的數碼取出放在堆疊上。這是 FORTH ENGINE 程式中產生數值,並將它放上堆疊的唯一方法。

編碼器最核心的工作是由 $COMPILE 完成的。所做編碼的工作,即是在字典 上建造新的指令。這是相當複雜的工作,須要一系列下述編碼器的輔助指 令,才能圓滿達成完整的編碼工作。

$,n ( a -- ) 在字典邊界的頂端建造一個新指令的連接欄和名稱 欄。建名稱欄時,將在位址 a 的名稱字串壓縮後塞入 名稱欄中。

?UNIQNE ( a – a ) 用位址 a 的字串查字典,看其中是否已有相同名稱的 指令。若有,則印出「Redef」的警告訊號。

$," ( -- ) 在新指令的定義中編入一個字串,此字串是以 ” 號 結束的。

LITERAL ( n -- ) 在新指令中編入一個數碼指令 LIT,然後編入數碼 n,

將來在程式執行到此指令時,n 會被取出放在堆疊上。

COMPILE ( -- ) 將程式中此指令後面所編入的指令取出,編入現在定 義的新指令中。

[COMPILE] ( -- ) 此屬立即執行指令。它會尋找下一字串文字所代表的 指令,並將其地址以 CALL 的指令形式,編入字典邊界 頂端正定義的新指令中。

, ( n -- ) 此逗點指令,乃是將堆疊上的一個數值 n 編入字典邊 界頂端正在定義的新指令中。

ALLOT ( n -- ) 將字典指標 CP 增加 n,給正定義的新指令留下 n 個字 碼的空間。

' ( -- a ) 此單引號指令,尋找下一字串所代表的指令,找到後 將其執行碼欄地址留在堆疊。找不到與名稱相符的指 令,則會顯示錯誤信號。

OVERT ( -- ) 編造新指令成功後,將這新指令的名稱欄加入字典的 串連鏈列表中。以後查字典,即可在此串連鏈中找到 這個新指令。

: ( -- ) 開始定義一個新指令。用下一字串做為新指令的名 稱,建造一個連接欄及名稱欄。

( -- ) 結束一個新指令的定義。在此新指令的機器碼最後,

追加編入一個 RET 的機器碼,並用 OVERT 把這新指令 加入字典的串連鏈。

] ( -- ) 將 $COMPILE 的執行碼欄地址存入 'EVAL 中。以後即 讓此編碼器處理所輸入文字序列中的指令字串。

表 4-6 編碼器(COMPILER)相關指令

$Compiler

NAME?

Compiler token NUMBER

OK?

EXIT

Print error message

QUIT no

yes no

Compiler a

literal yes

圖 4-5 $COMPILER LOOP

相關文件