Some FORTH systems even have a "metacompiler" that lets one FORTH system compile another FORTH system for the same or different CPU, word size, byte order, threading technique, with or without a built-in compiler, etc, from the same source code!
OpenFirmware (the FORTH burnt into boot roms of SPARC, PowerPC, OLPC, and other systems) is a great highly refined example that supports many different architectures:
It seems like there should be a clarification in the article about the difference in the use of the term. These are not threads at all in the more typical sense used more in computing today.
Good point, that could be the source of confusion! The "Threaded" in "Threaded Interpretive Language" has a very different meaning than operating system or cpu "thread".
>A ThreadedInterpreter is an interpreter written using a technique called threading (not to be confused with threads for concurrency) that entwines the 'get next instruction' operation of the interpreter with the actual instruction. This reduces the 'get next instruction' overhead and generally results in a 10% performance increase. [...]
>An excellent work on this subject, containing a complete TIL implementation for the Z-80, is Loeliger's book ("Threaded Interpretive Languages" R.G. Loeliger, Byte Books 1981, ISBN 0-07-038360-X).
I have a copy (I should have bought three) that I picked up in the years of Forth's waning "public" popularity. I've seldom had a such a lucid book that described the implementation details of a language.
"Threaded Interpretive Languages: Their Design and Implementation", by R.G. Loeliger:
6502 FORTHs have to work around a bug on the 6502 processor (which was fixed in later revisions like the 65C02):
The inner interpreter (NEXT) uses the indirect absolute jump instruction and self modifying code that patches the code field address into the jump instruction before executing it:
JMP ($ABCD)
However if the address is like $xxFF, the code field of the word it's jumping through straddles a 256-byte page boundary, and the 6502 mistakenly wraps around to the beginning of the same page to fetch the second byte of the address, instead of going to the next page.
So the compiler (usually CREATE) has to check before creating a new word, to make sure that its code field address will land at $xxFF, and allocate an extra byte of padding first to prevent that from happening.
I found this out the hard way when developing my own 6502 FORTH. I'd make some tweak to the assembly or FORTH source and recompile, then some essential old reliable word that always used to work would suddenly start failing catastrophically. So I'd enable debugging and recompile, and the problem would go away, or move to some other totally unrelated word! A classic Heisenbug! I finally found the problem and solution by looking at 6502 FIG FORTH.
; The following offset adjusts all code fields to avoid an
; address ending $XXFF. This must be checked and altered on
; any alteration , for the indirect jump at W-1 to operate !
;
.ORIGIN *+2
[...]
.WORD DP ;)
.WORD CAT ;| 6502 only. The code field
.WORD CLIT ;| must not straddle page
.BYTE $FD ;| boundaries
.WORD EQUAL ;|
.WORD ALLOT ;)
FIG-FORTH is pre-FORTH-83, so EQUAL returns 1 or 0 instead of -1 or 0. And ahem DP is the Dictionary Pointer, CAT is C@, while CLIT is Character LITeral, of course. :-|
I had a mental hiccup and for a couple seconds and interpreted the headline as a movie title. I got excited there was a movie to watch about Forth. I’m such a nerd.
OpenFirmware (the FORTH burnt into boot roms of SPARC, PowerPC, OLPC, and other systems) is a great highly refined example that supports many different architectures:
openfirmware/forth/kernel/metacompile.fth
https://github.com/openbios/openfirmware/blob/d5cc657ce81c0f...
openfirmware/forth/kernel/meta1.fth
https://github.com/openbios/openfirmware/blob/d5cc657ce81c0f...