feat(v4.0.0): CASE, ['], S", WORDS, FORGET and FENCE

- compile.v4: CASE OF ENDOF ENDCASE, as v3 (they nest; a word out of
  place is a control structure mismatch); ['] and [LITERAL].
- quit.v4: S" and its run-time word; at the prompt the text is copied to
  PAD.
- capsule/system.v4: WORDS and VLIST; FORGET (FORTH-79), which gives the
  space back and will not remove a word below FENCE -- the capsule's own
  words -- where v3's FORGET DUP succeeds.
- tests/test_host_quit.c: ten more transcripts of the v3 binary, and
  nesting, the fence and the listing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-04 20:49:53 -04:00
co-authored by Claude Opus 5.5
parent c02505db69
commit e7d686c7a2
7 changed files with 174 additions and 10 deletions
+41 -1
View File
@@ -177,6 +177,13 @@ header LITERAL immediate
header ' immediate
: TICK (') jump LITERAL
\ ['] xxx the same inside a definition, whatever STATE is; and [LITERAL],
\ which v3 has as another name for LITERAL.
header ['] immediate compile-only
: BRACKET-TICK (') jump (LIT,)
header [LITERAL] immediate
: BRACKET-LITERAL jump LITERAL
\ ---- colon definitions -----------------------------------------------------------
\ FORTH-79: start a definition; it cannot be found until ; ends it.
@@ -263,7 +270,7 @@ header DOES> immediate compile-only
\ ---- control structures (5.18, section 2) ---------------------------------------------
\ All immediate and compile-only. Each puts what the word that closes it
\ needs on the control-flow stack, with a number on top saying which word put
\ it there: 1 IF, 2 ELSE, 3 BEGIN, 4 WHILE, 5 DO, 6 ?DO. A closing word that
\ it there: 1 IF, 2 ELSE, 3 BEGIN, 4 WHILE, 5 DO, 6 ?DO, 7 CASE, 8 OF. A closing word that
\ finds the wrong number abandons the line.
\ ( tag wanted -- ) if they differ, abandon the line and leave the control
@@ -319,6 +326,39 @@ header REPEAT immediate compile-only
CF> 3 (PAIR) CF> (JUMP,) CF> drop
(C)+6 a! @ (HERE!) 23 jump (OP,)
\ CASE: the value being chosen on stays on the stack through the clauses.
\ CASE x1 OF a ENDOF x2 OF b ENDOF c ENDCASE
\ lays, for each clause,
\ over xor if M drop jump N M: drop drop a jump END N:
\ and ENDCASE lays the drop that the part after the last ENDOF leaves the
\ value for, with END after it. The control-flow stack holds the jumps to
\ END, how many there are, and 7; inside a clause, the jump to N and 8.
: (of) over xor ;
header CASE immediate compile-only
: CASE 0 >CF 7 jump >CF
header OF immediate compile-only
: OF
CF> 7 (PAIR)
&(of) (INLINE,) 6 (BRANCH>) (C)+6 a! ! \ if M
23 (OP,) 2 (BRANCH>) >CF \ drop, jump N
(C)+6 a! @ (HERE!) 23 (OP,) 23 (OP,) \ M: drop drop
8 jump >CF
header ENDOF immediate compile-only
: ENDOF
CF> 8 (PAIR) CF> (C)+6 a! ! \ the jump to N
CF> (C)+7 a! ! \ how many jumps to END so far
2 (BRANCH>) >CF \ one more
(C)+7 a! @ 1 + >CF
(C)+6 a! @ (HERE!) \ N:
7 jump >CF
header ENDCASE immediate compile-only
: ENDCASE
CF> 7 (PAIR) CF> (C)+7 a! !
23 (OP,)
L: (C)+7 a! @ if DONE -1 + !
CF> (HERE!) jump L
DONE: drop ;
\ DO loops: the limit and index are on the return stack, limit below (5.18).
: (do) over push push drop ;
: (?do) over over xor ;