Compilation pipeline
How the PHP compiler
turns code into machine code
Seven well-defined phases compile your PHP source into a standalone native binary. The compilation pipeline transforms PHP code into optimized assembly for the selected target, then assembles and links it into a native executable. No Zend Engine, VM, interpreter, or opcode fallback is involved in the compiled path.
Lexer
Character-by-character scanning of PHP source into keywords, operators, literals, and identifiers.
Parser
Pratt parser with binding powers builds a structured tree of expressions and statements.
Resolver
Builds the compile-time autoload registry from Composer metadata and SPL rules, lowers per-file PHP magic constants, runs the ifdef/--define conditional pass, pre-scans statically-resolvable include targets for declarations, folds compile-time include path expressions, lowers include_once and require_once runtime guards, runs static autoload file insertion for referenced classes, then resolves namespaces and use imports to fully qualified names — merging multiple files into one AST.
Type Checker
Infers and validates types for every variable and expression. Catches errors before assembly is emitted.
Optimizer
Constant folding, constant propagation, control-flow pruning and normalization, and dead-code elimination with CFG-lite reachability. Conservative by design — rewrites only happen when the shape is statically provable.
Codegen
Every AST node is translated to annotated assembly for the selected target: macOS ARM64, Linux ARM64, or Linux x86_64. Each line is commented explaining what and why.
Link
The host `as` assembles to object code, then `ld` links into a standalone executable (Mach-O on macOS, ELF on Linux) with elephc runtime routines included.
Code examples
Write PHP.
Compile to native.
80+ working PHP code examples ship with the compiler. Each one compiles to a standalone native binary and produces identical output to the PHP interpreter. From hello world to inheritance and exceptions — all compiled to native machine code.
All 80+ included examples
Documentation
Learn how a
PHP compiler works
12 guides covering every aspect of building a PHP compiler — from lexing and parsing, to type checking, code generation, and the ARM64 instruction set. No prior assembly or compiler knowledge required.
What is a compiler?
The big picture: source code in, binary out
How elephc works
The full pipeline walkthrough, step by step
The Lexer
How source text becomes a stream of tokens
The Parser
How tokens become an AST with Pratt parsing
The Type Checker
Static types, inference, and error detection
The Optimizer
Folding, propagation, pruning, normalization, dead-code elimination
The Codegen
How the AST becomes ARM64 assembly
The Runtime
Runtime routines: strings, arrays, exceptions, hash tables, I/O
Memory Model
Stack, heap, ref counting, copy-on-write, cycle collection
ARM64 Assembly
ARM64 primer for people who've never seen assembly
ARM64 Instructions
Quick reference for every instruction elephc uses
Architecture
Module map, file counts, conventions
"Every line of Rust that emits ARM64 assembly is annotated with an inline comment explaining what it does and why."
From stack frame setup to syscall invocation, from integer-to-string conversion to array memory layout.
If you've ever wondered what happens between echo "hello" and the CPU executing it,
follow the code from src/codegen/ and read the comments.