Skip to content
ALB Wiki

Diff — Compilers

Comparing rev 3 → rev 4

{{infobox
| title = Compiler
| name = Compiler
| field = Computer science, programming language implementation
| invented = 1950s — Grace Hopper's A-0 system, Backus's FORTRAN
| descendants = Interpreters, transpilers, JIT engines, assembler toolchains
}}
# Compilers
A **compiler** is the program that reads source code written by humans and produces something a machine can execute. It is the oldest and most foundational tool in all of software engineering — before there were editors, debuggers, version control, or IDEs, there had to be a compiler, because without one there was nothing else.
The word originally described a person. On the early machines, "the compiler" was the clerk who transcribed equations into machine code by hand. When [[Grace Hopper]]'s team built the **A-0 system** for the [[UNIVAC I]] in 1952 — a program that translated symbolic call numbers into relocatable machine code — the job title quietly passed to the machine itself. The modern compiler is still doing the same work: reading a notation designed for humans and producing the notation a processor understands.
```fact
The FORTRAN I compiler, completed in 1957, took 18 person-years to write — roughly 25,000 lines of assembly. It was the first optimizing compiler ever built, and its optimizers were invented out of necessity: customers refused to believe hand-written assembly could be beaten, so John Backus's team had to prove them wrong at release.
```
# How a compiler works
Nearly every compiler, from a 1950s single-pass translator to the modern LLVM pipeline, shares the same skeleton. The details vary enormously, but the stages are universal:
**Lexical analysis** — the lexer (or tokenizer) reads the raw character stream and groups it into tokens: keywords, identifiers, literals, operators. `LET x = 3 + 4` becomes `[LET] [IDENT:x] [EQUALS] [INT:3] [PLUS] [INT:4]`.
**Parsing** — the parser arranges the tokens into a tree matching the language's grammar — an *abstract syntax tree* (AST). `3 + 4 * 2` becomes a tree where the `*` binds tighter than the `+`. This is where syntax errors are caught: a missing parenthesis, an unterminated string, a keyword in the wrong place.
**Semantic analysis** — the type checker and name resolver walk the tree and enforce meaning, not just shape: is `x` declared? Is the function being called with the right number of arguments? Does `3 + "hello"` make sense in this language?
**Intermediate representation (IR)** — most modern compilers translate the AST into a lower-level, language-independent form. LLVM IR, GCC's GIMPLE/RTL, JVM bytecode, WebAssembly are all intermediate representations — portable forms that decouple "what the source language means" from "what the target machine does."
**Optimization** — the optimizer transforms the IR: constant folding (`3 + 4` → `7`), dead-code elimination, loop unrolling, register allocation, inlining, vectorization. Modern optimizers are enormously sophisticated — a hot loop in a FORTRAN program compiled with `-O3` will run through dozens of transformation passes before a single byte of machine code is emitted.
**Code generation** — the backend lowers the IR to actual machine instructions for a target CPU (x86-64, ARM64, RISC-V, WASM, 6502…) and emits object files, which the **linker** then combines with libraries into an executable.
```quote
Compilers are the closest thing we have to magic — you write down *what* you want, and a machine decides *how* to do it, in 200 million instructions per second, without ever getting bored or making a typo.
— the folklore
```
# The toolchain families
The world does not have "a compiler" — it has a small number of great infrastructure projects that hundreds of languages share. Nearly every compiler in production today is either one of these, or is built on one of these:
| Toolchain | Owner | Front ends (languages) | IR | Back ends (targets) |
|---|---|---|---|---|
| **GCC** | GNU / FSF | C, C++, Fortran (gfortran), Ada (GNAT), Go (gccgo), Rust (gccrs), D | GIMPLE/RTL | ~30+ CPU families |
| **LLVM** | LLVM Foundation | Clang (C/C++), rustc (Rust), Swift, Zig, Julia, flang, ldc (D) | LLVM IR | x86, ARM, RISC-V, WASM, GPU… |
| **MSVC** | Microsoft | C, C++ | proprietary (C1/C2/UTC) | x86, x64, ARM64 |
| **JVM** | Oracle / OpenJDK | Java (javac), Kotlin (kotlinc), Scala, Groovy, Clojure | JVM bytecode | HotSpot JIT → x86/ARM |
| **Go gc** | Google | Go | Plan-9-derived SSA | amd64, arm64, wasm, 386… |
| **GHC** | Haskell community | Haskell | Core/STG | native + JS/WASM |
| **Roslyn** | Microsoft | C#, VB.NET | IL (CLR bytecode) | CoreCLR JIT / NativeAOT |
| **Emscripten** | OSS | C/C++/Rust via LLVM | LLVM IR → WASM | WebAssembly + JS glue |
Each of these is covered in depth below — and most have their own pages elsewhere on this wiki.
# GCC — the GNU Compiler Collection
**GCC** is the oldest of the great free toolchains and still the most widely ported. Richard Stallman released the GNU C Compiler in **1987** as the foundational act of the GNU project; today it has grown into the GNU Compiler Collection, a single shared backend serving front ends for C, C++, Fortran (`gfortran`), Ada (`GNAT`), Go (`gccgo`), D (`gdc`), Modula-2, COBOL (`gcobol`), and a nascent Rust front end (`gccrs`).
GCC's architecture is a three-stage pipeline: a *front end* parses a source language and produces a tree; the tree is lowered into **GIMPLE** (a high-level SSA IR) and then **RTL** (register-transfer language); the *backend* pattern-matches RTL against one of more than thirty CPU descriptions to emit machine code. This architecture is why a new CPU family can get a full C/C++/Fortran/Ada toolchain by writing a single machine description file — and why nearly every embedded processor on Earth is first reached through GCC.
The toolchain is the default on virtually every Linux distribution, builds the Linux kernel itself, and is the reference implementation for the C and C++ standards alongside Clang. Its `-Wall`, `-Wextra`, and `-fanalyzer` warnings, sanitizers (`-fsanitize=address/undefined/thread`), and LTO pipeline define the modern C/C++ development experience. Ada's industrial toolchain — **GNAT** — is a GCC front end: every Ada program certified to DO-178C flight standards in a Boeing or Airbus jet was compiled through GCC's backend.
# LLVM and Clang — the modular challenger
**LLVM** began as Chris Lattner's 2000 master's project at the University of Illinois Urbana-Champaign and was adopted by Apple in 2005, becoming the production toolchain for macOS and iOS. The original name meant "Low Level Virtual Machine," though the project officially retired the acronym — LLVM today is a *compiler infrastructure*, not a VM.
Its central idea was radical modularity: a single well-specified **LLVM IR** in static single-assignment form, optimized by composable *passes*, with language front ends and machine backends attached as libraries. Where GCC grew as a monolith over decades, LLVM was designed as a toolkit — and the industry responded by building almost every major new language on top of it:
- **Clang** — the C/C++/Objective-C front end, famous for readable diagnostics and fast compile times; now the default compiler on Apple platforms, Android NDK, and FreeBSD
- **rustc** — the Rust compiler lowers to LLVM IR; every Rust binary in production today is LLVM-optimized
- **Swift** — Apple's language, architected by Lattner himself, compiles through its own SIL → LLVM IR
- **Zig** — cross-compilation-first systems language that embeds Clang as its C/C++ front end and ships LLVM bitcode for dozens of targets
- **Julia**, **D (ldc)**, **Fortran (flang)**, **CUDA (NVCC)** — numerical, systems, and GPU languages all reach machine code through LLVM
LLVM's umbrella also contains the **LLD** linker, **compiler-rt** runtime, **LLDB** debugger, **libc++** standard library, and **MLIR** — a newer multi-level IR framework used for AI accelerators and domain-specific compilers. WebAssembly reached production largely through LLVM's WASM backend and the **Emscripten** toolchain, which compiles C/C++ to run in every browser.
# MSVC and Visual Studio
**Microsoft Visual C++** (MSVC) is the third great native toolchain — a proprietary compiler living inside Visual Studio, maintained since 1993 and continuously re-engineered. MSVC's optimizer (`UTC`, the "Universal Tuple Compiler") is shared across Microsoft's C++, C#, and even Fortran-era compilers. On Windows it defines the ABI: DLL import libraries, calling conventions, COM, and SEH all assume MSVC's object model.
-
The modern MSVC is unrecognizable from its 1990s reputation — `/std:c++20` support is complete, AddressSanitizer (`/fsanitize=address`) shipped in 2019, and Microsoft open-sourced its **C# compiler Roslyn**, which compiles C# and VB.NET to **IL bytecode** for the .NET CLR's JIT or the NativeAOT ahead-of-time compiler. [[ALB .NET backend|ALB's own .NET backend]] emits C# source that Roslyn and the .NET SDK then take to IL and machine code.
+
The modern MSVC is unrecognizable from its 1990s reputation — `/std:c++20` support is complete, AddressSanitizer (`/fsanitize=address`) shipped in Visual Studio 2019 v16.9, and Microsoft open-sourced its **C# compiler Roslyn**, which compiles C# and VB.NET to **IL bytecode** for the .NET CLR's JIT or the NativeAOT ahead-of-time compiler. [[ALB .NET backend|ALB's own .NET backend]] emits C# source that Roslyn and the .NET SDK then take to IL and machine code.
# The JVM — bytecode's kingdom
The **Java Virtual Machine** is not a traditional compiler at all — it is the target. `javac` compiles Java source to portable `.class` **bytecode**, and the JVM's just-in-time compiler (HotSpot's tiered C1/C2) turns hot paths into optimized machine code *while the program runs*, using live profiling data no ahead-of-time compiler can see. The JVM became the industry's largest shared language platform: Kotlin (`kotlinc`), Scala, Groovy, Clojure, JRuby, and Jython all target the same bytecode and interoperate through the same runtime. Android's ART continues the idea with `.dex` bytecode. The [[Java Virtual Machine]] has its own article.
# Go — the fast toolchain
Google's **gc toolchain** (`cmd/compile`, `cmd/link`) is deliberately a third path: a single-language, monorepo-quality compiler designed from scratch in 2007 for *compilation speed* above all. Go's designers judged that C++ compile times — minutes to hours on large builds — were themselves a language defect. The Go compiler performs modest optimization (SSA-based, since Go 1.7) but compiles in seconds; `go build` compiles, links, and produces a static binary with no external toolchain dependencies, including full **cross-compilation** (`GOOS=windows GOARCH=arm64 go build`) built in from day one.
# Rust's rustc
**rustc** is LLVM's most famous customer after Clang: it parses Rust source, builds its own MIR (mid-level IR) to run the borrow checker, then lowers through LLVM IR to machine code. `cargo` wraps rustc into a complete build system and package manager — the toolchain that drove Rust's adoption more than any single language feature. The alternative **gccrs** front end and the **Cranelift** backend exist to make Rust less dependent on LLVM, and **mrustc** (a Rust-to-C++ transpiler) provides a bootstrapping path for new platforms.
# The rest of the world
- **GHC** — the Glasgow Haskell Compiler, a research-quality optimizing compiler whose `Core` and `STG` intermediate languages keep lazy functional evaluation efficient; compiles to native code, JavaScript, and WASM
- **Emscripten** — compiles C/C++ (and anything LLVM supports) to WebAssembly with a libc and POSIX emulation layer; the reason Quake, AutoCAD, and Photoshop run in browsers
- **gfortran** — GCC's Fortran front end; modern Fortran 2003–2023, still the backbone of weather forecasting and scientific computing
- **icc / oneAPI** — Intel's compiler, now LLVM-based; its vectorizer was the secret to a decade of supercomputer benchmarks
- **NASM / FASM / GAS** — the assemblers: not compilers by name, but the last stage of every native toolchain — and the direct emit target of several ALB backends
- **tcc** — the Tiny C Compiler, famously boots Linux from source in seconds; compilers this small double as debuggers for the bootstrap problem
- **wasm32 / Emscripten / Zig cc** — the WebAssembly toolchains turning LLVM targets into browser-capable sandboxes
- **Roslyn** — Microsoft's open-source C#/VB compiler-as-a-service; the same engine that compiles your code also powers IntelliSense and live analysis inside Visual Studio
# Compilers and ALB
[[AdaLogic BASIC]] is unusual in this landscape: rather than binding to a single toolchain, ALB's compiler **targets sixteen backends** — emitting FASM and NASM assembly directly, transpiling to C, TypeScript, Ada, Lua, MoonScript, and .NET C# among others. ALB is therefore a *polyglot compiler front end*: the same source program becomes a native x86-64 binary through FASM, a browser program through TypeScript/WebAssembly, or a certified-adjacent Ada program through the [[ALB Ada backend|Ada backend]] — and GNAT's GCC backend then does the optimizing.
This design means ALB inherits whatever the underlying toolchain can do: FASM's speed, GCC's code generation, .NET's CLR JIT, WASM's sandboxing — all reachable from one BASIC program.
# See also
- [[Grace Hopper]] — built the first compiler while everyone told her it couldn't be done
- [[FORTRAN]] — the first production language with an optimizing compiler
- [[GNAT]] — the Ada front end inside GCC
- [[ALB FASM backend]] · [[ALB NASM backend]] · [[ALB C backend]] · [[ALB TypeScript backend]] · [[ALB .NET backend]] — the emitters
- [[Forth]] — threaded code: the whole compiler is three instructions
- [[ALGOL]] · [[LISP]] · [[COBOL]] · [[Ada Programming Language]] · [[Rust (programming language)]] — the languages the toolchains serve
- [[Java Virtual Machine]] — the bytecode platform
# References
1. Hopper, Grace Murray. "The Education of a Computer" (1952) — the A-0 paper.
2. Backus, John, et al. "The FORTRAN Automatic Coding System." *Proceedings of the Western Joint Computer Conference* (1957).
3. Stallman, Richard. *GNU Manifesto* (1985); GCC 1.0 released March 1987.
4. Lattner, Chris, and Vikram Adve. "LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation." *CGO 2004*.
5. *The Dragon Book* — Aho, Lam, Sethi, Ullman. *Compilers: Principles, Techniques, and Tools*, 2nd ed. (Addison-Wesley, 2006).
6. gcc.gnu.org — GCC online documentation and front-end matrix.
7. llvm.org — LLVM project documentation.
8. Microsoft Learn — MSVC and Roslyn documentation.
9. OpenJDK — HotSpot and javac source repositories.
10. Go.dev — `cmd/compile` documentation.
[[Category:Programming]]
[[Category:Languages]]
[[Category:Technology]]