forth: fix IF/THEN/ELSE in colon defs

This commit is contained in:
Virgil Dupras 2020-03-11 17:53:27 -04:00
parent 02b56c547a
commit 3996f0c825
3 changed files with 52 additions and 66 deletions

View File

@ -242,71 +242,35 @@ DEFINE:
; All we need to do is to know how many bytes to copy. To do so, we ; All we need to do is to know how many bytes to copy. To do so, we
; skip compwords until EXIT is reached. ; skip compwords until EXIT is reached.
ex de, hl ; DE is our dest ex de, hl ; DE is our dest
ld (HERE), de ; update HERE
ld l, (ix) ld l, (ix)
ld h, (ix+1) ld h, (ix+1)
.loop: .loop:
call HLPointsNUMBER call HLPointsEXIT
jr nz, .notNUMBER jr z, .loopend
; is number call compSkip
ld bc, 4
ldir
jr .loop jr .loop
.notNUMBER: .loopend:
call HLPointsLIT ; skip EXIT
jr nz, .notLIT inc hl \ inc hl
; is lit ; We have out end offset. Let's get our offset
ldi ld e, (ix)
ldi ld d, (ix+1)
call strcpyM or a ; clear carry
jr .loop sbc hl, de
.notLIT: ; HL is our copy count.
; it's a word ld b, h
call HLPointsIMMED ld c, l
jr nz, .notIMMED
; Immediate word, we'll have to call it.
; Before we make our call, let's save our current HL/DE position
ld (CMPDST), de
ld e, (hl)
inc hl
ld d, (hl)
inc hl ; point to next word
push de \ pop iy ; prepare for executeCodeLink
ld (ix), l
ld (ix+1), h
; Push return address
ld hl, .retList
call pushRS
; Ready!
jp executeCodeLink
.notIMMED:
; a good old regular word. We have 2 bytes to copy. But before we do,
; let's check whether it's an EXIT. LDI doesn't affect Z, so we can
; make our jump later.
call HLPointsEXITQUIT
ldi
ldi
jr nz, .loop
; HL has our new RS' TOS
ld (ix), l
ld (ix+1), h
ld (HERE), de ; update HERE
jp exit
; This label is pushed to RS when an IMMED word is called. When that word calls
; exit, this is where it returns. When we return, RS will need to be popped so
; that we stay on the proper RS level.
.retList:
.dw .retWord
.retWord:
.dw .retEntry
.retEntry:
call popRS ; unwind stack
; recall old HL / DE values
ld l, (ix) ld l, (ix)
ld h, (ix+1) ld h, (ix+1)
ld de, (CMPDST) ld de, (HERE) ; recall dest
; continue! ; copy!
jr .loop ldir
ld (ix), l
ld (ix+1), h
ld (HERE), de
jp exit
.db "DOES>" .db "DOES>"
.fill 3 .fill 3

View File

@ -123,7 +123,9 @@ forthInterpret:
.retRef: .retRef:
.dw $+2 .dw $+2
.dw forthInterpret .dw $+2
call popRS
jr forthInterpret
msgOk: msgOk:
.db " ok", 0 .db " ok", 0

View File

@ -69,14 +69,28 @@ HLPointsLIT:
pop de pop de
ret ret
HLPointsEXITQUIT: HLPointsBRANCH:
push de
ld de, BRANCH
call HLPointsDE
jr z, .end
ld de, CBRANCH
call HLPointsDE
.end:
pop de
ret
HLPointsEXIT:
push de push de
ld de, EXIT ld de, EXIT
call HLPointsDE call HLPointsDE
jr z, .end pop de
ret
HLPointsQUIT:
push de
ld de, QUIT ld de, QUIT
call HLPointsDE call HLPointsDE
.end:
pop de pop de
ret ret
@ -85,7 +99,9 @@ HLPointsEXITQUIT:
; to after null-termination. ; to after null-termination.
compSkip: compSkip:
call HLPointsNUMBER call HLPointsNUMBER
jr z, .isNum jr z, .isNumOrBranch
call HLPointsBRANCH
jr z, .isNumOrBranch
call HLPointsLIT call HLPointsLIT
jr nz, .isWord jr nz, .isWord
; We have a literal ; We have a literal
@ -93,7 +109,7 @@ compSkip:
call strskip call strskip
inc hl ; byte after word termination inc hl ; byte after word termination
ret ret
.isNum: .isNumOrBranch:
; skip by 4 ; skip by 4
inc hl \ inc hl inc hl \ inc hl
; continue to isWord ; continue to isWord
@ -160,7 +176,11 @@ readLIT:
; it's a word. ; it's a word.
call HLPointsNUMBER call HLPointsNUMBER
jr z, .notWord jr z, .notWord
call HLPointsEXITQUIT call HLPointsBRANCH
jr z, .notWord
call HLPointsEXIT
jr z, .notWord
call HLPointsQUIT
jr z, .notWord jr z, .notWord
; Not a number, then it's a word. Copy word to pad and point to it. ; Not a number, then it's a word. Copy word to pad and point to it.
push hl ; --> lvl 1. we need it to set DE later push hl ; --> lvl 1. we need it to set DE later