Libor's blog


Crafting Interpreters in Rust

Published on Apr 07, 2026

I set out to implement the second interpreter from Crafting Interpreters using Rust. I wanted to use Rust in a real-life project to see how easy or hard it is to develop in it. My thinking was that in these days with AI agents at hand, it should be simpler than just googling every single issue and trying to make it fix those. It worked for some part. In this post, I'll describe the experience of coding in Rust with AI and the learnings from implementing single-pass compiler with a VM. And in the end, my eye-opening experience with AI.

Single-pass compiler with a Virtual Machine interpreting generated byte-code

Just writing title of this section sounds so cool. Writing the compiler and the interpreter itself felt very familiar actually. What the compiler does is it cleverly stores the op-codes or instructions on the stack and reference other objects on the stack relative to their position. It sounds complicated and it is but it's also deeply familiar because that's how other languages work too. Unlike with tree-walk interpreter, this time I didn't really learn new techniques but putting all the things together and making the compiler and interpreter and making them work is still worth. It takes a lot of effort to get everything right.

As Robert remarked in his book, this is how most of the high-level languages work (python, for example) so after implementing a language of your own it's actually much easier to deep dive some other languages. I highly recommend to everyone to try and implement the language on your own or just read the book, it's a great read. My full rust implementation can be found here.

Having said that, I'd like to move on to another part of this project - coding in Rust.

Development in Rust

My eyes were on Rust for quite some time but I've been always developing in high-level languages (Python, Kotlin, TypeScript, etc...) and frankly was worried that I would get stuck real fast while developing with Rust, especially because of its famed borrow-checker. While this time around, I had a very helpful AI at hand, I was also keeping up by reading the Rust book on side to try to keep up with my errors.

It did help and to my surprise, I was able to hand-craft much of the project on my own and sometimes asking AI how to proceed, never letting it do the actual coding though. This was until I came across implementing functions. Up to that point the codebase kept getting more and more complex but still manageable. However, adding function support required quite a lot of refactoring where I simply gave up due to all the lifetime and borrow-checker errors.

My learning from this?

Coding in Rust is doable, but, and as much as important it is in other languages too, I think it's super important to come up with the architecture of your project upfront to know (or since many projects evolve over time, at least have a grasp) what the relationships and lifetime of the objects. Knowing that would make things much easier, but following the book, and essentially being single-pass reader of the single-pass compiler, it's impossible to start with the architecture first.

Will I do some more coding in Rust? Maybe. Stay tuned.

Development with AI

As mentioned above, when I encountered functions the code was so convoluted that I simply gave up and started questioning my life decisions. At that point I summoned AI not to answer some of my questions but instead I asked it to develop the feature itself. This was the first time I actually gave AI so much leeway, not asking for something very narrow or unit tests for very isolated feature, I simply said, here's my codebase, implement support for functions. And it did just that. I was astonished, this was in January 2026 using Claude Opus 4.6. Once doing that, I simply had AI finish the whole codebase and write tests, this all while I was reading the rest of the book.

You could say there's nothing more to add but actually this was eye-opening event for me and I tried using AI for coding on much larger codebases that I develop on at work. To my astonishment (and using the 1M context model) AI was absolutely able to handle that. The only thing holding back was never-ending asking for tool permissions. So after few tweaks customization my agent, I arrived at one which does all the coding, research, document-checking etc... for me. These days whenever I start working on a task, I first ask my agent.

I switched sides and it all started with Crafting interpreters.