home .. forth .. colorforth mail list archive ..

RE: [colorforth] forth taxonomy


> With metacompilation you are not simply extending the internals, but
> actually describing the internals in Forth, correct? I started down this

Yes.

> compilation address is likely different from the execution address. This
> part seems tricky.

Yup.  This is why I don't bother with metacompilation.  The target compiler is
designed expressly for the purposes of generating a target image, at a target
address, designed to be run at another address.  The dialect of Forth I write
my Forth in isn't 100% the same as the Forth it's written in (sometimes it's
very different; I'm currently trying to write FS/Forth for Linux using GForth),
but I work hard to keep it as close as possible.

For example, suppose I have a definition that I want to compile:

: hw [entrypoint] ." Hello World!" CR BYE ;

Now I know that my target compiler must define :, [entrypoint], .", and ; at
the very least, in order to compile the definition into the target image.  To
facilitate this, the first thing I do is redefine : and ; thusly (remember, I'm
currently using GForth; this will change based on your specific Forth):

: H: : ;
: ;H POSTPONE ; ; IMMEDIATE

Now I can use H: and ;H throughout the rest of the target compiler's
implementation to define : and ;

H: bind ( create a target binding of the given name and the current compile
address; it's aware of the current compilation vocabulary ) ;H
H: name 32 WORD COUNT ;H
H: header name bind ;H

H: compiler? ( find word in HOST dictionary, prefixed with \\ ) ;H
H: forth? ( find word in TARGET Forth dictionary; no prefix ) ;H
H: compile, ( compile a call to a target word ) ;H
H: number, ( compile a numeric literal ) ;H

H: ] BEGIN name compiler? IF EXECUTE ELSE forth? IF compile, ELSE number, THEN
THEN AGAIN ;H
H: [ R> DROP ;H

H: : header ] ;H
H: \\;- ( compile return; tail call optimization here; etc ) ;H
H: \\; \\;- R> DROP ;H

As a side effect, we get ;- (same as EXIT in regular ANSI Forth), and the
ability to define arbitrary host-executed, target-compiler words using a prefix
\\.  Note that, ironically, THIS is what enabled me to finally see how/why
ColorForth was a better technology for Forth programming -- if every word had a
standard character prefix (\ for immediate, / for normal words, . for
variables, etc), then we wouldn't need support for IMMEDIATE words, we wouldn't
need :, etc.  The mental leap from standard character prefixes to colors wasn't
a big one.  It was more a stumble over a twig in the forest.

So, with this infrastructure, I can now define the following:

H: \\[entrypoint] ( make current definition the Forth cold-boot entry-point )
;H
H: \\." \\S" S" TYPE" forth? IF compile, ELSE TypeNotDefinedError THEN ;H
H: \\BYE ( compile code to return to Linux command line ) ;H
H: \\EMIT ( compile code to emit a character ) ;H
: CR 10 EMIT ;  ( Note -- target compiled! )

That should be everything that's really needed to do a simple target
compilation.  From here, it's a relatively straight-forward matter of saving
the binary image that exists in memory.

The disadvantage of meta/target-compiling is that you often have to write stuff
twice.  For example, the compiler is written twice, the dictionary lookup code
is written twice, etc.  But it's a small price to pay, I think -- I like the
payoff that it brings.

If you're thrifty with blocks, you can probably re-use the same block for both
host and target images.  Unfortunately, I don't have that option.

--
Samuel A. Falvo II


__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com

---------------------------------------------------------------------
To unsubscribe, e-mail: colorforth-unsubscribe@xxxxxxxxxxxxxxxxxx
For additional commands, e-mail: colorforth-help@xxxxxxxxxxxxxxxxxx
Main web page - http://www.colorforth.com