Search-order specification and control mechanisms vary widely. The FIG-Forth, Forth-79, polyFORTH, and Forth-83 vocabulary and search order mechanisms are all mutually incompatible. The complete list of incompatible mechanisms, in use or proposed, is much longer. The ALSO/ONLY scheme described in a Forth-83 Experimental Proposal has substantial community support. However, many consider it to be fundamentally flawed, and oppose it vigorously.
Recognizing this variation, this Standard specifies a new primitive set of tools from which various schemes may be constructed. This primitive search-order word set is intended to be a portable construction set from which search-order words may be built, rather than a user interface. ALSO/ONLY or the various vocabulary schemes supported by the major Forth vendors can be defined in terms of the primitive search-order word set.
The encoding for word list identifiers wid might be a small-integer index into an array of word-list definition records, the data-space address of such a record, a user-area offset, the execution token of a Forth-83 style sealed vocabulary, the link-field address of the first definition in a word list, or anything else. It is entirely up to the system implementor.
In some systems the interpretation of numeric literals is controlled by including pseudo word lists that recognize numbers at the end of the search order. This technique is accommodated by the default search order behavior of SET-ORDER when given an argument of -1. In a system using the traditional implementation of ALSO/ONLY , the minimum search order would be equivalent to the word ONLY.
There has never been a portable way to restore a saved search order. F83 (not Forth-83) introduced the word PREVIOUS , which almost made it possible to unload the search order by repeatedly executing the phrase CONTEXT @ PREVIOUS. The search order could be reloaded by repeating ALSO CONTEXT !. Unfortunately there was no portable way to determine how many word lists were in the search order.
ANS Forth has removed the word CONTEXT because in many systems its contents refer to more than one word list, compounding portability problems.
Note that : (colon) no longer affects the search order. The previous behavior, where the compilation word list replaces the first word list of the search order, can be emulated with the following redefinition of : (colon).
: : GET-ORDER SWAP DROP GET-CURRENT SWAP SET-ORDER : ;
In other words, the following is not guaranteed to work:
: FOO ... [ ... SET-CURRENT ] ... RECURSE ... ; IMMEDIATERECURSE, ; (semicolon), and IMMEDIATE may or may not need information stored in the compilation word list.
The string argument to SEARCH-WORDLIST is represented by c-addr u, rather than by just c-addr as with FIND. The committee wishes to establish c-addr u as the preferred representation of a string on the stack, and has adopted that representation for all new functions that accept string arguments. While this decision may cause the implementation of SEARCH-WORDLIST to be somewhat more difficult in existing systems, the committee feels that the additional difficulty is minor.
When SEARCH-WORDLIST fails to find the word, it does not return the string, as does FIND. This is in accordance with the general principle that Forth words consume their arguments.
Here is an implementation of ALSO/ONLY in terms of the primitive search-order word set.
WORDLIST CONSTANT ROOT ROOT SET-CURRENT : DO-VOCABULARY ( -- ) \ Implementation factor DOES> @ >R ( ) ( R: widnew ) GET-ORDER SWAP DROP ( wid1 ... widn-1 n ) R> SWAP SET-ORDER ; : DISCARD ( x1 .. xu u - ) \ Implementation factor 0 ?DO DROP LOOP \ DROP u+1 stack items ; CREATE FORTH FORTH-WORDLIST , DO-VOCABULARY : VOCABULARY ( name -- ) WORDLIST CREATE , DO-VOCABULARY ; : ALSO ( -- ) GET-ORDER OVER SWAP 1+ SET-ORDER ; : PREVIOUS ( -- ) GET-ORDER SWAP DROP 1- SET-ORDER ; : DEFINITIONS ( -- ) GET-ORDER OVER SET-CURRENT DISCARD ; : ONLY ( -- ) ROOT ROOT 2 SET-ORDER ; \ Forth-83 version; just removes ONLY : SEAL ( -- ) GET-ORDER 1- SET-ORDER DROP ; \ F83 and F-PC version; leaves only CONTEXT : SEAL ( -- ) GET-ORDER OVER 1 SET-ORDER DISCARD ;
The preceding definition of ONLY in terms of a ROOT word list follows F83 usage, and assumes that the default search order just includes ROOT and FORTH. A more portable definition of FORTH and ONLY, without the assumptions, is:
<omit the ... WORDLIST CONSTANT ROOT ... line> CREATE FORTH GET-ORDER OVER , DISCARD DO-VOCABULARY : ONLY ( -- ) -1 SET-ORDER ;
Here is a simple implementation of GET-ORDER and SET-ORDER, including a corresponding definition of FIND. The implementations of WORDLIST, SEARCH-WORDLIST, GET-CURRENT and SET-CURRENT depend on system details and are not given here.
16 CONSTANT #VOCS VARIABLE #ORDER CREATE CONTEXT #VOCS CELLS ALLOT : GET-ORDER ( -- wid1 .. widn n ) #ORDER @ 0 ?DO #ORDER @ I - 1- CELLS CONTEXT + @ LOOP #ORDER @ ; : SET-ORDER ( wid1 .. widn n -- ) DUP -1 = IF DROP <push system default word lists and n> THEN DUP #ORDER ! 0 ?DO I CELLS CONTEXT + ! LOOP ; : FIND ( c-addr -- c-addr 0 | w 1 | w -1 ) 0 ( c-addr 0 ) #ORDER @ 0 ?DO OVER COUNT ( c-addr 0 c-addr' u ) I CELLS CONTEXT + @ ( c-addr 0 c-addr' u wid) SEARCH-WORDLIST ( c-addr 0; 0 | w 1 | w -1 ) ?DUP IF ( c-addr 0; w 1 | w -1 ) 2SWAP 2DROP LEAVE ( w 1 | w -1 ) THEN ( c-addr 0 ) LOOP ( c-addr 0 | w 1 | w -1 ) ;
In an implementation where the dictionary search mechanism uses a hash table or lookup cache to reduce the search time, SET-ORDER might need to reconstruct the hash table or flush the cache.
/STRING is used to remove or add characters relative to the left end of the character string. Positive values of n will exclude characters from the string while negative values of n will include characters to the left of the string. /STRING is a natural factor of WORD and commonly available.
If c-addr2 lies within the source region (i.e., when c-addr2 is not less than c-addr1 and c-addr2 is less than the quantity c-addr1 u CHARS +), memory propagation occurs.
Typical use: Assume a character string at address 100: ABCD. Then after
100 DUP CHAR+ 3 CMOVE
the string at address 100 is AAAA.
Rationale for CMOVE and CMOVE> follows MOVE.
If c-addr1 lies within the destination region (i.e., when c-addr1 is greater than or equal to c-addr2 and c-addr2 is less than the quantity c-addr1 u CHARS +), memory propagation occurs.
Typical use: Assume a character string at address 100: ABCD. Then after
100 DUP CHAR+ SWAP 3 CMOVE>
the string at address 100 is DDDD.
Existing Forth systems perform string comparison operations using words that differ in spelling, input and output arguments, and case sensitivity. One in widespread use was chosen.
Existing Forth systems perform string searching operations using words that differ in spelling, input and output arguments, and case sensitivity. One in widespread use was chosen.
The current functionality of 6.1.2165 S" may be provided by the following definition:
: S" ( "ccc<quote>" -- ) [CHAR] " PARSE POSTPONE SLITERAL ; IMMEDIATE
Table of Contents
Next Section