Anyway. To cut to the chase, pijFORTHos was missing the ;CODE functionality from Jonesforth 47, which let you define native machine words in Forth... i.e. an assembler, basically. A couple of completely empty and useless examples that do nothing (and yet not crash) would look like:
: FOO ;CODE : BAR $NEXT ;CODEThe later is redundant, since $NEXT is already emitted by ;CODE. The implementation is straighforward.. Although I took the liberty of sticking it into jonesforth.s instead of the Forth prelude, and in the actual commit I'm a bit smarter about defining $NEXT and the actual _NEXT/NEXT bits used by the Forth core itself. You wonder why bother emitting the NEXT bits inline instead of branching, but the later would take up 3 cells as well (ldr, bx and immed for ldr) and also involve a branch. Look at how the $NEXT word is defined. Isn't this crazy? It's an IMMEDIATE word that writes literals, which just happen to be machine code, at HERE, effectively compiling them into the current word definition when used in compiler mode (such as a colon definition).
@ @ $NEXT ( -- ) emits the _NEXT body at HERE, to be used @ in ;CODE or ;CODE-defined words. @ defword "$NEXT",F_IMM,ASMNEXT .int LIT ldr r0, [FIP], #4 .int COMMA .int LIT ldr r1, [r0] .int COMMA .int LIT bx r1 .int COMMA .int EXIT @ @ Finishes a machine code colon definition in Forth, as @ a really basic assembler. @ defword ";CODE",F_IMM,SEMICODE .int ASMNEXT @ end the word with NEXT macro .int LATEST, FETCH, DUP @ LATEST points to the compiled word .int HIDDEN @ unhide the compiled word .int DUP, TDFA, SWAP, TCFA, STORE @ set codeword to data instead of DOCOL .int LBRAC @ just like ";" exit compile mode .int EXIT
No comments:
Post a Comment