Forth systems are unusually simple to develop, in comparison with compilers for more conventional languages such as C. In addition to Forth systems supported by vendors, public-domain implementations and implementation guides have been widely available for nearly twenty years, and a large number of individuals have developed their own Forth systems. As a result, a variety of implementation approaches have developed, each optimized for a particular platform or target market.
X3J14 技術委員會已經盡力用強迫實作者的方式去調整這些多樣性, 用一個定義標準介面的目標來讓統一底層的 Forth 系統和一個被發展在其上的應用程式.
The X3J14 Technical Committee has endeavored to accommodate this diversity by constraining implementors as little as possible, consistent with a goal of defining a standard interface between an underlying Forth System and an application program being developed on it.
相似地, 我們將不會在這一節著手告訴你如何去實作一個 Forth 系統, 而將會提供一些指導如可以適當地宣稱遵守標準的系統最小需求.
Similarly, we will not undertake in this section to tell you how to implement a Forth System, but rather will provide some guidance as to what the minimum requirements are for systems that can properly claim compliance with this Standard.
Most computers deal with arbitrary bit patterns. There is no way to determine by inspection whether a cell contains an address or an unsigned integer. The only meaning a datum possesses is the meaning assigned by an application.
當工作於資料之上時, 這個結果的意義是依照於輸入值. 有些輸入值的合併產生了無意義的結果; 例如, 什麼意義可以被指定給字元 A 的 ASCII 表示法和一個 TRUE 旗標的算術總和? 這個答案可以是 無意義; 或是替換地, 這項操作可以是產生一個檢查碼的第一步. 上下文是決定的東西.
When data are operated upon, the meaning of the result depends on the meaning assigned to the input values. Some combinations of input values produce meaningless results: for instance, what meaning can be assigned to the arithmetic sum of the ASCII representation of the character A and a TRUE flag? The answer may be no meaning; or alternatively, that operation might be the first step in producing a checksum. Context is the determiner.
當一個程式可以指定位元模型的多種組合時, 限定意義的規定有時叫做資料分派. 許多電腦語言強制施行明白的資料分派, 並且讓編譯器來避免不合定義的操作.
The discipline of circumscribing meaning which a program may assign to various combinations of bit patterns is sometimes called data typing. Many computer languages impose explicit data typing and have compilers that prevent ill-defined operations.
Forth 罕有地明白強制施行資料型別的限制. 然而, 資料型別絕對性確時存在, 而且規定是需要的, 尤其是程式的可移植性是一個目標時. 在 Forth 中, 它是依靠於程式設計師 (而不是編譯器) 來決定資料精確的分類.
Forth rarely explicitly imposes data-type restrictions. Still, data types implicitly do exist, and discipline is required, particularly if portability of programs is a goal. In Forth, it is incumbent upon the programmer (rather than the compiler) to determine that data are accurately typed.
這一節嘗試提供關於在 Forth 中實際上的資料型別的指導.
This section attempts to offer guidance regarding de facto data typing in Forth.
The correct identification and proper manipulation of the character data type is beyond the purview of Forth's enforcement of data type by means of stack depth. Characters do not necessarily occupy the entire width of their single stack entry with meaningful data. While the distinction between signed and unsigned character is entirely absent from the formal specification of Forth, the tendency in practice is to treat characters as short positive integers when mathematical operations come into play.
1) 字元資料型別的儲存單元 (C@, C!, FILL, 等等.) 必須能夠包含從 0 到 255 的無號整數數目.
1) The storage unit for the character data type (C@, C!, FILL, etc.) must be able to contain unsigned numbers from 0 through 255.
2) 一個實作不需要限制字元儲存到這個範圍, 但是一個沒有環境相依性的程式不能假定在一個 字元 位置儲存在這個範圍之外數目的能力.
2) An implementation is not required to restrict character storage to that range, but a Standard Program without environmental dependencies cannot assume the ability to store numbers outside that range in a char location.
3) 允許的數字表示法是二補數, 一補數, 和符號量值. 注意所有這些數字系統同意正數數字的表示.
3) The allowed number representations are two's-complement, one's-complement, and signed-magnitude. Note that all of these number systems agree on the representation of positive numbers.
4) 由於一個 字元 可以儲存小正數而且由於字元資料型別是無號整數資料型別的子範圍, C! 必須儲存一個單元的 n 個最低有效位元 (8
<= n <= 位元/單元). 給予允許數目表示法的一覽表和它們已知的編碼, TRUE xx C! xx
C@ 必須留下有一些數目的位元設定的一個堆疊元素, 它將因此被 IF
接受為非零.
4) Since a char can store small positive numbers and since the
character data type is a sub-range of the unsigned integer data type, C! must
store the n least-significant bits of a cell (8 <= n <= bits/cell).
Given the enumeration of allowed number representations and their known
encodings, TRUE xx C! xx C@ must leave a stack item with
some number of bits set, which will thus will be accepted as non-zero by IF.
5) 對於輸入的目標 (KEY, ACCEPT, 等等.) 和輸出 (EMIT, TYPE, 等等.), 在數字和人類可讀的符號之間的編碼是在 32 到 126 範圍 (空白到 ~) 的 ISO646/IRV (ASCII). EBCDIC 出局了, (大部分的 EBCDIC 電腦系統也支援 ASCII). 在這個範圍之外, 它是依據實作而定. 顯然地實作的選擇是使用從 0 到 31 的 ASCII 控制字元, 至少是在這個範圍的 可顯示的 字元 (TAB, RETURN, LINEFEED, FORMFEED). 然而, 沒有像它們看起來得這麼清晰, 因為作業系統對於這些字元的對待方式不同. 例如, 有些系統 TAB 是 4 個字元的邊界, 其他的是 8 個字元的邊界, 另外的預先設定 tab 停止位置. 有些系統在一個 carriage return 後進行一個自動的 linefeed, 其他的在一個 linefeed 後進行一個自動的 carriage return, 另外的什麼都不做.
5) For the purposes of input (KEY, ACCEPT, etc.) and output (EMIT, TYPE, etc.), the encoding between numbers and human-readable symbols is ISO646/IRV (ASCII) within the range from 32 to 126 (space to ~). EBCDIC is out (most EBCDIC computer systems support ASCII too). Outside that range, it is up to the implementation. The obvious implementation choice is to use ASCII control characters for the range from 0 to 31, at least for the displayable characters in that range (TAB, RETURN, LINEFEED, FORMFEED). However, this is not as clear-cut as it may seem, because of the variation between operating systems on the treatment of those characters. For example, some systems TAB to 4 character boundaries, others to 8 character boundaries, and others to preset tab stops. Some systems perform an automatic linefeed after a carriage return, others perform an automatic carriage return after a linefeed, and others do neither.
從 128 到 255 的碼可能最後被標準化, 正式地或非正式地, 用於國際的字元, 像是在許多歐州語言中可以找到的能區分的標記字元. 一個這樣的編碼是八位元的 ISO 拉丁-1 字元集. 電腦市場大致上將最後選擇佔優勢的編碼集中的字元. 對於在一個作業系統上執行的 Forth 實作而言 (這些日子它們大多數執行於標準平台), 大部分的 Forth 實作者將可能選擇系統做什麼, 而不在 Forth 的領域內進行任何的重新對映動作.
The codes from 128 to 255 may eventually be standardized, either formally or informally, for use as international characters, such as the letters with diacritical marks found in many European languages. One such encoding is the 8-bit ISO Latin-1 character set. The computer marketplace at large will eventually decide which encoding set of those characters prevails. For Forth implementations running under an operating system (the majority of those running on standard platforms these days), most Forth implementors will probably choose to do whatever the system does, without performing any remapping within the domain of the Forth system itself.
6) 一個標準的程式可以依靠透過 KEY 接收 32 ... 126 範圍的任何字元的能力, 並且相似地用 EMIT 來顯示相同的集合. 如果一個程式必須能夠接收或顯示在這個範圍之外的任何特別的字元, 它可以在這個接收或顯示那個字元的能力上宣告一個環境相依性.
6) A Standard Program can depend on the ability to receive any character in the range 32 ... 126 through KEY, and similarly to display the same set of characters with EMIT. If a program must be able to receive or display any particular character outside that range, it can declare an environmental dependency on the ability to receive or display that character.
7) 一個標準的程式不能在定義名稱中使用控制字元. 然而一個標準的系統不需要強制這個禁令. 因此, 目前允許從 BLOCK
來源的控制字元在詞的名稱中的已存在系統可以繼續運作. 在文字檔案來源中, 這個用空白作為一個分界符號的分析動作 (例如, BL WORD)
把控制字元當作是跟空白相同. 這有效地暗示你不能在文字檔案來源中使用控制字元, 因為這個文字解譯器將會把控制字元當作是分界符號. 注意這個
可摺疊的控制字元 只適用於當空白字元是分界符號時, 因此這個詞組 CHAR ) WORD
可以收集到一個包含控制字元的字串.
7) A Standard Program cannot use control characters in definition names.
However, a Standard System is not required to enforce this prohibition. Thus,
existing systems that currently allow control characters in words names from
BLOCK
source may continue to allow them, and programs running on those systems will
continue to work. In text file source, the parsing action with space as a
delimiter (e.g., BL WORD)
treats control characters the same as spaces. This effectively implies that
you cannot use control characters in definition names from text-file source,
since the text interpreter will treat the control characters as delimiters.
Note that this control-character folding applies only when space is the
delimiter, thus the phrase CHAR ) WORD may collect a
string containing control characters.
b) 儲存和恢復(Storage and retrieval)
c) 在堆疊上的操作(Manipulation on the stack)
In addition to C@ and C!, characters are moved to, from and upon the data stack by the following words:
d) 附加的操作(Additional operations)
The following mathematical operators are valid for character data:
下列的比較和位元操作對於字元可以是正確的, 記住在字元的高有效位元顯示的資訊是以一種實作自訂的方式, 必須可以遮蔽或以其他的方式處理:
The following comparison and bitwise operators may be valid for characters, keeping in mind that display information cached in the most significant bits of characters in an implementation-defined fashion may have to be masked or otherwise dealt with:
一個不需要分類的單一單元堆疊記錄, 是 Forth 的基本資料型別. 所有其他的資料型別是實際上以一個或多個單一單元堆疊記錄來表示.
A single-cell stack entry viewed without regard to typing is the fundamental data type of Forth. All other data types are actually represented by one or more single-cell stack entries.
Single-cell data are transferred from the stack to memory by !; from memory to the stack by @. All bits are transferred in both directions and no type checking of any sort is performed, nor does the Standard System check that a memory address used by ! or @ is properly aligned or properly sized to hold the datum thus transferred.
b) 在堆疊上的操作(Manipulation on the stack)
Here is a selection of the most important words which move single-cell data to, from and upon the data stack:
c) 比較操作子(Comparison operators)
A FALSE flag is a single-cell datum with all bits unset, and a TRUE flag is a single-cell datum with all bits set. While Forth words which test flags accept any non-null bit pattern as true, there exists the concept of the well-formed flag. If an operation whose result is to be used as a flag may produce any bit-mask other than TRUE or FALSE, the recommended discipline is to convert the result to a well-formed flag by means of the Forth word 0<> so that the result of any subsequent logical operations on the flag will be predictable.
附加於移動、取得、和儲存單一單元元素的詞, 下列的詞對於在一個或多個在堆疊上的旗標的操作是正確的.
In addition to the words which move, fetch and store single-cell items, the following words are valid for operations on one or more flag data residing on the data stack:
給予相同的位元, 無號整數通常能表示由有號整數所代表的值的絕對值的兩倍數目.
Given the same number of bits, unsigned integers usually represent twice the number of absolute values representable by signed integers.
一個單一單元資料可以被一個標準程式當作是一個無號整數. 搬移和儲存這樣的資料是進行於任何單一單元資料. 附加地, 下列的數學和比較運算元對於單一單元無號整數而言是正確的:
A single-cell datum may be treated by a Standard Program as an unsigned integer. Moving and storing such data is performed as for any single-cell data. In addition, the following mathematical and comparison operators are valid for single-cell unsigned integers:
UM* UM/MOD + +! - 1+ 1- * U< U>
An address is uniquely represented as a single cell unsigned number and can be treated as such when being moved to, from, or upon the stack. Conversely, each unsigned number represents a unique address (which is not necessarily an address of accessible memory). This one-to-one relationship between addresses and unsigned numbers forces an equivalence between address arithmetic and the corresponding operations on unsigned numbers.
數個運算元特別地提供於位址算術:
Several operators are provided specifically for address arithmetic:
並且, 如果浮點運算詞存在:
and, if the floating-point word set is present:
FLOAT+
FLOATS
SFLOAT+
SFLOATS
DFLOAT+
DFLOATS
一個標準程式可以永遠不需負責一個 Forth 位址和它對應的實際位址之間的特別對應關係.
A Standard Program may never assume a particular correspondence between a Forth address and the physical address to which it is mapped.
The trend in ANS Forth is to move toward the consistent use of the c-addr u representation of strings on the stack. The use of the alternate address of counted string stack representation is discouraged. The traditional Forth words WORD and FIND continue to use the address of counted string representation for historical reasons. The new word C" , added as a porting aid for existing programs, also uses the counted string representation.
計數字串作為一種儲存字串在記憶體中的方式而保持有用. 這種使用法是不被鼓勵的, 但是參考到這種出現在堆疊上的字串時, 使用 c-addr u 表示法是比較好的.
Counted strings remain useful as a way to store strings in memory. This use is not discouraged, but when references to such strings appear on the stack, it is preferable to use the c-addr u representation.
在一個執行記號和一個記號之間的關連是靜態的. 一旦造成後, 它不會在改變搜尋順序或任何其他事物時改變. 然而它不會是唯一的, 例如, 詞組
' 1+ 和 ' CHAR+可能傳回相同值.
The association between an execution token and a definition is static. Once made, it does not change with changes in the search order or anything else. However it may not be unique, e.g., the phrases
' 1+ and ' CHAR+might return the same value.
b) 在堆疊上的操作(Manipulation on the stack)
Additionally, these operators may be used to move cell pairs from, to and upon the stack:
c) 比較(Comparison)
If a double-cell integer is to be treated as signed, the following comparison and mathematical operations are valid:
D+ D- D<
D0<
DABS
DMAX
DMIN
DNEGATE
M*/
M+
如果一個雙單元整數是被當成無號的, 下列的比較和數學操作是正確的:
If a double-cell integer is to be treated as unsigned, the following comparison and mathematical operations are valid:
Traditionally, Forth has been implemented on two's-complement machines where there is a one-to-one mapping of signed numbers to unsigned numbers - any single cell item can be viewed either as a signed or unsigned number. Indeed, the signed representation of any positive number is identical to the equivalent unsigned representation. Further, addresses are treated as unsigned numbers: there is no distinct pointer type. Arithmetic ordering on two's complement machines allows + and - to work on both signed and unsigned numbers. This arithmetic behavior is deeply embedded in common Forth practice. As a consequence of these behaviors, the likely ranges of signed and unsigned numbers for implementations hosted on each of the permissible arithmetic architectures is:
---------------------------------------------------------
算術架構 有號數 無號數
---------------------------------------------------------
二補數 -n-1 to n 0 to 2n+1
一補數 -n to n 0 to n
有號量 -n to n 0 to n
---------------------------------------------------------
---------------------------------------------------------
Arithmetic architecture signed numbers unsigned numbers
---------------------------------------------------------
Two's complement -n-1 to n 0 to 2n+1
One's complement -n to n 0 to n
Signed magnitude -n to n 0 to n
---------------------------------------------------------
這裡的 n 是最大的正有號數. 對於所有的三種架構而言, 在 0 到 n 之間有號數範圍是位元的相等於對應的無號數. 注意在一個有號量機器上, 無號數是相等於有號的非負數, 作為一個強迫對應於位址和無號數而且需要 + 和 - 行為的影響.
where n is the largest positive signed number. For all three architectures, signed numbers in the 0 to n range are bitwise identical to the corresponding unsigned number. Note that unsigned numbers on a signed magnitude machine are equivalent to signed non-negative numbers as a consequence of the forced correspondence between addresses and unsigned numbers and of the required behavior of + and -.
為了參考, 這些數字表示法可以用 NEGATE 實作的方式來定義:
For reference, these number representations may be defined by the way that NEGATE is implemented:
二補數: : NEGATE INVERT 1+ ; 一補數: : NEGATE INVERT ; 有號量: : NEGATE HIGH-BIT XOR ;
two's complement: : NEGATE INVERT 1+ ; one's complement: : NEGATE INVERT ; signed-magnitude: : NEGATE HIGH-BIT XOR ;
這裡的 HIGH-BIT 是一個只有最大有效位元設定的位元遮罩. 注意所有的這些數字系統同意於非負的數字上的表示.
where HIGH-BIT is a bit mask with only the most-significant bit set. Note that all of these number systems agree on the representation of non-negative numbers.
每一個 3.2.1.1 內部數值表示和 6.1.0270 0=, 實作者必須確保沒有標準或支援的詞對於任何數字 (非布林或旗標) 結果傳回負零. 否則許多已經存在的程式設計師假定將會被違反.
Per 3.2.1.1 Internal number representation and 6.1.0270 0=, the implementor must ensure that no standard or supported word return negative zero for any numeric (non-Boolean or flag) result. Many existing programmer assumptions will be violated otherwise.
沒有實作圓圈的無號算術的需求, 也不需要設定無號數字到一個單元的完整大小的範圍. 有歷史的慣例限制 u 的範圍到 +n, 當單元的大小超過 16 位元時, 這是允許的.
There is no requirement to implement circular unsigned arithmetic, nor to set the range of unsigned numbers to the full size of a cell. There is historical precedent for limiting the range of u to that of +n, which is permissible when the cell size is greater than 16 bits.
For example, an implementation might convert the characters a through z identically to the characters A through Z, or it might treat the characters [ through ~ as additional digits with decimal values 36 through 71, respectively.
The Forth-79 Standard specifies that the signed division operators (/, /MOD, MOD, */MOD, and */) round non-integer quotients towards zero (symmetric division). Forth-83 changed the semantics of these operators to round towards negative infinity (floored division). Some in the Forth community have declined to convert systems and applications from the Forth-79 to the Forth-83 divide. To resolve this issue, an ANS Forth system is permitted to supply either floored or symmetric operators. In addition, ANS Forth systems must provide a floored division primitive (FM/MOD), a symmetric division primitive (SM/REM), and a mixed precision multiplication operator (M*).
這個妥協保護了目前 Forth 應用程式的投資; Forth-79 和 Forth-83 程式自動地迎合了 ANS Forth 的除法方面. 實際上, 四捨五入方面很少影響應用程式. 然而, 如果一個程式需要一個指定的四捨五入方面, 它可以使用底限除法原詞 FM/MOD 或對稱除法原詞 SM/REM 來建造一個需求的風味的除法運算子. 這個簡單的技術可以用於轉換 Forth-79 和 Forth-83 程式成 ANS Forth 程式, 而不需要任何對於原始的程式的分析.
This compromise protects the investment made in current Forth applications; Forth-79 and Forth-83 programs are automatically compliant with ANS Forth with respect to division. In practice, the rounding direction rarely matters to applications. However, if a program requires a specific rounding direction, it can use the floored division primitive FM/MOD or the symmetric division primitive SM/REM to construct a division operator of the desired flavor. This simple technique can be used to convert Forth-79 and Forth-83 programs to ANS Forth without any analysis of the original programs.
1 2 - 對於結果是無號數的就是不足, 而會產生正確的有號結果 -1.
Whether underflow occurs depends on the data-type of the result. For example,
the phrase 1 2 - underflows if the result is unsigned and
produces the valid signed result -1.
The only data type in Forth which has concrete rather than abstract existence is the stack entry. Even this primitive typing Forth only enforces by the hard reality of stack underflow or overflow. The programmer must have a clear idea of the number of stack entries to be consumed by the execution of a word and the number of entries that will be pushed back to a stack by the execution of a word. The observation of anomalous occurrences on the data stack is the first line of defense whereby the programmer may recognize errors in an application program. It is also worth remembering that multiple stack errors caused by erroneous application code are frequently of equal and opposite magnitude, causing complementary (and deceptive) results.
為了這些理由和一個機器的其他的理由, 這個明白的、無爭論的、和不可缺少的程式設計規律自從早期的 Forth 日子就被注意到, 對於所有附加於應用程式詞典的詞要提供一個堆疊示意圖, 除了靜態的建造詞像是 VARIABLEs 和 CONSTANTs.
For these reasons and a host of other reasons, the one unambiguous, uncontroversial, and indispensable programming discipline observed since the earliest days of Forth is that of providing a stack diagram for all additions to the application dictionary with the exception of static constructs such as VARIABLEs and CONSTANTs.
The simplest use of control-flow words is to implement the basic control structures shown in figure A.1.
---------------------------------------------------------------
| _____ | _____ |
< >----- IF | \| BEGIN | \| BEGIN
| | | +-------+ | +-------+
+-------+ | | | | | | |
| | | | +-------+ | +-------+
+-------+ | | | | |
| _____| -----< > UNTIL ------ AGAIN
|/ THEN |
| |
---------------------------------------------------------------
Figure A.1 - The basic control-flow patterns.
圖(Figure) A.1 - 基本流程控制原型(The basic control-flow patterns).
在流程控制的每一個分支, 或控制的傳送, 必須在某些方向終止. 一個自然的實作用一個堆疊來記住原始的向前分支和向後分支的目標. 在最小狀況, 只有每一個原始或目標的位置必須被提示, 雖然其他的實作相依的資訊也可以被維護.
In control flow every branch, or transfer of control, must terminate at some destination. A natural implementation uses a stack to remember the origin of forward branches and the destination of backward branches. At a minimum, only the location of each origin or destination must be indicated, although other implementation-dependent information also may be maintained.
一個原始點是一個分支它自己的位置. 一個目標點是如果分支被採用, 控制將繼續的位置. 一個目標點需要去解析每一個原始點的分支位址, 反過來說, 如果每一個流程控制路徑被完成, 不能殘留沒有用到的目標點.
An origin is the location of the branch itself. A destination is where control would continue if the branch were taken. A destination is needed to resolve the branch address for each origin, and conversely, if every control-flow path is completed no unused destinations can remain.
只增加下列三個詞 (AHEAD, CS-ROLL 和 CS-PICK), 基本流程控制詞支援了必要編譯一個不同的可運輸的控制結構的原詞. 需要能力是向前和向後的狀況和非狀況分支的編譯, 和分支來源點和目標點的編譯時期管理. 表格 A.1 顯示了需求的行為.
With the addition of just three words (AHEAD, CS-ROLL and CS-PICK), the basic control-flow words supply the primitives necessary to compile a variety of transportable control structures. The abilities required are compilation of forward and backward conditional and unconditional branches and compile-time management of branch origins and destinations. Table A.1 shows the desired behavior.
對於流程控制詞的需求是適當由其他的流程控制詞平衡, 讓一個編譯時期實作自訂流程控制堆疊的描述是有理由的. 沒有規則有關如何實作流程控制堆疊, 例如, 資料堆疊, 連結列表, 特別的陣列. 每一個在上面提到的流程控制元素是相同的大小.
The requirement that control-flow words are properly balanced by other control-flow words makes reasonable the description of a compile-time implementation-defined control-flow stack. There is no prescription as to how the control-flow stack is implemented, e.g., data stack, linked list, special array. Each element of the control-flow stack mentioned above is the same size.
表格 A.1 - 流程控制詞的編譯行為 --------------------------------------------------------------------------- 在編譯時期, 詞: 支援: 分析: 用於: --------------------------------------------------------------------------- IF orig 標示向前狀況分支的原始點 THEN orig 解析 IF 或 AHEAD BEGIN dest 標示向後目標點 AGAIN dest 用向後非狀況分支來解析 UNTIL dest 用向後狀況分支來解析 AHEAD orig 標示向前非狀況分支的原始點 CS-PICK 複製在流程控制堆疊上的元素 CS-ROLL 重新排序在流程控制堆疊上的元素 --------------------------------------------------------------------------
Table A.1 - Compilation behavior of control-flow words --------------------------------------------------------------------------- at compile time, word: supplies: resolves: is used to: --------------------------------------------------------------------------- IF orig mark origin of forward conditional branch THEN orig resolve IF or AHEAD BEGIN dest mark backward destination AGAIN dest resolve with backward unconditional branch UNTIL dest resolve with backward conditional branch AHEAD orig mark origin of forward unconditional branch CS-PICK copy item on control-flow stack CS-ROLL reorder items on control-flow stack --------------------------------------------------------------------------
有了這些工具, 顯示於 圖表 A.2 的其餘的基本流程控制元素就可以被定義了. 用於這邊的立即詞的堆疊標示法是 ( 編譯 / 執行 ).
With these tools, the remaining basic control-structure elements, shown in figure A.2, can be defined. The stack notation used here for immediate words is ( compilation / execution ).
: WHILE ( dest -- orig dest / flag -- )
\ 狀況的從迴圈中跳出
POSTPONE IF \ 狀況的向前分支
1 CS-ROLL \ 保持在上面的 dest
; IMMEDIATE
: REPEAT ( orig dest -- / -- )
\ 解析一個單一的 WHILE 並且返回 BEGIN
POSTPONE AGAIN \ 非狀況的向後分支到 dest
POSTPONE THEN \ 從 orig 解析向前分支
; IMMEDIATE
: ELSE ( orig1 -- orig2 / -- )
\ 解析 IF 支援的替代的執行
POSTPONE AHEAD \ 非狀況的向前分支 orig2
1 CS-ROLL \ 將 orig1 放回在上面
POSTPONE THEN \ 從 orig1 解析向前分支
; IMMEDIATE
: WHILE ( dest -- orig dest / flag -- )
\ conditional exit from loops
POSTPONE IF \ conditional forward branch
1 CS-ROLL \ keep dest on top
; IMMEDIATE
: REPEAT ( orig dest -- / -- )
\ resolve a single WHILE and return to BEGIN
POSTPONE AGAIN \ uncond. backward branch to dest
POSTPONE THEN \ resolve forward branch from orig
; IMMEDIATE
: ELSE ( orig1 -- orig2 / -- )
\ resolve IF supplying alternate execution
POSTPONE AHEAD \ unconditional forward branch orig2
1 CS-ROLL \ put orig1 back on top
POSTPONE THEN \ resolve forward branch from orig1
; IMMEDIATE
-----------------------------------------------
| _____ |
< >----- IF | \| BEGIN
| | | +-------+
+-------+ | | | |
| | | | +-------+
+-------+ | | |
| _____| | < >----- WHILE
_____/ / ELSE | | |
| | | +-------+ |
| +-------+ | | | |
| | | | +-------+ |
| +-------+ | | |
|_____ | |_____/ _____|
\| THEN / REPEAT
| |
----------------------------------------------
Figure A.2 - Additional basic control-flow patterns.
Forth 流程控制為知名的嚴格結構的程式設計的問題提供了一個解決方案.
Forth control flow provides a solution for well-known problems with strictly structured programming.
基本的控制結構可以被補充的, 像顯示於 圖表 A.3 的例子一樣, 附加 WHILEs 於 BEGIN ... UNTIL 和 BEGIN ... WHILE ... REPEAT 結構. 然而, 對於每一個附加的 WHILE, 必須有一個 THEN 在這個結構的結尾. THEN 完成了與 WHILE 的語法, 並且提示了 WHILE 傳送控制時, 到哪邊去繼續執行. 使用超過一個附加 WHILE 是可能但不常用的. 注意如果使用者發現使用 THEN 是惹人厭的, 一個更討人喜歡的別名可以被定義.
The basic control structures can be supplemented, as shown in the examples in figure A.3, with additional WHILEs in BEGIN ... UNTIL and BEGIN ... WHILE ... REPEAT structures. However, for each additional WHILE there must be a THEN at the end of the structure. THEN completes the syntax with WHILE and indicates where to continue execution when the WHILE transfers control. The use of more than one additional WHILE is possible but not common. Note that if the user finds this use of THEN undesirable, an alias with a more likable name could be defined.
附加的動作可以在流程控制詞 (REPEAT 或 UNTIL) 和對應到附加 WHILE 的 THEN 之間進行. 此外, 如果附加的動作是預期的對於正常的終止和較早的終止, 替代的動作可以用普通的 Forth ELSE 來分隔. 這個終止的動作是全部在迴圈的主體後指定.
Additional actions may be performed between the control flow word (the REPEAT or UNTIL) and the THEN that matches the additional WHILE. Further, if additional actions are desired for normal termination and early termination, the alternative actions may be separated by the ordinary Forth ELSE. The termination actions are all specified after the body of the loop.
--------------------------------------------------
_____ | _____ |
| \| BEGIN | \| BEGIN
| +-------+ | +-------+
| | | | | |
| +-------+ | +-------+
| | | |
| < >------ WHILE | < >----- WHILE
| | | | | |
| +-------+ | | +-------+ |
| | | | | | | |
| +-------+ | | +-------+ |
| | | | | |
| < >---- | WHILE -----< > | UNTIL
| | | | | |
| +-------+ | | +-------+ |
| | | | | | | |
| +-------+ | | +-------+ |
| | ____| | | _____/
\____/ / | REPEAT _____/ / ELSE
| | | |
+-------+ | | +-------+
| | | | | |
+-------+ | | +-------+
| ______/ \____ |
|/ THEN \| THEN
| |
---------------------------------------------------
Figure A.3 - Extended control-flow pattern examples.
注意當用 ELSE 或 THEN 符合 WHILE 時, REPEAT 創造了一個不規則., 當比較於 BEGIN...UNTIL 的狀況時, 是值得注意的. 那就是說, 有比 WHILEs 少一個 ELSE 或 THEN, 因為 REPEAT 解析了一個 THEN. 如上所述, 如果使用者發現這個計數不符合是惹人厭的, REPEAT 可以被由它自己的定義來內含式地取代.
Note that REPEAT creates an anomaly when matching the WHILE with ELSE or THEN, most notable when compared with the BEGIN...UNTIL case. That is, there will be one less ELSE or THEN than there are WHILEs because REPEAT resolves one THEN. As above, if the user finds this count mismatch undesirable, REPEAT could be replaced in-line by its own definition.
其他的迴圈跳出流程控制詞, 甚至是其他的迴圈, 可以被定義. 唯一的需求是流程控制堆疊被適當維護和操作.
Other loop-exit control-flow words, and even other loops, can be defined. The only requirements are that the control-flow stack is properly maintained and manipulated.
下列的 ANS Forth CASE 結構簡單的實作是一個控制延伸結構的範例. 注意要維護資料堆疊來避免干擾可能的流程控制堆疊的使用.
The simple implementation of the ANS Forth CASE structure below is an example of control structure extension. Note the maintenance of the data stack to prevent interference with the possible control-flow stack usage.
0 CONSTANT CASE IMMEDIATE ( OFs 的初始計數值 )
: OF ( #of -- orig #of+1 / x -- )
1+ ( 計數 OFs )
>R ( 在 case 這個控制流程中移出堆疊 )
( 堆疊是資料堆疊. )
POSTPONE OVER POSTPONE = ( 複製並測試 case 值 )
POSTPONE IF ( 增加 orig 到控制流程堆疊 )
POSTPONE DROP ( 如果相等, 丟棄 case 值 )
R> ( 我們現在可以拿回計數值 )
; IMMEDIATE
: ENDOF ( orig1 #of -- orig2 #of )
>R ( 在 case 這個控制流程中移出堆疊 )
( 堆疊是資料堆疊. )
POSTPONE ELSE
R> ( 我們現在可以拿回計數值 )
; IMMEDIATE
: ENDCASE ( orig1..orign #of -- )
POSTPONE DROP ( 丟棄 case 值 )
0 ?DO
POSTPONE THEN
LOOP
; IMMEDIATE
0 CONSTANT CASE IMMEDIATE ( init count of OFs )
: OF ( #of -- orig #of+1 / x -- )
1+ ( count OFs )
>R ( move off the stack in case the control-flow )
( stack is the data stack. )
POSTPONE OVER POSTPONE = ( copy and test case value)
POSTPONE IF ( add orig to control flow stack )
POSTPONE DROP ( discards case value if = )
R> ( we can bring count back now )
; IMMEDIATE
: ENDOF ( orig1 #of -- orig2 #of )
>R ( move off the stack in case the control-flow )
( stack is the data stack. )
POSTPONE ELSE
R> ( we can bring count back now )
; IMMEDIATE
: ENDCASE ( orig1..orign #of -- )
POSTPONE DROP ( discard case value )
0 ?DO
POSTPONE THEN
LOOP
; IMMEDIATE
The restrictions in section 3.2.3.3 Return stack are necessary if implementations are to be allowed to place loop parameters on the return stack.
1 CHARS. 相似地, 對齊可以用詞組像是 1 ALIGNED 來決定.
The size in address units of various data types may be determined by phrases
such as 1 CHARS. Similarly, alignment may be determined by
phrases such as 1 ALIGNED.
環境的訊問可以分類成兩組: 總是產生相同值的, 和那些產生不同值的. 前者這一組包含像是 MAX-N 的記錄. 這項記錄是由硬體固定或是由 Forth 系統設計來決定; 一個使用者被擔保訊問這個問題一次就足夠.
The environmental queries are divided into two groups: those that always produce the same value and those that might not. The former groups include entries such as MAX-N. This information is fixed by the hardware or by the design of the Forth system; a user is guaranteed that asking the question once is sufficient.
另一組的訊問是對於合理地在時間經過時改變的事物. 例如一個應用程式可以用一個環境訊問來測試是否雙數字詞的存在. 如果它不存在, 系統可以呼叫一個系統相依的行程來載入這個詞集. 系統允許改變 ENVIRONMENT? 的資料庫, 因此有關它的接著的訊問提示了它的存在.
The other group of queries are for things that may legitimately change over time. For example an application might test for the presence of the Double Number word set using an environment query. If it is missing, the system could invoke a system-dependent process to load the word set. The system is permitted to change ENVIRONMENT?'s database so that subsequent queries about it indicate that it is present.
注意一個回傳一個 未知 回應的訊問, 可以在接著的訊問傳回一個 已知 的結果.
Note that a query that returns an unknown response could produce a known result on a subsequent query.
A Standard Program may redefine a standard word with a non-standard definition. The program is still Standard (since it can be built on any Standard System), but the effect is to make the combined entity (Standard System plus Standard Program) a non-standard system.
The language in this section is there to ensure the portability of Standard Programs. If a program uses something outside the Standard that it does not provide itself, there is no guarantee that another implementation will have what the program needs to run. There is no intent whatsoever to imply that all Forth programs will be somehow lacking or inferior because they are not standard; some of the finest jewels of the programmer's art will be non-standard. At the same time, the committee is trying to ensure that a program labeled Standard will meet certain expectations, particularly with regard to portability.
在許多系統環境中, 輸入來源不能支援由於延伸的因素的這些非書寫字元, 像是使用這些字元來作流量控制或編輯. 附加地, 在從一個文字檔案中解譯時, 分析的函式特別的假定非書寫字元為空白; 因此由文字解譯器接收到的詞將不會包含內嵌的非書寫字元. 要允許這樣的環境實作為標準的, 標準程式的最小的限制是必須的.
In many system environments the input source is unable to supply certain non-graphic characters due to external factors, such as the use of those characters for flow control or editing. In addition, when interpreting from a text file, the parsing function specifically treats non-graphic characters like spaces; thus words received by the text interpreter will not contain embedded non-graphic characters. To allow implementations in such environments to call themselves Standard, this minor restriction on Standard Programs is necessary.
一個標準程式允許去有權創造包含非書寫字元的定義名稱. 歷史地, 這樣的名稱是用於鍵盤函式和 不可見的 詞.
A Standard System is allowed to permit the creation of definition names containing non-graphic characters. Historically, such names were used for keyboard editing functions and invisible words.
The words #TIB, >IN, BASE, BLK, SCR, SOURCE, SOURCE-ID, STATE, and TIB contain information used by the Forth system in its operation and may be of use to the application. Any assumption made by the application about data available in the Forth system it did not store other than the data just listed is an environmental dependency.
沒有指定 (在標準中) 哪些單位是可定址的或不可定址的.
There is no point in specifying (in the Standard) both what is and what is not addressable.
一個標準的程式不能定址:
A Standard Program may NOT address:
因為某些 Forth 系統從 ROM 開始執行, 而且有些共享於其他使用者或系統的輸出入緩衝區, 唯讀的限制出現, 可移植的程式不能知道哪些區域被影響到了, 因此有整體的限制.
The read-only restrictions arise because some Forth systems run from ROM and some share I/O buffers with other users or systems. Portable programs cannot know which areas are affected, hence the general restrictions.
Many processors have restrictions on the addresses that can be used by memory access instructions. For example, on a Motorola 68000, 16-bit or 32-bit data can be accessed only at even addresses. Other examples include RISC architectures where 16-bit data can be loaded or stored only at even addresses and 32-bit data only at addresses that are multiples of four.
一個 ANS Forth 的實作者可以在一或兩天內處理這些對齊的限制. Forth 的記憶體存取詞 (@, !, +!, 等等.) 可以用較小寬度而沒有對齊限制的指定來實作. 例如, 一個在 68000 上的 16 位元單元 Forth, @ 可以用兩個 68000 位元提取指令和一個將這兩個位元組重組成一個 16 位元的單元. 雖然這為程式設計師隱藏硬體的限制, 它是沒有效率的, 而且可能在某些硬體環境中有不可預期的效應. 一個替代的 ANS Forth 的實作可以用最接近符合詞的功能的固有的指令. 在一個有 16 位元單元的 68000 Forth, @ 將會使用 68000 的 16 位元移動指定. 在這個例子中, 給予 @ 一個正確的對齊位址的責任交給了程式設計師. 一個可移植的 Forth 程式必須假定對齊可能是需要的, 並且跟隨這一節的區求.
An implementor of ANS Forth can handle these alignment restrictions in one of two ways. Forth's memory access words (@, !, +!, etc.) could be implemented in terms of smaller-width access instructions which have no alignment restrictions. For example, on a 68000 Forth with 16-bit cells, @ could be implemented with two 68000 byte-fetch instructions and a reassembly of the bytes into a 16-bit cell. Although this conceals hardware restrictions from the programmer, it is inefficient, and may have unintended side effects in some hardware environments. An alternate implementation of ANS Forth could define each memory-access word using the native instructions that most closely match the word's function. On a 68000 Forth with 16-bit cells, @ would use the 68000's 16-bit move instruction. In this case, responsibility for giving @ a correctly-aligned address falls on the programmer. A portable ANS Forth program must assume that alignment may be required and follow the requirements of this section.
The data space of a Forth system comes in discontinuous regions! The location of some regions is provided by the system, some by the program. Data space is contiguous within regions, allowing address arithmetic to generate valid addresses only within a single region. A Standard Program cannot make any assumptions about the relative placement of multiple regions in memory.
章節 3.3.3.2 確實規定了在資料空間中的哪些連續區域可以被獲得的情況. 例如:
CREATE TABLE 1 C, 2 C, ALIGN 1000 , 2000 ,
Section 3.3.3.2 does prescribe conditions under which contiguous regions of data space may be obtained. For example:
CREATE TABLE 1 C, 2 C, ALIGN 1000 , 2000 ,
製造了一個位址由 TABLE 傳回的表格. 要存取這個表格,
TABLE C@ 將傳回 1 TABLE CHAR+ C@ 將傳回 2 TABLE 2 CHARS + ALIGNED @ 將傳回 1000 TABLE 2 CHARS + ALIGNED CELL+ @ 將傳回 2000.
makes a table whose address is returned by TABLE. In accessing this table,
TABLE C@ will return 1 TABLE CHAR+ C@ will return 2 TABLE 2 CHARS + ALIGNED @ will return 1000 TABLE 2 CHARS + ALIGNED CELL+ @ will return 2000.
相似地,
CREATE DATA 1000 ALLOT
製造了大小 1000 位址單元的陣列. 一個更可移植的策略將以應用程式單位來定義它, 像是:
500 CONSTANT NCELLS CREATE CELL-DATA NCELLS CELLS ALLOT
這個陣列可以用這樣的方式索引:
: LOOK NCELLS 0 DO CELL-DATA I CELLS + ? LOOP ;
Similarly,
CREATE DATA 1000 ALLOT
makes an array 1000 address units in size. A more portable strategy would define the array in application units, such as:
500 CONSTANT NCELLS CREATE CELL-DATA NCELLS CELLS ALLOT
This array can be indexed like this:
: LOOK NCELLS 0 DO CELL-DATA I CELLS + ? LOOP ;
In many existing Forth systems, these areas are at HERE or just beyond it, hence the many restrictions.
(2*n)+2 是包含未加標點符號的、有開頭減號的和一個尾端的空白的最大雙數字的一個字元字串大小.
(2*n)+2 is the size of a character string containing the unpunctuated binary representation of the maximum double number with a leading minus sign and a trailing space.
實作要點: 由於最小的 n 值是 16, 書寫數字輸出字串的絕對最小值是 34 個字元. 但是如果你的實作有一個較大的 n, 你必須也增加書寫數字輸出字串的大小.
Implementation note: Since the minimum value of n is 16, the absolute minimum size of the pictured numeric output string is 34 characters. But if your implementation has a larger n, you must also increase the size of the pictured numeric output string.
The initiation semantics correspond to the code that is executed upon entering a definition, analogous to the code executed by EXIT upon leaving a definition. The run-time semantics correspond to code fragments, such as literals or branches, that are compiled inside colon definitions by words with explicit compilation semantics.
在一個 Forth 跨越編譯器中, 執行語義可以被指定只有在主機系統中出現, 目標系統出現, 或兩個系統中都出現. 例如, 由像是 CELLS 的詞執行於主機系統, 而傳回描述一個目標系統是很適當的, 對於冒號定義就只執行於目標系統, 對於 CONSTANT 和 VARIABLE 就在兩個系統都有執行行為. 跨越編譯器的細節超過這個標準的範圍.
In a Forth cross-compiler, the execution semantics may be specified to occur in the host system only, the target system only, or in both systems. For example, it may be appropriate for words such as CELLS to execute on the host system returning a value describing the target, for colon definitions to execute only on the target, and for CONSTANT and VARIABLE to have execution behaviors on both systems. Details of cross-compiler behavior are beyond the scope of this Standard.
For a variety of reasons, this Standard does not define interpretation semantics for every word. Examples of these words are >R, .", DO, and IF. Nothing in this Standard precludes an implementation from providing interpretation semantics for these words, such as interactive control-flow words. However, a Standard Program may not use them in interpretation state.
Compiler recursion at the definition level consumes excessive resources, especially to support locals. The Technical Committee does not believe that the benefits justify the costs. Nesting definitions is also not common practice and won't work on many systems.
內容列表(Table of Contents)
下一章(Next Section)