1. 程式人生 > >Forth 文字解釋程式

Forth 文字解釋程式

      FORTH 中有一組使用者變數,由這組變數記錄和儲存程式的執行環境。 DP 指向詞典區的下一個可用地址。SP0 指向引數堆疊的起點。RP0 指向返回堆疊的起點。
[email protected] (- addr) 引數堆疊指標
SP!  ( n - ) 把引數堆疊指標設定成規定的數值
[email protected] (- addr) 返回堆疊指標
RP! (n - ) 把返回堆疊指標置為規定的數值

:  QUIT     F ORTH 的主要迴圈。接收來自終端的輸入並解釋執行,如果成功則顯示“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      ( - )          檢查引數堆疊是否上溢或下溢,若溢位則控制返回終端。
        [email protected]                      取出現行堆疊指標的值
        SP0  @                  取出棧底的位置
        SWAP  U<            檢查是否下溢
        ABORT"  STACK Underflow"                若下溢則執行 ABORT"
        [email protected]  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 外迴圈。