forth: separate COMPILE and [COMPILE]

This commit is contained in:
Virgil Dupras 2020-03-16 21:31:43 -04:00
parent f404c2f4d0
commit aec98a7a3a
3 changed files with 29 additions and 8 deletions

View File

@ -5,22 +5,28 @@
: , H ! 2 ALLOT ; : , H ! 2 ALLOT ;
: C, H C! 1 ALLOT ; : C, H C! 1 ALLOT ;
: BEGIN H ; IMMEDIATE : BEGIN H ; IMMEDIATE
: AGAIN ['] (bbr) , H -^ C, ; IMMEDIATE : COMPILE ' ['] LITN EXECUTE ['] , , ; IMMEDIATE
: AGAIN COMPILE (bbr) H -^ C, ; IMMEDIATE
: NOT 1 SWAP SKIP? EXIT 0 * ; : NOT 1 SWAP SKIP? EXIT 0 * ;
: ( BEGIN LITS ) WORD SCMP NOT SKIP? AGAIN ; IMMEDIATE : ( BEGIN LITS ) WORD SCMP NOT SKIP? AGAIN ; IMMEDIATE
( Hello, hello, krkrkrkr... do you hear me? ( Hello, hello, krkrkrkr... do you hear me?
Ah, voice at last! Some lines above need comments Ah, voice at last! Some lines above need comments
BTW: Forth lines limited to 64 cols because of default BTW: Forth lines limited to 64 cols because of default
input buffer size in Collapse OS input buffer size in Collapse OS
NOT: a bit convulted because we don't have IF yet
IF true, skip following (fbr). Also, push br cell ref H, COMPILE; Tough one. Get addr of caller word (example above
to PS ) (bbr)) and then call LITN on it. However, LITN is an
: IF ['] SKIP? , ['] (fbr) , H 1 ALLOT ; IMMEDIATE immediate and has to be indirectly executed. Then, write
a reference to "," so that this word is written to HERE.
NOT: a bit convulted because we don't have IF yet )
: IF COMPILE SKIP? COMPILE (fbr) H 1 ALLOT ; IMMEDIATE
( Subtract TOS from H to get offset to write to IF or ELSE's ( Subtract TOS from H to get offset to write to IF or ELSE's
br cell ) br cell )
: THEN DUP H -^ SWAP C! ; IMMEDIATE : THEN DUP H -^ SWAP C! ; IMMEDIATE
( write (fbr) addr, allot, then same as THEN ) ( write (fbr) addr, allot, then same as THEN )
: ELSE ['] (fbr) , 1 ALLOT DUP H -^ SWAP C! H 1 - ; IMMEDIATE : ELSE
COMPILE (fbr) 1 ALLOT DUP H -^ SWAP C! H 1 - ; IMMEDIATE
: ? @ . ; : ? @ . ;
: VARIABLE CREATE 2 ALLOT ; : VARIABLE CREATE 2 ALLOT ;
: CONSTANT CREATE H ! DOES> @ ; : CONSTANT CREATE H ! DOES> @ ;

View File

@ -225,7 +225,7 @@ EXECUTE:
jp (hl) ; go! jp (hl) ; go!
.db "COMPILE" .db "[COMPIL"
.dw EXECUTE .dw EXECUTE
.db 1 ; IMMEDIATE .db 1 ; IMMEDIATE
COMPILE: COMPILE:

View File

@ -42,13 +42,28 @@ directly, but as part of another word.
ALLOT n -- Move HERE by n bytes ALLOT n -- Move HERE by n bytes
C, b -- Write byte b in HERE and advance it. C, b -- Write byte b in HERE and advance it.
CREATE x -- Create cell named x. Doesn't allocate a PF. CREATE x -- Create cell named x. Doesn't allocate a PF.
COMPILE x -- Compile word x and write it to HERE [COMPILE] x -- Compile word x and write it to HERE
COMPILE x -- Meta compiles. Kind of blows the mind. See below.
CONSTANT x n -- Creates cell x that when called pushes its value CONSTANT x n -- Creates cell x that when called pushes its value
DOES> -- See description at top of file DOES> -- See description at top of file
IMMEDIATE -- Flag the latest defined word as immediate. IMMEDIATE -- Flag the latest defined word as immediate.
LITN n -- *I* Inserts number from TOS as a literal LITN n -- *I* Inserts number from TOS as a literal
VARIABLE c -- Creates cell x with 2 bytes allocation. VARIABLE c -- Creates cell x with 2 bytes allocation.
Compilation vs meta-compilation. When you compile a word with "[COMPILE] foo",
its straightforward: It writes down to HERE wither the address of the word or
a number literal.
When you *meta* compile, it's a bit more mind blowing. It fetches the address
of the word specified by the caller, then writes that number as a literal,
followed by a reference to ",".
Example: ": foo [COMPILE] bar;" is the equivalent of ": foo bar ;" if bar is
not an immediate. However, ": foo COMPILE bar ;" is the equivalent of
": foo ['] bar , ;". Got it?
Meta-compile only works with real words, not number literals.
*** Flow *** *** Flow ***
Note about flow words: flow words can only be used in definitions. In the Note about flow words: flow words can only be used in definitions. In the
INTERPRET loop, they don't have the desired effect because each word from the INTERPRET loop, they don't have the desired effect because each word from the