Skip to content
Compiling Expressions to Bytecode
step 1/3

Reading — step 1 of 3

The Compiler — AST to Bytecode

~2 min readCompiling to Bytecode

Compiling Expressions to Bytecode

The compiler bridges the parser and the VM. It walks the AST (or, in a single-pass design, directly consumes tokens) and emits bytecode instructions.

Single-Pass Compilation

In Crafting Interpreters, the clox compiler is a single-pass compiler — it does not build an AST. Instead, it compiles directly from tokens to bytecode in one pass. This is the approach used by Lua and early Pascal compilers.

The key insight: if we design the grammar carefully, we can emit bytecode for each construct as we parse it, without needing to see the entire program first.

Compiling Expressions

Each expression type maps to a sequence of bytecode instructions:

Literals

42       → OP_CONSTANT [index of 42 in constant pool]
true     → OP_TRUE
false    → OP_FALSE
nil      → OP_NIL
"hello"  → OP_CONSTANT [index of "hello"]

Unary

-x  → [compile x], OP_NEGATE
!x  → [compile x], OP_NOT

Binary

a + b → [compile a], [compile b], OP_ADD
a - b → [compile a], [compile b], OP_SUBTRACT
a * b → [compile a], [compile b], OP_MULTIPLY

Notice the pattern: compile left operand, compile right operand, emit the operator. The operands end up on the stack in the right order because the left is compiled (and pushed) first.

Grouping

(expr) → [compile expr]   // parentheses produce no bytecode!

Grouping only affects parse structure — the tree shape handles precedence. No runtime work needed.

Pratt Parsing for Precedence

The single-pass compiler uses Pratt parsing (operator-precedence parsing) to handle precedence without separate grammar rules. Each token has a precedence level and a parse function. This is more compact than recursive descent for expressions.

The Compilation Pipeline

source → scanner → tokens → compiler → chunk → VM → result

We no longer need the AST or tree-walk interpreter. The compiler replaces both the parser and interpreter with a more efficient pipeline.

Your Task

Build a compiler that takes source code, parses expressions, and emits bytecode into a Chunk. Then run the chunk on the VM.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…