Jul 2025
7 min read
Closures in first didn't need a special case
first just got fn function literals, calls, and closures. I expected closures to need a capture list or a snapshot of variables. Instead they fell out of the Environment struct that was already backing every block.
internals
interpreter
closures
Jun 2025
9 min read
Why I wrote my own hash map instead of using a library
JMap is a simple open-addressing hash map in about 120 lines of C. Here's why writing it myself was the right call, and what I learned about linear probing along the way.
internals
data structures
C99
May 2025
7 min read
Designing a streaming lexer that never loads the file
Most toy lexer implementations slurp the whole source into a string buffer first. Here's why I went with a FILE*-based streaming approach and what get_while() and get_until() ended up looking like.
lexer
design
C99
Apr 2025
12 min read
Tagged unions in C: representing an AST without malloc hell
Adding a new AST node type in many C implementations means a new malloc, a new free, and an audit of every switch statement. Here's how first's tagged union design keeps that manageable.
AST
parser
memory
Mar 2025
5 min read
Testing a C lexer with Criterion: what worked and what didn't
Criterion is a great testing framework but its CMake integration has a few rough edges. This is the setup that actually worked, and the test patterns I wish I'd started with.
testing
criterion
cmake
Feb 2025
8 min read
How operator precedence emerges from a recursive descent parser
I didn't need a Pratt parser or a precedence table. Precedence fell out of the grammar structure for free — and understanding why is one of the most satisfying moments in building first.
parser
theory
design