Compilers and interpreters

Thirteen sources on making language tools fast and checkable.

These sources are about turning text into running programs, and doing it fast. This page lists thirteen sources, oldest first where dated. Many are one person's account of their own language or tool.

Themes here: Close to the machine (7), Small means (3), Rules that generate (2), Saying it exactly (2), Getting good (2), Handing over control (2), Given away (1), How forms evolve (1), Checking the work (1).

Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I

John McCarthy, Massachusetts Institute of Technology. April 1960. Foundational research paper describing the LISP system.

This is the original description of LISP, split over several web pages. It defines the notation and shows worked examples. It also explains how the IBM 704 system stores lists. The evidence is definitions and hand-traced examples, plus a short status report.

Introduction to Compilers and Language Design

Douglas Thain, University of Notre Dame. 2nd edition, 2020; online version revised 26 July 2026. Landing page for a free online textbook.

This is a short landing page, not the book. It lists the chapters, says who the book is for and links to code examples. The book was not read.

Forth: The programming language that writes itself: The Web Page

Dave Gauer (ratfactor.com). Created 2023-02-02, updated 2026-07-09. Personal illustrated web page adapted from a talk, with the author's own hands-on projects.

The page follows Charles Moore's Forth from a 1958 card interpreter to modern chips. It explains threaded code, the dictionary and compiling. Code comes from the author's own port. The evidence is history from secondary sources and the author's projects, with no measurements.

Strategies for very fast Lexers

xnacly. Jul 14, 2025. Personal blog post, a long tutorial in C with benchmarks.

The post walks through a C lexer for the purple-garden language. Each technique is followed by a benchmark taken from the author's commit messages. It ends with throughput on two machines and a table citing figures from another article.

A catalog of side effects

Max Bernstein. November 11, 2025. Personal blog post, a survey of existing compiler source code.

The post compares two ways to represent instruction effects: bitsets and heap ranges. It walks through real code from Cinder and JavaScriptCore, then lists others. The evidence is code excerpts and a small generator experiment by the author.

Langjam Gamejam: Build a programming language then make a game with it

Posted by birdculture, with replies from many commenters. 30 November 2025. Hacker News discussion thread of about 58 comments.

The thread discusses a 7-day jam called Langjam Gamejam. Commenters debate its difficulty, what a game language should look like and where to start. One commenter describes a game language they built over three years.

Treat Agent Output Like Compiler Output

Hugo Venturini, Software Engineer, SkipLabs. March 9, 2026. Company blog post, an argument by analogy.

The post replies to a call for code-review-free codebases. It argues that trust in compilers comes from surrounding tools, and that agents lack equivalents. It offers analogy and a to-build list, with no tests or data of its own.

Two studies in compiler optimisations

Henrique Cabral. 20 March 2026. Personal blog post with annotated compiler output and exercises.

The post follows two short C++ examples through LLVM optimisation passes. It reads the compiler source and intermediate code to explain each result. It also lists nine exercises and closing advice for writing code the optimiser handles well.

A tail-call interpreter in (nightly) Rust

Posted by g0xA52A2A, with replies from many commenters. 5 April 2026. Hacker News discussion thread of about 56 comments.

The thread responds to a post at mattkeeter.com. That post covers an interpreter built with Rust's become keyword. Many comments cover why such interpreters are fast and why the keyword exists. Several give first-hand reports from their own interpreters.

I rewrote PostHog's SQL parser, 70x faster, while barely looking at the code

Posted by robbie-c, with replies from many commenters. 24 June 2026. Hacker News discussion thread of about 70 comments.

The thread discusses a post on posthog.com/blog/sql-parser. The poster, robbie-c, answers questions as its author. Comments cover the 70x claim, parser design, oracle testing and worries about AI.

Everyone Says Assembly Is Untyped—Everyone Is Wrong

gingerBill (Ginger Bill). 2026-08-20. Language designer's blog post, a design rationale with code examples.

The post explains how Odin's inline assembly works. It contrasts this with string-based GCC and Clang designs. It surveys older approaches in MSVC and Turbo Pascal. The evidence is design argument and code samples, with no measurements.

Finite State Machines in Forth

J.V. Noble, Institute for Nuclear and Particle Physics, University of Virginia. Undated (the page notes it was formatted 11 June 1994 and 17 April 1995). Technical note for Forth programmers, with worked code.

The note starts with a nested-IF solution to a number-entry problem. It then builds a defining word that compiles a state table into a Forth word. The evidence is working code and examples, with no timing data.

How To Make a Fast Dynamic Language Interpreter

Not stated. Undated. Technical write-up with step-by-step benchmark results.

The post takes a slow tree-walking interpreter and applies 21 changes in order. After each change it reports speed against the baseline, Python, Lua and QuickJS. Raw timings for four benchmarks are included.

Connections to other subjects

These links are this wiki's own reading, not claims the sources make.

Glossary

