diff --git a/apps/forth/core.fs b/apps/forth/core.fs index 5f72445..3b62283 100644 --- a/apps/forth/core.fs +++ b/apps/forth/core.fs @@ -5,22 +5,28 @@ : , H ! 2 ALLOT ; : C, H C! 1 ALLOT ; : BEGIN H ; IMMEDIATE -: AGAIN ['] (bbr) , H -^ C, ; IMMEDIATE +: COMPILE ' ['] LITN EXECUTE ['] , , ; IMMEDIATE +: AGAIN COMPILE (bbr) H -^ C, ; IMMEDIATE : NOT 1 SWAP SKIP? EXIT 0 * ; : ( BEGIN LITS ) WORD SCMP NOT SKIP? AGAIN ; IMMEDIATE ( Hello, hello, krkrkrkr... do you hear me? Ah, voice at last! Some lines above need comments BTW: Forth lines limited to 64 cols because of default 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, - to PS ) -: IF ['] SKIP? , ['] (fbr) , H 1 ALLOT ; IMMEDIATE + + COMPILE; Tough one. Get addr of caller word (example above + (bbr)) and then call LITN on it. However, LITN is an + 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 br cell ) : THEN DUP H -^ SWAP C! ; IMMEDIATE ( 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 ; : CONSTANT CREATE H ! DOES> @ ; diff --git a/apps/forth/dict.asm b/apps/forth/dict.asm index 6127bc1..f75e39f 100644 --- a/apps/forth/dict.asm +++ b/apps/forth/dict.asm @@ -225,7 +225,7 @@ EXECUTE: jp (hl) ; go! - .db "COMPILE" + .db "[COMPIL" .dw EXECUTE .db 1 ; IMMEDIATE COMPILE: diff --git a/apps/forth/dictionary.txt b/apps/forth/dictionary.txt index c892bc7..a4a6a1d 100644 --- a/apps/forth/dictionary.txt +++ b/apps/forth/dictionary.txt @@ -42,13 +42,28 @@ directly, but as part of another word. ALLOT n -- Move HERE by n bytes C, b -- Write byte b in HERE and advance it. 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 DOES> -- See description at top of file IMMEDIATE -- Flag the latest defined word as immediate. LITN n -- *I* Inserts number from TOS as a literal 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 *** 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