Teaching a Dog to Talk
Every programmer eventually gets the itch to build their own language. Not because the world
needs another one — it emphatically does not — but because there's no faster way to find out
what a for loop is actually made of than building one yourself, bolt by bolt, at 11pm,
questioning your life choices.
So: I'm building a programming language. It's called Dogesh, and it is, in the most technical sense, a very good boy.
What even is Dogesh¶
Dogesh is a dog-themed dialect of Lox — the toy language at the heart of Robert Nystrom's Crafting Interpreters, which is widely considered the friendliest possible way to go from "what's a token?" to "I built a programming language" without losing your mind somewhere around chapter 6.
The plan is to follow the book chapter by chapter and, instead of writing plain old jlox,
write something that barks. Concretely, that means things like:
fetch age = 3;
sniff (age < 1) {
woof("still a pup");
} growl {
woof("a very good boy indeed");
}
No prizes for guessing what woof does. fetch declares a variable because that's just what
a var statement is doing, if you think about it. sniff and growl are if and else,
because a dog checking something out is basically a conditional branch with a wagging tail.
There's a chase (while), a walk (for), tricks you can teach it (trick, a.k.a.
functions), and eventually — if I get that far without rage-quitting — packs (pack, a.k.a.
classes) with an alpha you can call alpha.something() on, because every good class hierarchy
deserves a pack leader.
Why though¶
A few reasons, roughly in order of honesty:
- I want to actually understand how the code I write every day gets from text to behavior, instead of vaguely gesturing at "compilers do... stuff."
- Crafting Interpreters is the rare technical book that's genuinely fun to read, and I wanted an excuse to slow down and do the exercises properly instead of skimming with good intentions.
- Renaming
thistodoggofelt objectively funnier than not doing that.
The plan¶
I'm building the tree-walking interpreter from Part I of the book first — scanner, parser, and a straightforward evaluator that walks the syntax tree and just... does the thing. No bytecode, no virtual machine, no premature optimization. Just a dog, sniffing its way through an abstract syntax tree one branch at a time.
If that goes well (and if my sanity remains intact), Part II covers building an actual bytecode
virtual machine in C, which is the "and now for something completely different" chapter of the
book. That's a problem for future me. Present me is just trying to get woof("Hello, World!")
to print without an off-by-one error ruining my evening.
What to expect on this blog¶
I'll be writing this up as I go — not a polished "here's the finished thing," but the actual process: the chapters that clicked, the ones that didn't, the bugs that took four hours and turned out to be a missing semicolon, the moment recursive descent parsing finally makes sense and you feel like a wizard for about six minutes.
Rough shape of what's coming:
- Scanning — turning
"woof(1 + 2);"into a list of tokens, and why this is secretly the easiest chapter and you should enjoy it while it lasts - Parsing — recursive descent, one grammar rule at a time, and how a
forloop turns out to secretly just be awhileloop wearing a trench coat - Evaluating — actually running the thing, and the surprisingly small amount of code it
takes to make a calculator that also has
ifstatements - Functions and closures — teaching Dogesh tricks, and the delightfully weird moment where a function remembers where it was born
- Classes — giving Dogesh a pack mentality,
pup(that's the constructor — a newborn pup, get it), and inheritance viaalpha
I've got a basic skeleton of the whole thing already sketched out (thanks to some very persistent help I did not ask for), but I'm setting that aside and building it properly myself, chapter by chapter, so I actually learn something instead of just having a working folder of files I don't understand.
Onward. Time to teach a dog to read.