1. 程式人生 > >Forth 文本解釋程序

Forth 文本解釋程序

編譯 width 結束 循環 gin 數值 回車 word lse

FORTH 中有一組用戶變量,由這組變量記錄和保存程序的運行環境。DP 指向詞典區的下一個可用地址。SP0 指向參數堆棧的起點。RP0 指向返回堆棧的起點。
SP@ (- addr) 參數堆棧指針
SP! ( n - ) 把參數堆棧指針設置成規定的數值
RP@ (- addr) 返回堆棧指針
RP! (n - ) 把返回堆棧指針置為規定的數值

: QUIT FORTH 的主要循環。接收來自終端的輸入並解釋執行,如果成功則顯示“ok”. SP0 @ ' TIB ! 置終端輸入緩存區在參數堆棧上方。 BLK OFF 令 BLK 為0,處理來自終端的輸入。 [COMPILE] [ 令 STATE 為0,使系統處於解釋狀態。 BEGIN 進入 FORTH 主要循環。 RP0 @ RP! STATUS 初始化返回堆棧指針。送出一個回車換行。 QUERY 催促使用者從終端輸入下一行並將輸入行傳送到 TIB 中。 RUN 處理所接收的行。 STATE @ NOT 如果 STATE 為0,系統處於執行狀態。 IF ." OK" THEN 顯示出信息"ok"。 AGAIN ; 無窮循環:一行處理完畢後要求得到下一行。
: RUN ( - ) 改進了的解釋程序,運行分行輸入一個冒號定義。 STATE @ IF 若 STATE 不為0。系統必須處於編譯狀態。 ] 調用編譯程序。 STATE @ NOT 編譯完一源行後再次檢查 STATE 之值。 IF INTERPRET THEN 系統已脫離了編譯狀態,那麽就執行該行的剩余部分,否則退出。 ELSE INTERPRET STATE 為0,執行命令 THEN ;
RUN 的過程就是: IF 編譯 ELSE 執行 THEN ;


: INTERPRET ( - ) forth 解釋程序循環:分離出輸入流中的詞,如果它在詞典中有定義,則執行之。否則將其轉換為一個數字並放置到參數棧上。
BEGIN
?STACK 檢查堆棧有無上溢或下溢
DEFINED 取出輸入流中的下一個詞,返回它的 cfa 及一個標誌
IF EXECUTE 如果該詞已被定義,則執行
ELSE NUMBER 否則轉換成為一個數字
DOUBLE? 它是一個雙精度數嗎?
NOT IF DROP THEN 不是就丟棄它的高 16 位,僅保留低 16 位
THEN
FALSE 在堆棧上為 DONE? 留下一個 FALSE;解釋程序死循環,一直在運行
DONE? 到了行的末端了?
UNTIL ; 如果已到行結束處,退出循環;否則再次循環去處理下一詞。
   // DEFINED 首先取出輸入流中的下一個詞並把它放到詞緩沖區中,然後再詞典中搜索該詞,若該詞在詞典中存在,則把它的 cfa 放在堆棧上,並在其後跟上一個為真標誌。然後就是 EXECUTE 接過堆棧上的 cfa 執行該定義。如果該詞不在詞典中,控制程序就傳給命令 NUMBER ,以期待把緩沖區中的字符串轉換成為一個數字。      在循環開始處 ?STACK 檢查堆棧是否有溢出發生。若有溢出系統就被迫轉去執行 ABORT,於是一切就從新開始。如果在數字轉換過程中遇到錯誤,系統也同樣轉去 ABORT 處執行。這兩種情況就是非正常脫離解釋循環的條件。
: ?STACK ( - ) 檢查參數堆棧是否上溢或下溢,若溢出則控制返回終端。
SP@ 取出現行堆棧指針的值
SP0 @ 取出棧底的位置
SWAP U< 檢查是否下溢
ABORT" STACK Underflow" 若下溢則執行 ABORT"
SP@ PAD PAD 之值同時也是參數棧頂的上限
U< 檢查是否上溢
ABORT" Stack Overflow" ; 若上溢則也執行 ABORT"

      FORTH 工作的主要輪廓是一個二重循環:外循環是 QUIT 循環;內循環是 INTERPRET 循環。FORTH 啟動後即執行 QUIT ,QUIT 選擇終端作為輸入設備,調用 QUERY 等待使用者從鍵盤輸入一命令行。輸入行送至終端輸入緩沖區後,QUIT 調用 RUN 處理已接收進來的命令行。RUN 有兩個分支:若系統處於編譯狀態,則 RUN 調用編譯程序對所接收的源行進行編譯,當從鍵盤上鍵入一個冒號開頭的定義時,就進入 RUN 的這一個分支;若系統處於解釋狀態(又叫執行狀態),則調用解釋程序 INTERPRET 。INTERPRET 調用 DEFINED ,DEFINED 有兩個任務:檢測出輸入流中下一個詞並把它復制到詞典緩沖區( WORD);再詞典中搜索放在詞緩沖區中的詞( FIND )。// WORD 首先調用 PARSE-WORD ,PARSE-WORD 能夠確定輸入流來自哪一個輸入緩存區。因此文本解釋程序不僅僅能處理來自終端的源行,而且能夠處理來自磁盤塊的源行。輸入流不能輸入太多字符,如果輸入流耗盡,FORTH 就退出 INTERPRET 循環而回到 QUIT 外循環。

Forth 文本解釋程序