Brad R wrote:
I'd say it depends on what you want to use vocabularies for. There's no rule that says vocabularies have to be kept in multiple linked lists. You could, for example, add a single byte to the header of each word, indicating what vocabulary that word belongs to. (If you make that byte part of the name, the vocabulary match is done as part of the name comparison.) That would let you have 256 vocabularies, which is enough for any Forth application I've ever seen.
This idea is great! Thank you. I'm going to do it.
BL WORD COUNT (get the word's buffer address and the length)
add 1 to the length
append the context vocabulary identifier byte to the end of the word I'm search for
set the $20 bit on the length byte (meaning "this word is a member of a vocabulary")
In the symbol table, it's still 2 bytes of CFA, then length/flags, followed by the name. For a vocabulary member, the length includes 1+ for the vocabulary byte and the length will have the $20 bit set. But I'll only scan $1F AND (up to 31) bytes of name. No vocabulary member can have a name longer than 30, and no core word name can be longer than 31.
This vastly simplifies the FIND code vs. chaining vocabularies together in a linked list. They can be hashed like any other word. Their (fake) 32+ length will cause them to float to the top of the hash thread they belong to.
The body of a vocabulary will be
jsr dovocab (it's direct-threaded)
.word parentvocabulary (or 0 for core)
.byt ident (unique identifier e.g. 1=editor; 2=assembler; 3=first user defined vocabulary...)
So for the editor, something like this --
body of EDITOR
jsr dovocab (direct-threaded code so no CFA. The return address tells us where to find the parameters)
.word 0 (editor is a member of core)
.byt 1 (identifier appended to all editor vocabulary members)
The head of the EDITOR vocabulary would be
(CFA of EDITOR) 2 bytes
7, "EDITOR"
The head of EDIT would be
(CFA of EDIT)
5 | $20, "EDIT", 1
Nested vocabularies will be possible. I doubt I'll implement ONLY/ALSO and to get into a vocabulary that's a grandchild of core would require setting CONTEXT to the one in the middle (child of core, parent of grandchild) first.
Quote:
Of course, implementing it that way does not speed compilation in the slightest. I do know of people who have broken their dictionary into multiple vocabularies in order to speed dictionary search. But I tend to think of that as an incidental benefit of certain implementations. The purpose of vocabularies (IMHO) is to give you multiple, independent namespaces.
I'm not doing this multiple vocabularies thing because I already break up the dictionary into 16 roughly equal sized chunks, and I agree with this statement about the purpose of vocabularies.