Now we see how UBER executes. When it is interpreted from the terminal keyboard, 'D-E' will execute to fetch the emplaced PFA within the definitions of UBER (by R> 2+ @). After checking STATE the ELSE part will execute OVER from its parameter field address.
When UBER is encountered by the compiler in a colon definition, it will execute, as do all compiling words. Again R> 2+ @ will fetch the PFA of OVER to the stack. The check of STATE will be true and DUP 8 - C@ will fetch the byte containing the precedence bit. When compared to hex 80, a true will result for non-immediate, and 2 - , will compile the code field address.
However, if the word had been immediate ( OVER isn't ) the ELSE part will execute the word as in any compiling word.
The space cost of example 2 is 14 bytes
per word ( 8 bytes per header and 6 bytes in
the parameter field). The compile time cost
is the execution of 'D-E.' There is no
ultimate run-time cost in compiled
definitions.
EXAMPLE TWO - <BUILDS - DOES>
Another way is to define a 'BUILDS-DOES' word E>G (English to German). It is then used to build a set of translation words similar to a FORTH mnemonic assembler.
- E>G <BUILDS ' , IMMEDIATE
DOES> @ STATE @ IF (compiling ) DUP 8 - C@ 80 < IF 2 - , ELSE EXECUTE THEN ELSE EXECUTE THEN ;
E>G UBER OVER E>G LADEN LOAD E>G BASIS BASE ..... etc.
E>G is a defining word that builds each German word (UBER) and emplaces the parameter field address of the English word (OVER) into the new parameter field ( of UBER ), and finally makes UBER immediate. When UBER is encountered by the outer interpreter, it does the DOES> part. The parameter of UBER, (the PFA of OVER ) will be fetched and STATE tested. Since executing, the ELSE part will execute OVER from its parameter field address ( as in the example 1 ).
When compiling, the DOES> part will be executed, again similarly to 'D-E' as in Example 1, The space cost of the BUILDS-DOES method its 10 bytes per word ( 8 in the header, 2 in the parameter field). The compile time is the same as in Example 1 and there is no run-time cost.
EXAMPLE THREE - RENAME
This last method is the most fool-proof of all. We will just re-label the name field of each resident word to the German equivalent.
- RENAME ' S - DUP C@ 60
AND (precedence bit ) 20 WORD HERE C@ + HERE C! (store into length) HERE SWAP 4 MOVE ; ( overlay old name ) RENAME OVER UBER RENAME LOAD LADED RENAME BASE BASIS
This method extracts the precedence bit of the old (English) definition and adds it to the length count of the new (German) name. The new name is then overwritten to the old name field. There is no space or time cost!! The dictionary is now truely translated.
A final caution is in order for Examples 1 and 2. Some FORTH methods may still give trouble. If you should try:
UBER
you will find the PFA of UBER which is a translating definition, and not the ultimate run-time procedure, (which is really in OVER). This would have disasterous results if you were attempting to alter what you thought was the executing procedure, and you were really altering the compiling word. For this reason, the method of Example 3 is the only truly 'fool-proof' method. The renaming method has the added use of allowing you to change names in your running system. For example, it is likely that the old <R will be renamed >R in the international standard FORTH-77. You can simply update your system by the use of the word RENAME.
- S W.F. RAGSDALE 8/27/78