Before the compiler

The Pipeline

Source code to behavior as a sequence of representations, each existing because the previous one could not answer the next question — and what is lost at every handover.

From Source to Behavior
▶ lab

A source file is a byte sequence with no meaning of its own. What turns it into behavior is a language definition plus an implementation that honours it — and knowing which of the two you are arguing with is most of the skill.

Q · What has to be true before the text in my editor does anything at all?
The Phases, and Why Each One Exists
▶ lab

Thirteen stages from characters to execution, each justified by a question the previous representation could not express — and the reason "phase" and "pass" are not the same word.

Q · What are the phases of a compiler, and why is each one a separate phase instead of one big function?
Frontend, Middle-End, Backend

The three-way split exists for one reason worth stating in arithmetic: it turns `m` languages times `n` targets into `m` plus `n` implementations. What it costs is everything that does not survive the crossing into the IR.

Q · Why do compilers split into a frontend, a middle-end and a backend, and what does each part know?
Compiler versus Interpreter Is Not a Binary
▶ lab

Three implementation shapes, not two categories — and none of them is a property of a language. The sentence to stop saying is named, dismantled and replaced with a question that has an answer.

Q · Is my language compiled or interpreted, and why does nobody give me a straight answer?
What Seven Real Languages Actually Do
▶ lab

C++, Python, JavaScript, TypeScript, Java, Rust and Go, each traced through the same three questions — with the version numbers attached, because every one of these answers has changed at least once.

Q · For the languages I actually use, what happens at build time and what happens at run time?
Ahead-of-Time Compilation

Do all the work before the program starts, and inherit four consequences: the fastest possible start, an unlimited optimization budget, one artifact per target, and permanent ignorance of everything only the run knows.

Q · What do I actually get by compiling ahead of time, and what am I giving up?
What Dies at Each Stage
▶ lab

Every handover in the pipeline destroys something, and every tool you rely on afterwards — diagnostics, debuggers, profilers, stack traces, source maps — is an attempt to buy back one specific casualty at a specific price.

Q · Why can the debugger not show me that variable, and why does the error message point at the wrong thing?
One Line, All the Way Down
▶ lab

Follow `x = a + b` from characters to retired machine instructions, and watch each stage answer a question the previous representation could not even express.

Q · What actually happens to a single line of source code between my editor and the CPU?