The Fleet Forth metacompiler has a new feature.
In another thread, Garth Wilson commented:
The 6502 Forth I got started on used lower-case for the internals, and I have stuck with that. So for example, DO compiles do, LOOP compiles loop, IF compiles 0branch, etc.. It's shorter than (do), (loop), etc.. which I think fig-Forth does, and if you want to put it in a comment marked out by parentheses, you can, without ending the comment prematurely.
Since the
DO LOOP primitives are only used by the
DO LOOP compiling words, I was wondering if anyone thought about naming the primitives the same thing.
DO would compile a primitive named
DO ,
LOOP would compile a primitive named
LOOP , etc. .
The Fleet Forth metacompiler does not allow redefinitions within the target vocabulary and for good reason. The metacompiler builds the target in virtual memory. For each word that is defined, a 'target word' is added to the target vocabulary on the host. the target words are
CREATE DOES> words with three cells in their parameter fields. The first cell is the virtual address of the corresponding word in the target, the address it will have in the new kernel. The second address is the address of the word that was found with the same name ( usually found in the
META vocabulary or the host
FORTH vocabulary). The third cell is for statistical data ( how many times was this word compiled into a new definition? ). While interpreting, or if the target word is immediate, the target word ( the word in the target vocabulary on the host ) is executed. All target words have the same behavior, fetch the address in their second cell, abort with a message if it is zero, otherwise execute it. There are metacompiler versions of the compiler words in the
META vocabulary. When compiling a word in the target that has a
DO LOOP , the
META versions of these words are found and executed. If the target versions of these words are already defined, the target word executes the
META version when it is executed.
The problem arises if the primitive and compiling word for
DO have the same name. If the compiling word has not been defined yet and a
DO LOOP is used in the source of a word ( the primitives having already been defined ) , the primitive in the target will be found and compiled! No in line branching addresses will be compiled, just the primitive.
The metacompiler's new feature adds a name buffer which normally has a zero in the first byte. If there is a non zero value in the first byte, the name in the buffer is used for the name in virtual memory. If I want to name the
DO primitive
DO , I can do it like this:
Code: Select all
// (DO)
HEX
T" DO"
CODE (DO) ( N1 N2 -- )
< CODE FOR (DO) >
END-CODE
The target word for the
DO primitive will have the name
(DO) , but the actual name for the primitive in the new kernel will be
DO .
If I want to leave the name in the new kernel the same as in the source (
(DO) ) , I just leave out the
T" <name>
" .
Code: Select all
// (DO)
HEX
CODE (DO) ( N1 N2 -- )
< CODE FOR (DO) >
END-CODE