Compiler Construction · week 1

What is Selfie?

The talk, then the spine of the semester in an hour: the axis, the three theorems, and the definition a compiler class earns.

↑ Compiler Construction

What this class is for

A compiler is a proof system for syntax and a constructor of semantics — and every semantic question it seems to answer is a chosen approximation.

That sentence is the class: fourteen weeks of building starc, selfie's compiler, extension by extension.

The purpose is shared with the companion classes: principles deep enough to position generative AI, and whatever comes next, properly. A compiler is where notation meets meaning most exactly.

The assignments

Twelve autograded extensions of selfie, from hexadecimal literals to structs, one per week. And in week 12: verify your own extension with a model checker.

The book

What is Intelligence? The Programming chapter is this class. Read the Introduction and the Selfie chapter this week.

The axis

One line carries the semester.

the six stations, and where a compiler class dwells

Finite, countable. Bits, and everything you can write down: programs, grammars, binaries. Weeks 2 to 5 live here — scanner, parser, code generator — and they never leave the decidable.

Uncountable. What programs mean. Weeks 6 to 9 — statements, procedures, self-compilation, optimisation — are where the compiler constructs meaning and where Gödel, Turing and Rice say what it cannot decide about it.

Cost. Weeks 10 to 12 turn the compiler's output into a formula, hand it to a solver, and meet NP-completeness. Then a week on generated code, and the definition.

Three commands, three theorems

Understand the first and you understand compilers.

$ ./selfie -c selfie.c -o selfie1.m -m 2 -c selfie.c -o selfie2.m && diff -s selfie1.m selfie2.m Files selfie1.m and selfie2.m are identical $ ./selfie -c selfie.c -o selfie.m -m 2 -l selfie.m -m 1 $ ./selfie -c selfie.c -o selfie.m -m 3 -l selfie.m -y 2 -l selfie.m -y 1
Self-compilation · a fixed point

The compiler compiles its own source and gets the same bytes twice. Gödel's self-reference, runnable. It proves self-agreement — and week 8 says what it cannot prove.

Self-execution · the universal machine

An emulator that runs every program for its machine, itself included. Turing's move, forwards. The target of every instruction you will emit.

Self-hosting · the bootstrap problem

A hypervisor that must isolate itself from the machines it isolates. The systems class. Here, only the reminder that the loop is the subject.

The three theorems, briefly

Cantor, Gödel, Rice — what a compiler class needs from each.

Cantor · 1891

Programs are countable; behaviours are not. So almost every behaviour has no program, and no analysis of programs can list what they do. Semantic analysis is approximation, by counting alone.

Gödel · 1931

No strong system certifies itself. A compiler that agrees with itself has certified nothing; the outside check is a second compiler, or a solver. Week 8, with Thompson.

Rice · 1953

Every non-trivial property of behaviour is undecidable; only questions about the text are safe. Type checking is about the text. Dead code is about behaviour. Week 4 and week 9.

All three are one move: assume a complete list, ask each item about itself, answer the opposite. The introduction class proves them; here they are the constraints the compiler is built under.

The system

Nothing in the middle is left out.

selfie.c → scanner → parser → code generator → RISC-U

Twelve thousand lines, one file: the compiler starc, the emulator mipster, the hypervisor hypster, and a small library. The compiler is about four thousand of those lines and you will read all of them.

C*: 7 keywords, 22 symbols, LL(1), one type and pointers to it. RISC-U: 14 instructions, 32 registers, 4 GB. Small enough to hold in one head, which is the only argument for the size.

Fourteen weeks

The route.

wklectureassignment
2The scannerhex-literal
3The parser—
4Symbols and typesbitwise-shift-compilation
5Expressionsbitwise-shift-execution
6Statementsbitwise-and-or-not
logical-and-or-not
7Proceduresfor-loop, lazy-evaluation
8Self-compilationarray-access
wklectureassignment
9Optimisation and Ricearray-allocation
10Semantics as a formulaarray-multidimensional
11SATstruct-declaration
12Bounded model checkingstruct-execution
rotor-check
13Generated code—
14What a compiler is—
This week

Take a selfie.

  1. Install selfie, run the three commands, and read the grader's README: private clone, upstream, commit links.
  2. Do print-your-name: make selfie print your name right after initialisation, prefixed like every other status message. Part of the assignment is finding out where.
  3. Check your grade with ./grader/self.py print-your-name, and that self-compile still passes.
  4. Read the Introduction, the Selfie chapter, and the Programming chapter's opening callout.
Next week

The scanner: characters into symbols, one finite state machine per kind of symbol, and your first extension of the grammar — hexadecimal integer literals.

After this week

Listen, then read.

Listen

Bach · The Art of Fugue — Musica Antiqua Köln, 1984. Fourteen fugues on one subject, and the last breaks off as the notes B-A-C-H enter: the work names its author and halts. A compiler class begins with a text that signs itself.

Read

Compilers: Principles, Techniques, and Tools — Aho, Lam, Sethi and Ullman, the dragon book: the field in one volume, and the knight on the cover is you. And, more technical, Compiler Construction — Wirth, 2005, free from ETH: a whole compiler in a hundred pages, and the closest thing in print to how selfie does it.

CC 02 · The Scanner →