1. 程式人生 > >Forth 採用Create,Does>定義新的詞(word)& 延遲詞技術

Forth 採用Create,Does>定義新的詞(word)& 延遲詞技術

   程式碼指標域中包含有一個 程式段的地址,每當一個定義被引用時該程式段就首先被執行。因此,又稱 該程式段為執行時間程式碼不同型別的定義具有不同的執行時間程式碼。執行時間程式碼決定了一個詞的類別,決定了該詞的特性及如何對待和處理放在該詞引數域中的資料。    三種不同型別的定義,常數、變數和冒號定義。CONSTANT、VARIABLE 和 冒號定義 可以給詞典增加新詞,所以又把它們稱為 定義詞。   
  如果由程式碼指標域所指著的執行時間程式碼是由彙編程式碼來定義的,則定義一個新的定義詞的格式是: : 新定義詞名 CREATE ... ;CODE 彙編程式碼
其中彙編程式碼是由彙編助記符編寫的程式段。   如果執行時間程式碼是由冒號定義規定的話: : 新定義詞名 CREATE ... DOES> ... ; CREATE 使用輸入流中下一個字串作為名字在詞典中建立一個入口,CREATE 後面的內容規定詞典中如何編譯一個新的定義,DOES> 後面的內容規定新定義的執行時間程式碼。
// 定義一個 雙字長常數
: DCONSTANT   CREATE , , DOES> DUP 2 + @ SWAP @ ;
123.456 DCONSTANT CON1

CON1 D.    






執行時間行為:       任何由 CREATE 所創立的詞的“預設”的 執行時間程式碼行為是返回其詞身的地址。而詞身在詞典中的大小,格式及最初的內容則是由定義詞在編譯階段的行為決定的,也就是定義詞中跟隨在 CREATE 之後的詞決定。        CREATE  名稱   生成<名稱>的詞典專案。在<名稱>生成之後,下一個可利用的詞典單元就是<名稱>的引數域中的第一個位元組,隨後執行<名稱>時,<名稱>的引數域中的第一個位元組的地址被留在堆疊中,CREATE並不給<名稱>的引數域分配空間。       CREATE  定義的詞的程式碼指標CFA就是CREATE的執行時間程式碼,當定義的詞被執行時,把潛在的引數域(PFA)地址壓棧。       DOES>  執行時間:標誌它的編譯部分的結束和執行時間的開始。執行時間的操作由高階形式 FORTH 編寫。在執行時間,被定義的詞的引數域地址壓棧。





延遲詞:     當一個冒號定義被引用時,組成該冒號定義的各個詞就被順序執行。即詞典中一個冒號定義的功能是固定不變的。    定義這樣的詞,定義它的時候勿需確定它的功能;這種在編譯時不規定功能,其功能延遲到以後再規定的詞叫做延遲詞。FORTH 中用 DEFER 來定義。
: DEFER  ( - )          (建立一個延遲詞)  
              CREATE       (建立延遲詞首部)
              2 ALLOT      (引數域為一個單元)
              DOES> @ EXECUTE ;      (執行時間程式碼)
當定義詞 DEFER 執行時,在詞典中建立一個詞身位一個單元的延遲詞,並規定延遲詞的執行時間程式碼;當延遲詞執行時,把其 pfa 單元內的地址交給 EXECUTE 執行。
    // 這個自己定義的延遲詞有兩個缺點:一是已定義的延遲詞的 pfa 單元是“空的”;如果執行的時候忘記給這個空單元填入一個編譯地址,則程式執行到這個延遲詞時就無法再繼續執行下去;二是這個的執行時間是由高階定義規定,因此執行速度不夠快。
: WARNING  ." Uninitialized" ;
: DEFER  CREATE ['] WARNING , DOES> @ EXECUTE ;
// 這樣定義防止DEFER定義詞未賦值麼有執行程式碼無法繼續執行下去

為了簡化規定延遲詞的功能的工作(即把某一個定義的編譯地址填入延遲詞的 pfa 單元)所用到的定義是 IS : :  IS  ( cfa - )   '  >BODY  !  ;  把跟著的詞的 pfa 單元置為引數棧頂的地址。 上面的操作可以這樣寫 //為了能在冒號定義內部也能使用 IS ,把 IS 的定義改進如下:
STATE  ( - addr)  具有編譯狀態的變數。STATE 之值非 0 ,表明系統處於編譯狀態;為零,則表明系統處於解釋(執行)狀態。  
:  (IS)   ( cfa -  )   ( IS的執行時間行為)   [email protected]  @  >BODY  !  (得到目標地址) R>  2+  >R  ;  ( 調整 IP )
:   IS   ( cfa -  )             把跟著的詞身(pfa)置為引數棧頂的數值。若在冒號定義內使用,則IS作用於在冒號定義中跟著它的詞。
      STATE  @       
      IF  COMPILE  (IS)   系統處於編譯狀態則做此工作。
      ELSE '  >BODY  !      系統處於解釋狀態做此工作。
      THEN 
      ;   IMMEDIATE   由於 IS 在冒號定義內部也要能使用,所以它必須是立即詞。