Before Christmas I made slow but steady progress implementing various core words. I have written various stack manipulation words like ROT, SWAP, DROP and DUP, the memory words @, !, C@, C!, and the arithmetic words 1+ and 1-. I have also written the code for entering and exiting a thread: DOCOL and EXIT.
The experience of writing all of this code in assembly has been a mixture of fun and frustration. On the one hand it's a nice exercise in that it's just creative enough to be interesting, without allowing much space for analysis paralysis. The sort of task where you can keep putting one foot in front of another. On the other hand it's so slow! I don't think I've ever got a single routine correct the first time, and often my first effort is hilariously wrong. Even with my fairly decent test approach, working out what I've done wrong always seems to involve single stepping my code, usually multiple times, which is a very laborious process. Often I'm working on this in odd half-hours, and this really tasks that feel like they should be done in one session end up taking several. I'm really glad I've aimed for good unit test coverage, otherwise I'd be lost.
I'm now at a point where I can start to think about defining words in terms of other words. For example, a definition of NIP could be:
: NIP SWAP DROP ;
I could re-write this in Python as
def nip(): label("forth.core.NIP") docol() for word in ["SWAP", "DROP", "EXIT"]: st(lo("forth.core." + word), [Y, Xpp]) jmp(Y, "forth.next3.rom-mode-tail") st(hi("forth.core." + word), [Y, Xpp])
However if I follow that style, I will end up writing a whole Forth in Python-generated assembly, which isn't really the path I want to go down.
Instead I'd like a tool that can process the Forth definition above, and issue the same Python function calls. Lots of definitions for Forth words in Forth syntax would be quite complicated, so really this needs to be a full Forth implementation in Python. Of course, I want to write as much of this in Forth as possible too, because otherwise I have to write everything twice (or perhaps even three times). None of the existing Forth in Python projects that I've seen quite for the bill.
That Forth in Python is what I've been working on so far this year (although without spending much time on it), and I've finally got to a point where it does something. I can run simple definitions in an interactive session, and see the results, and while there are many words written in Python, the interpreter loop and several core words are written in Forth and loaded during a bootstrapping process. This includes ;, ['] and \. I think it has promise. My next step is to get it to generate Gigatron code, and NIP is the first word I shall be trying to compile.
There's still a lot of assembly to write, but it will be good to be able to write Forth too.