|
|
|
|
|
by crq-yml
407 days ago
|
|
It took me a few tries(over a few years) to properly approach the task of writing a Forth, and when I approached it, I made my Forth in Lua, and all I really did was implement the wordlist in FORTH-83 as the spec indicated, and rewrite every time my model assumptions were off. No diving into assembly listings. Eventually I hit the metaprogramming words and those were where I grasped the ways in which the parser and evaluator overlap in a modal way - that aspect is the beating heart of a bootstrappable Forth system and once you have it, the rest is relatively trivial to build when starting from a high level environment. The thing is, pretty much every modern high level language tends to feel a bit clumsy as a Forth because the emphasis of the execution model is different - under everything with an Algol-like runtime, there's a structured hierarchy of function calls with named parameters describing subprograms. Those are provisions of the compiler that automate a ton of bookkeeping and shape the direction of the code. It's easier to see what's going on when starting from the metaphor of a line-number BASIC (as on most 8-bit micros) where program execution is still spatial in nature and there usually aren't function calls and sometimes not even structured loops, so GOTO and global temporaries are used heavily instead. That style of coding maps well to assembly, and the Forth interpreter adds just a bit of glue logic over it. When I try to understand new systems, now, I will look for the SEE word and use that to tear things down word by word. But I still usually don't need to go down to the assembly(although some systems like GForth do print out an assembly listing if asked about their core wordset). |
|
Which brings up another complication -- the threading model. There are multiple, of course. But sometimes I want to figure out, for example, what the `w` variable does. Is it different between indirect threading and subroutine threading? Maybe!