STM8EF had a serious bug in COMPILE which not only corrupted the return stack, but also managed to do that in a really sneaky way: it was inoffensive as long as COMPILE was called just once in a ACCEPT-EVAL loop (i.e. most of the time). As soon as COMPILE was used at least twice, the flow of compilation was corrupted (and sometimes even reversed).
The bug was one of a kind, one that deserves a place in my Cabinets of Curiosities :-)
Anyhow, it's gone, STM8EF is better tested now, and I'm a step closer to implementing DOES>.
PS: COMPILE is part of the Forth kernel and is used for extending the compiler. When executed, COMPILE reads the following (already compiled) word and stores it at the top of the code dictionary. To do that, the pointer on the return stack (IP in ITC Forth) has to be increment to the word following the next word.
In STC (Subroutine Threaded Code) the compiled code looks like this:
; COMPILE ( -- )
; Compile next jsr in
; colon list to code dictionary.
.dw LINK
LINK = .
.db (COMPO+7)
.ascii "COMPILE"
COMPI:
CALL RFROM ; R>
CALL ONEP ; 1+
CALL DUPP ; DUP
CALL AT ; @
CALL JSRC ; CODE, compile subroutine
CALL CELLP ; 2+
JP TOR ; >R and EXIT
The shortcut "JP" for "CALL and EXIT" is where the code was wrong: the updated IP was added as second item on the return stack - it didn't replace the actual return address of COMPILE.
Actually CALLing ">R" does something more than just adding something to the return stack. JPing violates the assumption at the base of the implementation of ">R".
The following code works as expected:
CALL CELLP ; 2+
CALL TOR ; >R
RET ; EXIT
A well tested Forth implementation will never face the user with such a problem. However, if you're implementing your own Forth, this is the kind of things you have to be aware of!
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.