forth: Replace "SKIP?" with "(?br)"
There is an alternate git history where I continued the Forth-ification of words, including "SKIP?", but that was a bad idea: because that word was written by flow control immediates, I stepped into quicksands where stability became necessary in z80c.fs and I couldn't gracefully get out of it. I'm stepping back and take this opportunity to replace the shoddy SKIP? algo with a more straightforward (?br) implementation. (br) and (?br) will always stay in boot code where it's easier manage a stable ABI.
This commit is contained in:
parent
9fcfebd84c
commit
48078d9c9c
Binary file not shown.
@ -2,17 +2,17 @@
|
||||
: -^ SWAP - ;
|
||||
: [ INTERPRET 1 FLAGS ! ; IMMEDIATE
|
||||
: ] R> DROP ;
|
||||
: LIT [ JTBL 26 + LITN ] , ;
|
||||
: LIT JTBL 26 + , ;
|
||||
: LITS LIT SCPY ;
|
||||
: LIT< WORD LITS ; IMMEDIATE
|
||||
: _err LIT< word-not-found (print) ABORT ;
|
||||
: ' WORD (find) SKIP? _err ;
|
||||
: ['] WORD (find) SKIP? _err LITN ; IMMEDIATE
|
||||
: ' WORD (find) NOT (?br) [ 4 , ] _err ;
|
||||
: ['] ' LITN ; IMMEDIATE
|
||||
: COMPILE ' LITN ['] , , ; IMMEDIATE
|
||||
: [COMPILE] ' , ; IMMEDIATE
|
||||
: BEGIN H@ ; IMMEDIATE
|
||||
: AGAIN COMPILE (br) H@ - , ; IMMEDIATE
|
||||
: UNTIL COMPILE SKIP? COMPILE (br) H@ - , ; IMMEDIATE
|
||||
: UNTIL COMPILE (?br) H@ - , ; IMMEDIATE
|
||||
: ( BEGIN LIT< ) WORD SCMP NOT UNTIL ; IMMEDIATE
|
||||
( Hello, hello, krkrkrkr... do you hear me?
|
||||
Ah, voice at last! Some lines above need comments
|
||||
@ -29,8 +29,7 @@
|
||||
: ALLOT HERE +! ;
|
||||
|
||||
: IF ( -- a | a: br cell addr )
|
||||
COMPILE SKIP? ( if true, don't branch )
|
||||
COMPILE (br)
|
||||
COMPILE (?br)
|
||||
H@ ( push a )
|
||||
2 ALLOT ( br cell allot )
|
||||
; IMMEDIATE
|
||||
@ -73,7 +72,7 @@
|
||||
the RS )
|
||||
: LOOP
|
||||
COMPILE R> 1 LITN COMPILE + COMPILE DUP COMPILE >R
|
||||
COMPILE I' COMPILE = COMPILE SKIP? COMPILE (br)
|
||||
COMPILE I' COMPILE = COMPILE (?br)
|
||||
H@ - ,
|
||||
COMPILE R> COMPILE DROP COMPILE R> COMPILE DROP
|
||||
; IMMEDIATE
|
||||
|
@ -73,10 +73,9 @@ 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
|
||||
input stream is executed immediately. In this context, branching doesn't work.
|
||||
|
||||
(fbr) -- Branches forward by the number specified in its
|
||||
atom's cell.
|
||||
(bbr) -- Branches backward by the number specified in its
|
||||
atom's cell.
|
||||
(br) -- Branches by the number specified in the 2 following
|
||||
bytes. Can be negative.
|
||||
(?br) f -- Branch if f is false.
|
||||
[ -- Begin interetative mode. In a definition, words
|
||||
between here and "]" will be executed instead of
|
||||
compiled.
|
||||
@ -92,9 +91,6 @@ INTERPRET -- Get a line from stdin, compile it in tmp memory,
|
||||
then execute the compiled contents.
|
||||
QUIT R:drop -- Return to interpreter prompt immediately
|
||||
RECURSE R:I -- R:I-2 Run the current word again.
|
||||
SKIP? f -- If f is true, skip the execution of the next atom.
|
||||
Use this right before ";" and you're gonna have a
|
||||
bad time.
|
||||
THEN I:a -- *I* Set branching cell at a.
|
||||
UNTIL f -- *I* Jump backwards to BEGIN if f is *false*.
|
||||
|
||||
|
@ -670,61 +670,28 @@ BR:
|
||||
ld (IP), hl
|
||||
jp next
|
||||
|
||||
; Skip the compword where HL is currently pointing. If it's a regular word,
|
||||
; it's easy: we inc by 2. If it's a NUMBER, we inc by 4. If it's a LIT, we skip
|
||||
; to after null-termination.
|
||||
.db "SKIP?"
|
||||
.fill 72
|
||||
|
||||
.db "(?br)"
|
||||
.dw $-BR
|
||||
.db 5
|
||||
CSKIP:
|
||||
CBR:
|
||||
.dw nativeWord
|
||||
pop hl
|
||||
call chkPS
|
||||
ld a, h
|
||||
or l
|
||||
jp z, next ; False, do nothing.
|
||||
ld hl, (IP)
|
||||
ld de, NUMBER
|
||||
call .HLPointsDE
|
||||
jr z, .isNum
|
||||
ld de, BR
|
||||
call .HLPointsDE
|
||||
jr z, .isNum
|
||||
ld de, LIT
|
||||
call .HLPointsDE
|
||||
jr nz, .isWord
|
||||
; We have a literal
|
||||
inc hl \ inc hl
|
||||
call strskip
|
||||
inc hl ; byte after word termination
|
||||
jr .end
|
||||
.isNum:
|
||||
; skip by 4
|
||||
inc hl
|
||||
inc hl
|
||||
; continue to isWord
|
||||
.isWord:
|
||||
; skip by 2
|
||||
inc hl \ inc hl
|
||||
.end:
|
||||
ld (IP), hl
|
||||
jp z, BR+2 ; False, branch
|
||||
; True, skip next 2 bytes and don't branch
|
||||
ld hl, IP
|
||||
inc (hl)
|
||||
inc (hl)
|
||||
jp next
|
||||
|
||||
; Sets Z if (HL) == E and (HL+1) == D
|
||||
.HLPointsDE:
|
||||
ld a, (hl)
|
||||
cp e
|
||||
ret nz ; no
|
||||
inc hl
|
||||
ld a, (hl)
|
||||
dec hl
|
||||
cp d ; Z has our answer
|
||||
ret
|
||||
|
||||
.fill 45
|
||||
.fill 18
|
||||
|
||||
.db ","
|
||||
.dw $-CSKIP
|
||||
.dw $-CBR
|
||||
.db 1
|
||||
WR:
|
||||
.dw nativeWord
|
||||
@ -1046,3 +1013,5 @@ CMP:
|
||||
.db "_bend"
|
||||
.dw $-CMP
|
||||
.db 5
|
||||
; Offset: 06ee
|
||||
.out $
|
||||
|
@ -54,7 +54,7 @@
|
||||
( This is only the "early parser" in earlier stages. No need
|
||||
for an abort message )
|
||||
: (parse)
|
||||
(parsed) SKIP? _c ABORT
|
||||
(parsed) NOT IF _c ABORT THEN
|
||||
;
|
||||
|
||||
( a -- )
|
||||
|
@ -75,10 +75,10 @@
|
||||
;
|
||||
|
||||
: (parse) ( a -- n )
|
||||
(parsec) NOT SKIP? EXIT
|
||||
(parseh) NOT SKIP? EXIT
|
||||
(parseb) NOT SKIP? EXIT
|
||||
(parsed) NOT SKIP? EXIT
|
||||
(parsec) IF EXIT THEN
|
||||
(parseh) IF EXIT THEN
|
||||
(parseb) IF EXIT THEN
|
||||
(parsed) IF EXIT THEN
|
||||
( nothing works )
|
||||
ABORT" unknown word! "
|
||||
;
|
||||
|
@ -4,6 +4,6 @@
|
||||
|
||||
: fail SPC ." failed" LF 1 1 PC! BYE ;
|
||||
|
||||
: # SKIP? fail SPC ." pass" LF ;
|
||||
: # IF SPC ." pass" LF ELSE fail THEN ;
|
||||
|
||||
: #eq 2DUP SWAP . SPC '=' EMIT SPC . '?' EMIT = # ;
|
||||
|
Loading…
Reference in New Issue
Block a user