Revisiting "Let's Build a Compiler"

https://news.ycombinator.com/rss Hits: 16
Summary

There's an old compiler-building tutorial that has become part of the field's lore: the Let's Build a Compiler series by Jack Crenshaw (published between 1988 and 1995). I ran into it in 2003 and was very impressed, but it's now 2025 and this tutorial is still being mentioned quite often in Hacker News threads. Why is that? Why does a tutorial from 35 years ago, built in Pascal and emitting Motorola 68000 assembly - technologies that are virtually unknown for the new generation of programmers - hold sway over compiler enthusiasts? I've decided to find out. The tutorial is easily available and readable online, but just re-reading it seemed insufficient. So I've decided on meticulously translating the compilers built in it to Python and emit a more modern target - WebAssembly. It was an enjoyable process and I want to share the outcome and some insights gained along the way. The result is this code repository. Of particular interest is the TUTORIAL.md file, which describes how each part in the original tutorial is mapped to my code. So if you want to read the original tutorial but play with code you can actually easily try on your own, feel free to follow my path. A sample To get a taste of the input language being compiled and the output my compiler generates, here's a sample program in the KISS language designed by Jack Crenshaw: var X=0 { sum from 0 to n-1 inclusive, and add to result } procedure addseq(n, ref result) var i, sum { 0 initialized } while i < n sum = sum + i i = i + 1 end result = result + sum end program testprog begin addseq(11, X) end . It's from part 13 of the tutorial, so it showcases procedures along with control constructs like the while loop, and passing parameters both by value and by reference. Here's the WASM text generated by my compiler for part 13: (module (memory 8) ;; Linear stack pointer. Used to pass parameters by ref. ;; Grows downwards (towards lower addresses). (global $__sp (mut i32) (i32.const 65536)) (global $X (mut i32) (i32.c...

First seen: 2025-12-10 07:32

Last seen: 2025-12-11 01:35