home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
224b.lha
/
metavocs.txt
< prev
next >
Wrap
Text File
|
1989-04-08
|
12KB
|
288 lines
**this file explains how I implemented the multiple vocabularies with the
**copy of L&P Meta.compiler. It was posted on GEnie, I have included it
**here for information.
How to change Laxen&Perry F83 Metacompiler to use multiple vocabularies
when compiling the kernel.
First, the version I used this on is the Amiga F83 a derivative of L&P
V2.1.0 for CP/M. The Amiga F83 was posted to GEnie by me some time ago.
It is a 32 bit model. The differences are obvious, if you have your
version at hand and compare the listings. Most are simple substitutions
of 4* for 2* and 4+ for 2+, since cell size in my system is 32 bits, the
L&P model uses 16 bits.
This is not a new Metacompiler. I set out to make changes to the system,
instead. This is supposed to be a feature of Forth. Maintainability.
And as far as I'm concerned it is. It took very few changes to make
multiple vocabularies possible.
What that implies is that any word defined to be used interpretively from
within Meta is visible at all times. This includes defined VOCABULARIES.
Others which will be visible at all times (much as before) are VARIABLES
and CONSTANTS. In my opinion that is a small sacrifice. And the major
advantage is that the original Kernel.blk and Meta.blk need no changes
except for the ones given below. The Metacompiler feels and looks
identical to the original from L&P, with the added feature of hiding CODE
and COLON definitions.
This is a 2 step procedure:
1). Change the kernel, Metacompile
2). Change Meta and some minor changes in the kernel, Metacompile.
Some terminology:
target-image The data that will be the new kernel, once saved.
dictionary A set of vocabularies, with a CONTEXT like array, a variable
behaving like CURRENT, and a vocabulary link like VOC-LINK.
symbol-dict. A set of vocabularies into which all symbols are entered.
It is here that the Metacompiler finds the address to be
compiled. In the original version this was the TARGET
vocabulary. The symbol-dict will grow as each new target
vocabulary is defined.
STEP 1 Altering the way the system FINDs words
-----------------------------------------------
When Metacompiling, the host system is used to find the word in CONTEXT.
Meta controls the search order by using TARGET, the vocabulary where all
the symbols are defined. This is only one vocabulary, and what we want is
a multiple set of vocabularies, controlled by us in the kernel.blk source
file.
If the whole idea of FINDing and CONTEXT was designed to be used with
multiple dictionaries, that would have been a trivial change.
We can still simulate it by altering the way FIND works. If FIND
encounters a vocabulary address that we mark as a special vocabulary, it
can go and find the word in question in an extra CONTEXT.
CONTEXT: .... ..... TARGET ..... 0000
------------> + + ------>
| |
+------+ +-------+
| |
| |
+-> ------------->+
<CONTEXT>: .... .... .... 0000
In the above diagram TARGET would not receive any words. They are stuck
into another current; <CURRENT>.
This allows Meta to be used, almost unchanged. TARGET is still a
vocabulary in Meta, empty, and used as a flag.
The actual changes: (in Kernel.blk )
I inserted a blank screen between the screens that define (FIND) and FIND,
by moving screens around. In the blank screen I entered:
0 \ Meta multiple voc support. 02Jun88pJa
1 VARIABLE <CURRENT>
2 VARIABLE <CONTEXT> HERE THERE #VOCS 4* DUP ALLOT ERASE
3 VARIABLE <TARGET> -1 <TARGET> !-T
4 : TARGET? (S addr -- fl ) <TARGET> @ = ;
5 : <DEFINITIONS> <CONTEXT> @ <CURRENT> ! ;
6 : <FIND> (S addr -- addr false | cfa flag )
7 DUP C@ IF PRIOR OFF FALSE #VOCS 0
8 DO DROP <CONTEXT> I 4* + @ DUP
9 IF DUP PRIOR @ OVER PRIOR ! =
10 IF DROP FALSE
11 ELSE OVER SWAP HASH @ (FIND) DUP ?LEAVE
12 THEN THEN LOOP
13 DUP IF R> DROP LEAVE ELSE DUP THEN
14 ELSE DROP END? ON ['] NOOP 1 THEN ;
15
<CURRENT> and <CONTEXT> are alternate copies of CONTEXT and CURRENT.
<TARGET> is a flag, initialized to -1. Here Meta can put the address of
the vocabulary, which causes FIND to execute <FIND>. The word TARGET?
returns a flag for that purpose.
<DEFINITIONS> is the same as DEFINITIONS, for the alternate
CONTEXT/CURRENT. <FIND> is a copy of FIND, with a small difference. It
uses <CONTEXT> and it exists a little different. First of all the C@ will
always be true, or execution wouldn't even get to here, since <FIND>
should only be called from FIND. The C@ test is done in FIND, and it will
return NOOP and 1 in that case. I'm a little lazy, could have removed
that. (You can). If <FIND> finds a match in <CONTEXT> it will exit the
DO..LOOP via ?LEAVE. It will end up on line 13, test to see if it was a
match and exit the caller: FIND. The R> DROP pops the return address and
the LEAVE exits the DO..LOOP that was being executed in FIND. If no match
it duplicates the flag, to be used in FIND, to indicate no vocabulary in
that position of CONTEXT.
( I actually use all lower case, but that's my choice. Watch out for the
4* that should in 16 bit system be 2* )
In the next screen, the original FIND was changed:
.....................
DO DROP CONTEXT I 4* + @ DUP
TARGET? IF DROP <FIND> ELSE DUP THEN ( <--inserted )
IF DUP PRIOR @ OVER PRIOR ! =
..................
The added line will cause <FIND> to be used if TARGET? returns true, that
is, the vocabulary is e.g. TARGET.
In "CREATE, the sequence: CURRENT @
was replaced by:
CURRENT @ TARGET? IF <CURRENT> @ ELSE CURRENT @ THEN
Those are all the changes required for the kernel, next metacompile.
The new kernel must be used to Metacompile again, after the next
steps have been made.
STEP 2. Making the changes in Meta.blk and the last changes in Kernel.blk
-------------------------------------------------------------------------
The only changes required in Meta.blk are in the way Meta defines a
vocabulary. We want this vocabulary to:
1- Create a header and vocabulary links in the target-image.
2- Save the address of (1) in a symbol, which is kept in the <CURRENT>
vocabulary, part of the symbol dictionary.
3- Create a word in vocabulary META to save pointers into the symbol
dictionary; the vocabulary corresponding to the target-image one.
When this word executes, it must set <CONTEXT> and also CONTEXT-T,
which points to a set of links in the target-image.
The vocabulary defined in meta is linked into SYMBOL-LINK, not VOC-LINK
of the host system.
To make life easier a set of words to manipulate and take a look at the
symbol table are added. (.SYMBOLS doesn't work)
The changes in Meta.blk:
After the vocabulary TARGET is defined the variable <TARGET> must be set:
VOCABULARY TARGET ' TARGET >BODY <TARGET> !
After that I added a variable:
VARIABLE SYMBOL-LINK
It links all the symbol vocabularies together, see below.
The word VOCABULARY now is:
: VOCABULARY (S -- )
RECREATE [FORWARD] <VOCABULARY>
HERE-T #THREADS 0 DO 0 ,-T LOOP
HERE-T VOC-LINK-T @ ,-T VOC-LINK-T !
[FORTH] CREATE [META]
#TRHEADS 0 DO 0 , LOOP
HERE SYMBOL-LINK @ , SYMBOL-LINK !
,
DOES> DUP <CONTEXT> ! #THREADS 1+ 4* + @ CONTEXT-T ! ;
The first three lines are the same as before. ( In the Amiga version the
second ,-T is ,-tr ) On the fourth line, ( forth ) CREATE makes a header
in the host system, META vocabulary. It then allocates link pointers which
will point into the symbol dict. Links itself into SYMBOL-LINK. Stores the
target-image pointer to the target-image version of the defined
vocabulary. When the defined vocabulary is used, it will put the saved
target-image pointer into CONTEXT-T and set <CONTEXT> to the link
pointers.
Next I WIPED the screen defining .SYMBOLS, it will not work with the above
vocabulary definition. I used that screen to make some help words:
|
0 \ META <CONTEXT> MANIPULATORS. 03Jun88pJa
1 : <EMPTY> (S -- ) \ clears out <CONTEXT>.
2 <CONTEXT #VOCS 4* ERASE ;
3 : <ALSO> (S -- ) \ duplicate <CONTEXT>
4 <CONTEXT> DUP 4+ #VOCS 1- 4* CMOVE> ;
5 : <ORDER> (S -- ) \ show what <CONTEXT> is.
6 CR ." <Context>: " <CONTEXT> #VOCS 0 DO DUP @ ?DUP IF
7 BODY> >NAME .ID THEN 4+ LOOP DROP
8 CR ." <Current>: " <CURRENT> @ BODY> >NAME .ID ;
9 : <VOCS> (S -- ) \ display symbol vocabularies.
10 SYMBOL-LINK @ BEGIN DUP #THREADS 4* - BODY> >NAME .ID
11 @ DUP 0= UNTIL DROP ;
12 : <WORDS> (S -- ) \ show words (symbols) in <CONTEXT>.
13 CONTEXT @ <CONTEXT> @ CONTEXT ! WORDS CONTEXT ! ;
14
15
Again the 4+ and 4* should be 2+ and 2* for 16 bit versions. The words
work the same as the standard ONLY/ALSO extension. ONLY is replaced by
<EMPTY>. Since there is no ROOT vocabulary, it simply empties <CONTEXT>.
Make sure you invoke a vocabulary after <EMPTY>.
The last change is in the word DEFINITIONS on the last screen of Meta.blk
It should be:
H: DEFINITIONS DEFINITIONS <DEFINITIONS> CONTEXT-T @ CURRENT-T ! ;
So much for the changes in Meta.blk.
Now for the changes in Kernel.blk..
The problem is with the first word to be defined. FORTH is the first word
and is a vocabulary. It must be properly linked into the system. The
original version of L&P took care of linking the first word into
CURRENT-T. It also initialized that first word to point to it's own link.
I will repeat here the way I did it in the Amiga version, and then I will
guess at what it would be in a 16 bit version.
Amiga:
here-t dup 100 + current-t ! dup 116 + there <current> !
vocabulary forth forth definitions
dup 108 + -relocate
dup 124 + there @ dup last @ name> >body 8+ ! off
0 over 2+ !-t
dup 2+ swap 24 + dup relocate !-t
in-meta
And for 16 bits (guessing)
HERE-T DUP 100 + CURRENT-T ! DUP 108 + THERE <CURRENT> !
VOCABULARY FORTH FORTH DEFINITIONS
DUP 112 + THERE @ DUP LAST @ NAME> >BODY 4 + ! OFF
0 OVER 2+ !-T
DUP 2+ SWAP 16 + !-T
IN-META
The last change to Kernel.blk is not a problem, it is the result of the
feature of having multiple vocabularies. When another vocabulary is
created and words are to be defined in it, <CONTEXT> must now be
manipulated. For instance:
VOCABULARY DOS DOS DEFINITIONS
would hide all the FORTH defined symbols, you won't know, but at the end
of Metacompiling you will see a bunch of unresolved forward references.
You must take care in properly specifying the symbol search order.
<EMPTY> FORTH DEFINITIONS <ALSO>
VOCABULARY DOS DOS DEFINITIONS
A final note, when the Metacompiler defines a new colon word, the
<CURRENT> and <CONTEXT> are not altered. This is in contrast to the host
system, which sets CONTEXT to CURRENT at the start of a colon definition.
This way you can do the following:
<EMPTY> FORTH DEFINITIONS <ALSO> DOS
( <ORDER> = ) <Context>: DOS FORTH
<Current>: FORTH
And <CURRENT> will stay like that until the next DEFINITIONS.
At this point you can Metacompile, using the kernel you compiled in
step 1.
I hope I didn't forget anything.
Peter Appelman.