Abstract syntax tree
A tree that represents the structure of a program.
Advice Taker
A proposed program that would follow instructions and reason with common sense.
Alias
Two names that refer to the same object or memory location.
ANTLR
A tool that generates a parser from a written grammar.
AST-walking interpreter
An interpreter that runs a program by recursively visiting nodes of its syntax tree.
AT&T syntax
An x86 assembly style that writes the source operand first.
Bitset
A number whose individual bits each stand for one member of a set.
Branch prediction
The processor's guess about which way a branch will go.
Bump allocator
A memory allocator that hands out space by moving a pointer forward.
Bytecode interpreter
A program that runs compact instructions one at a time.
Canary deploy
Releasing a change to a small share of users first to catch problems.
Car, cdr, cons
The three basic list operations: take the first part, take the rest, build a pair.
Clobber
A register or resource that an instruction changes, which the compiler must know about.
Code word
A Forth word written in machine code instead of in Forth.
Combinator
A function that takes functions as input and builds new behavior from them.
Compiler Explorer
A website that shows the assembly a compiler produces for given source.
Computed goto
A GNU C feature that jumps to a label chosen at run time.
Concatenative language
A language where programs are built by chaining functions that pass values along a stack.
Conditional expression
An expression that picks a value by testing a series of conditions in order.
Conditional move
A machine instruction that picks one of two values without branching.
Dead code elimination
Removing instructions whose results are never used and which change nothing.
Defining word
A Forth word that creates new words and sets how they behave.
Dictionary
The list of named words that a Forth looks up when it reads input.
DSL
A small language made for one narrow job.
Execution token
A value that identifies a Forth word so it can be run later.
Fil-C++
A memory-safe C++ implementation that adds garbage collection and runtime checks.
Finite state machine
A model with fixed states and rules for moving between them on each input.
FNV hash
A simple, fast hash function for byte strings.
Forth
A tiny stack-based language that is easy to implement.
Free-storage list
A list of memory words that are available for new data.
Fuzzing
Feeding a program many random inputs to find failures.
Game jam
A short event where participants build a game within a set time.
Geomean
The geometric mean, a way to average ratios or times across benchmarks.
Geometric mean
An average suited to ratios, such as speed-ups across tests.
Hash consing
Keeping one shared copy of equal values so pointer equality means equality.
Hygienic macro
A macro whose names cannot accidentally collide with the surrounding code.
IBM 704
An early large computer on which LISP was first implemented.
Indirect threaded code
Compiled code stored as lists of addresses that point to routines running the words.
Indirect-threaded Forth
A Forth design where compiled code holds addresses of words, looked up when run.
Inline assembly
Assembly instructions written inside code in a higher-level language.
Inline cache
A remembered result at one code location, such as the last object type seen.
InstCombine
An LLVM pass that applies many such rewrites to its intermediate code.
Instruction selection
The compiler stage that chooses machine instructions for the intermediate code.
Interactive fiction
Text adventure games played by typing commands.
Intermediate representation
A simple internal form of a program used between compiler stages.
Interning
Keeping one shared copy of each repeated value.
Intrinsic
A built-in function the compiler maps directly to a machine instruction.
IR
Intermediate representation, the form a compiler works on between source and machine code.
ISA
Instruction set architecture, the set of instructions a processor understands.
JIT
A compiler that generates machine code while the program runs.
Lambda notation
A way to write a function with named inputs as an expression.
Lattice
A set of values with a union, an intersection, a bottom and a top.
Lexer
The compiler stage that turns characters into tokens.
Lights-out codebase
A codebase where agents write code and humans do not review it.
LLVM
A compiler toolkit used by clang and many other language compilers.
LLVM IR
LLVM's intermediate code, which sits between source code and machine code.
Mmap
A system call that maps a file directly into a program's memory.
Nightly Rust
The experimental release of Rust that carries unfinished features.
Nondeterministic FSM
A machine that may move to one of several next states, chosen by extra information.
NuN tagging
A way to pack doubles, integers and pointers into one 64-bit value.
Odin
A systems programming language created by gingerBill.
Oracle
A trusted reference whose output new code is checked against.
Parser
A program that turns query text into a structured form.
Peephole optimisation
A small local rewrite of a few instructions into cheaper ones.
Recursive descent
A hand-written parsing style with one function per grammar rule.
RFC
A written proposal for a language change.
RPN
Reverse Polish Notation, which puts operators after their operands, as in 3 4 +.
S-expression
A symbolic expression that is either an atom or a pair of two S-expressions.
Sanitizer
A tool that detects memory or behavior errors while a program runs.
Scanner
The compiler stage that splits source text into tokens.
Sea of Nodes
An IR design where effects are tracked in the graph structure itself.
SIMD
Instructions that process several values at once.
Tail call
A call made as a function's last step, so no old frame is kept.
Tree-walking interpreter
A program that runs code by visiting nodes of its syntax tree.
Watchpoint
A flag that invalidates cached assumptions when something in the runtime changes.
WebAssembly
A compact code format that browsers run alongside JavaScript.