Sunday, December 31, 2023

IRC Forth Chatbot

After putting in a lot of work on the 2023 Project Goals for my presentation at HHC 2023, I decided to take a break and work on a few other things for a while. One of those things is a chatbot that connects to IRC and runs Forth code it receives from users. My inspiration for this is the geordi bot which evaluates C code and also runs on IRC. Testing short programs and showing the results immediately is really useful to demonstrate language concepts. Although my Forth chatbot was a really fun project to work on and taught me a lot about several different technologies, I decided not to finish it in the end.

The chatbot is split into two parts. The main program is a Python script that connects to IRC, handles communication, and runs the terminal interface that manages the bot. The second part is a shared library written in C that the Python script loads and calls into to run the Forth code submitted by users. The library is written in C to maximize performance.

Sunday, January 29, 2023

6507 Graphing Calculator: Forth Virtual Machine

As my last post explains, my goal for 2023 is to finish enough projects to give a presentation at HHC 2023. One of the biggest jobs will be finishing the 6507 Graphing Calculator I've been working on the past few years. The latest stage of the project was rewriting part of the firmware in Forth to save space, which turned out to be a failure.

When I last worked on this project, the firmware had reached 9.3K which well exceeds the calculator's 8K EEPROM. This wasn't so concerning since it seemed plausible at the time to implement a tiny Forth core and shrink the firmware by rewriting parts of it in Forth. Also, some parts of the existing firmware, which is all written in assembly, could be improved to save space. With this plan in mind, I started implementing a preprocessor in Python that scans all of the project's assembly files for Forth code and converts it into bytes to embed in the assembly source code. The Forth core uses token threading so each Forth word in the source produces just one byte rather than two as in direct and indirect threading or three with subroutine threading. The Forth system is initiated with a BRK instruction which jumps to the software interrupt handler and begins interpreting the bytes following the BRK. This saves two bytes for every invocation of the Forth system over using JMP or JSR. One of the tokens in the Forth system is assigned the same number as the BRK op code and increments a counter when executed. A corresponding token at the end of each function decrements the counter and switches from Forth back to assembly when the counter reaches zero. With this setup, the program can jump from assembly or Forth to a function written in Forth and continue executing seamlessly.