These lessons walk through the interpreter from the inside out — starting with how the lexer reads characters, up through variable scoping and the runtime. Each lesson includes working code and a hands-on exercise.
Character by character: how lex_next_token() streams tokens from a FILE* without loading the file.
Every token has a type and a heap-allocated value. Learn the full TokenType enum and memory ownership rules.
How the grammar becomes code. Each BNF rule maps to a C function — and precedence falls out naturally from the call stack.
→Why a tagged union? How the AST struct represents every node type, and how to add your own without breaking existing code.
How interpreter_evaluate() dispatches on AST node types and produces a RuntimeValue*.
Open-addressing hash maps, parent-pointer scope chains, and why redeclaration is a runtime error.
→Booleans, the when expression, { } blocks, and now fn function literals — with closures and recursion — have already landed. See lessons 04–06 above for how the earlier ones fit into the AST and interpreter; lesson content for functions is on the way. These lessons are in preparation for what's next.