Devlog 11 Completing Colon
December 1, 2022
I think this session will be short since I only plan to “complete” the
OK so I wrote quite a few lines of code to finish this definition, without logging what I was doing. So I’ll start by showing what a word definition should look like in memory:
+----------+----------+----------+ | LINK | HASH | CODEWORD | +----------+----------+----------+ 32-bit 32-bit 32-bit
It’s similar to how jonesforth does it, except we don’t need to store the length of the word.
I realized later that we need to set the
HIDDEN flag inside the hash (in the second bit starting from the MSB), to ensure the it can’t be found during a lookup in compilation mode:
# set the hidden flag in the hash li t0, F_HIDDEN # load hidden flag into temporary or a0, a0, t0 # hide the word
Next, I want to load some variables into temporary registers, because I’ll use them later:
# copy the memory address of some variables to temporary registers li t0, HERE li t1, LATEST la t2, enter # load the codeword address into temporary # FIXME: enter or docol?
Notice I put a
# FIXME for loading the address of the
enter label. I did that because derzforth uses it as the codeword, but I have a feeling I may be mistaken in copying that implementation. sectorforth and jonesforth point to docol, so I need to read more about this later.
Next I want to load the actual values pointed by the
# load and update memory addresses from variables lw t3, 0(t0) # load the new start address of the current word into temporary (HERE) lw t4, 0(t1) # load the address of the previous word into temporary (LATEST)
They’re stored in different temporary registers because we’ll need to write to
t1 later. This should save a couple instructions.
From here it becomes quite simple, we’re first going to update the
LATEST variable to point to the value pointed by
HERE. Essentially we want
LATEST to point to this new word’s start address.
# update LATEST variable sw t3, 0(t1) # store the current value of HERE into the LATEST variable
Then we’re going to build the header (LINK, HASH, CODEWORD) by storing it in memory at the
# build the header in memory sw t4, 0(t3) # store the address of the previous word sw a0, 4(t3) # store the hash sw t2, 8(t3) # store the codeword address
The LINK mentioned above is the address of the previous word, aka
The next step is to update the
HERE variable, similarly to what we did with
LATEST above, except we’re now going to point
HERE to the end of the word:
# update HERE variable addi t3, t3, 12 # move the HERE pointer to the end of the word sw t3, 0(t0) # store the new address of HERE into the HERE variable
I’m using a 12-byte offset because we stored
3 * 32 (
96 bits / 12 bytes) of data in memory.
The final step in our
COLON definition is to update the
STATE variable. We want to set it to
1 so the interpreter knows we’re now in compilation mode:
# update STATE variable li t0, STATE # load the address of the STATE variable into temporary li t1, 1 # set the STATE variable to compile mode (1 = compile) sw t1, 0(t0) # store the current state back into the STATE variable NEXT
I think (hope?) that completes the
The good news is the code still compiles, and I can run it just fine in the Ripes simulator. Inspecting the memory addresses and registers confirms that the code works as expected, and the correct values are stored in the correct locations, but I still need to figure out the whole codeword thing (enter/docol?).
In the next session, I’m hoping to fully understand the roles of
enter, and maybe move onto the next missing primitive: