Austin Z. Henley’s weekend challenge: a Python interpreter in 1024 bytes of C, “no macro shenanigans or library tomfoolery.” His first attempt at 512 bytes only produced a calculator, so he asked a sharper question — what subset of Python can fit that still looks like Python, with defs, colons, and indentation?
The answer skips CPython’s tokenize → AST → bytecode pipeline entirely:
- State is a handful of globals: a source buffer, a 256-entry symbol table, a few position pointers
- Recursive descent parses and executes expressions at the same time — no intermediate representation exists
- The C call stack handles indentation blocks: a block function returns when indentation drops below its minimum
- Loops and functions work by time travel — they record a source position, then jump back and re-parse the code each iteration or call
- It trusts the programmer completely: no error handling, keywords skipped by counting characters, single-letter variable names so lookup is a direct array index
- Feature set that survived: integer math with precedence, comparisons, if/else, while and for-range loops with else, argument-less functions (even recursion), print, comments
Minification took the readable 4800+ bytes down to exactly 1024 — implicit-int C89, zero-initialized globals, ASCII values instead of char literals, ternary and comma operators, recursion over loops.
The essay is a small monument to constraint-driven design: when your whole budget is a kilobyte, the abstraction layers you assumed were necessary turn out to be conveniences you can trade away. And the loop-reparse trick — using the source itself as the only program representation — is genuinely beautiful. Both the readable and golfed versions are on GitHub (AZHenley/python1024).
A good companion to Henley’s “I write code by hand on the weekends” ethos — and a reminder that building tiny interpreters is still one of the best ways to understand what compilers actually do.