forth: remove CMPDST

We now always do ","-style writes in (HERE), even in IMMEDIATE mode. Simplifies
things and paves the way for compiling words in Forth.
This commit is contained in:
Virgil Dupras 2020-03-12 13:08:11 -04:00
parent ff281f69a8
commit 3819dbc083
2 changed files with 36 additions and 22 deletions

View File

@ -332,12 +332,12 @@ IMMEDIATE:
.db 1 ; IMMEDIATE
LITERAL:
.dw nativeWord
ld hl, (CMPDST)
ld hl, (HERE)
ld de, NUMBER
call DEinHL
pop de ; number from stack
call DEinHL
ld (CMPDST), hl
ld (HERE), hl
jp exit
; ( -- c )
@ -641,12 +641,12 @@ IF:
; Spit a conditional branching atom, followed by an empty 1b cell. Then,
; push the address of that cell on the PS. ELSE or THEN will pick
; them up and set the offset.
ld hl, (CMPDST)
ld hl, (HERE)
ld de, CBRANCH
call DEinHL
push hl ; address of cell to fill
inc hl ; empty 1b cell
ld (CMPDST), hl
ld (HERE), hl
jp exit
.db "ELSE"
@ -657,7 +657,7 @@ ELSE:
.dw nativeWord
; First, let's set IF's branching cell.
pop de ; cell's address
ld hl, (CMPDST)
ld hl, (HERE)
; also skip ELSE word.
inc hl \ inc hl \ inc hl
or a ; clear carry
@ -667,12 +667,12 @@ ELSE:
; Set IF's branching cell to current atom address and spit our own
; uncondition branching cell, which will then be picked up by THEN.
; First, let's spit our 4 bytes
ld hl, (CMPDST)
ld hl, (HERE)
ld de, BRANCH
call DEinHL
push hl ; address of cell to fill
inc hl ; empty 1b cell
ld (CMPDST), hl
ld (HERE), hl
jp exit
.db "THEN"
@ -683,7 +683,7 @@ THEN:
.dw nativeWord
; See comments in IF and ELSE
pop de ; cell's address
ld hl, (CMPDST)
ld hl, (HERE)
; There is nothing to skip because THEN leaves nothing.
or a ; clear carry
sbc hl, de ; HL now has relative offset

View File

@ -21,9 +21,6 @@
.equ HERE @+2
; Pointer to where we currently are in the interpretation of the current line.
.equ INPUTPOS @+2
; Pointer to where compiling words should output. During interpret, it's a
; moving target in (COMPBUF). During DEFINE, it's (HERE).
.equ CMPDST @+2
; Buffer where we compile the current input line. Same size as STDIO_BUFSIZE.
.equ COMPBUF @+2
.equ FORTH_RAMEND @+0x40
@ -38,19 +35,29 @@
;
; 1. read single word from line
; 2. compile word to atom
; 3. execute atom
; 4. goto 1
; 3. if immediate, execute atom
; 4. goto 1 until we exhaust words
; 5. Execute compiled atom list as if it was a regular compiledWord.
;
; During step 3, it's possible that atom read from input, so INPUTPOS might
; have moved between 3 and 4.
;
; Because the Parameter Stack uses PS, we can't just go around calling routines:
; Because the Parameter Stack uses SP, we can't just go around calling routines:
; This messes with the PS. This is why we almost always jump (unless our call
; doesn't involve Forth words in any way).
;
; This presents a challenge for our interpret loop because step 4, "goto 1"
; isn't obvious. To be able to do that, we must push a "return routine" to the
; Return Stack before step 3.
;
; HERE and IMMEDIATE: When compiling in step 2, we spit compiled atoms in
; (HERE) to simplify "," semantic in Forth (spitting, in all cases, is done in
; (HERE)). However, suring input line compilation, it isn't like during ":", we
; aren't creating a new entry.
;
; Compiling and executing from (HERE) would be dangerous because an
; entry-creation word, during runtime, could end up overwriting the atom list
; we're executing. This is why we have this list in COMPBUF.
;
; During IMMEDIATE mode, (HERE) is temporarily set to COMPBUF, and when we're
; done, we restore (HERE) for runtime. This way, everyone is happy.
; *** Code ***
forthMain:
@ -78,8 +85,12 @@ forthRdLine:
call stdioReadLine
ld ix, RS_ADDR-2 ; -2 because we inc-before-push
ld (INPUTPOS), hl
; We're about to compile the line and possibly execute IMMEDIATE words.
; Let's save current (HERE) and temporarily set it to COMPBUF.
ld hl, (HERE)
push hl ; Saving HERE
ld hl, COMPBUF
ld (CMPDST), hl
ld (HERE), hl
forthInterpret:
call readword
jr nz, .execute
@ -111,9 +122,9 @@ forthInterpret:
; called, triggering an abort.
ld de, LIT
call .writeDE
ld de, (CMPDST)
ld de, (HERE)
call strcpyM
ld (CMPDST), de
ld (HERE), de
jr forthInterpret
.immed:
push hl ; --> lvl 1
@ -124,16 +135,19 @@ forthInterpret:
.execute:
ld de, QUIT
call .writeDE
; Compilation done, let's restore (HERE) and execute!
pop hl ; Restore old (HERE)
ld (HERE), hl
ld iy, COMPBUF
jp compiledWord
.writeDE:
push hl
ld hl, (CMPDST)
ld hl, (HERE)
ld (hl), e
inc hl
ld (hl), d
inc hl
ld (CMPDST), hl
ld (HERE), hl
pop hl
ret