There are many ways to code a Forth interpreter. When I inherited Retro, there were two separate dictionaries, one for normal words and data, and one for compiler macros. There were two internal token processing loops, one for interpret time and one for compile time. This lead to some confusion as the compiler macro dictionary was only visible when compiling words, and preceeded the normal dictionary. When new functionality (inlining, etc) was added, more dictionaries and internal loops had to be coded.
Some Forths solve this by having flags in the dictionary headers and having the token processor use these to select the proper functionality. This still requires changes to the kernel to handle new flags and add the behaviour in the proper places.
Helmar Wodtke introduced me to a simpler approach which he calls word classes. In this approach each dictionary entry gets an additional value, a pointer to a class handler. Class handlers are just words that take an execution token (in Retro this is just the address of a word) and do something with it.
A default Retro build has three classes:
- .word
At compile time, compile a call to the word. At interpret time, execute the word. - .macro
Execute the word. The word may compile code or add data into the heap based on any form of system state. - .data
Return the address or value associated with the requested token.
These cover the core functionality required for a small Forth implementation.
In the next post we'll look at how to define new classes and use them to extend Retro's functionality.
No comments:
Post a Comment