An Intcode debugger in Rust
I really enjoyed Advent of Code 2019, and am really looking forward to it starting again in a few days. My favorite part of last year’s challenges was Intcode, which is a simple integer-based machine code, which you had to write an interpreter for and then use throughout the month.
I mainly used Racket to solve last year’s problems, and went so far as to write a disassembler for it, which output my own asm-esque version of the code. For example, given the following intcode source:
-a option it outputs:
0: INP @8 2: ADD @8,10 @8 6: JNZ 1 @0 9: DAT 0
This makes it easier to understand what the program is doing, but is complicated by the homoiconicity of intcode, where data is often later used as an instruction, or vice-versa. Really what I needed was a debugger that let me step through the execution.
I first became interested in Rust several years ago,
when I went through a few Project Euler problems
with it. At the time I found it interesting, but really fought with the borrow
checker, and decided to see how the language evolved. I’ve renewed interest, and
though that an intcode interpreter would be an interesting exercise in Rust. It
came together pretty well I thought. I really like Rust’s “fat”
match for handling the instructions and I/O.
Interpreter done, I moved forward with a text-based debugger. I played with two TUI libraries, tui and cursive. Both have their good points (cursive has a good comparison), but ultimately I found cursive more complete and in line with what I wanted.
The debugger isn’t complete yet, but it lets you step through one instruction at a time, highlighting the current instruction, stack, and prompting for input. At minimum it still needs to display output. Some other features I’d like to add:
- step backwards
- display “human-readable” instructions
- edit code