Now, for logic and math:
Especially since I am going to have a "preliminary" hex literal evaluation if the token fails to be found as a word, I am fine with just "+" as the underlying primitive for 1+, 2+, -, 1- etc.
However, after working out / looking at the implementation of NOT, AND OR and XOR using NAND alone, I decided that I am OK with:
: NOT ( x1 -- x2 ) DUP NAND ;
: AND ( x1 x2 -- x3 ) NAND DUP NAND ;
... but the definition of OR and XOR with NAND alone was just too much for me, so I've added "OR" as a primitive, which then also allows a simpler XOR since:
Code:
0 1 0 1 -- bit in x1
0 0 1 1 -- bit in x2
1 1 1 0 -- NAND(x1,x2)
0 1 1 1 -- OR(x1,x2)
0 1 1 0 -- x3 = AND(NAND(x1,X2),OR(x1,x2))
So rather than the theoretical minimum NAND (or alternatively NOR) from which to build all logic, I got with the more practical set of NAND and OR as primitives.
Another big change I've made is going from embedded dictionary to a block dictionary. Length+Flags Byte up front, then as many characters as the length byte says, then the code field address, then the preceding entry in the dictionary. LATEST points to the bottom of the dictionary block, and adding a new entry is done by subtracting two from LASTEST, writing the address in HERE there, then subtracting the length +1 from LATEST, writing the counted string there, and finally setting any flags if need be. On loading, the dictionary block would be written to the top of RAM, so LATEST grows down from the top of RAM while HERE grows up toward the top of RAM. That copy is simplified because the dictionary contain any addresses located within the dictionary itself -- it has no link fields, so there is no issue in whether the link field is absolute or a slower relative offset.
I'm allowing up to 31 byte names, I've got an immediate flag, I reserving a flag for compile-only,
so I can use the third flag set with a 0 length to mark the end of the dictionary block. My notion is if I ever need to handing situations where a simple block dictionary isn't enough, a non-zero length field with the third flag set can be used to indicate those special cases, but I'm not going to spend any time elaborating that at the moment ... this implementation will simply BRK on third flag set and a non-zero length field.EDIT: Scratch that, it turns out that with this dictionary, I need the third flag as a smudge bit. However, it also turns out that a simple NUL works just fine as an end of dictionary marker. Further, it turns out that an immediate flag with a nul length works just fine for a "bridge" over arbitrary data embedded in the dictionary, with the following integer being the address of the next dictionary entry, so I'm going with that approach.
SO I've got to rewrite the dictionary search to shift it from an embedded linked list to a vocabulary built on a dictionary block.