Compilers & Language Engineering
PINS Compiler Course
8 progressive compiler assignments from lexer to interpreter for 100+ university students
Overview
A complete set of 8 progressive compiler assignments (DN1-DN8) designed and maintained for the Compilers and Virtual Machines (PINS) course at the University of Ljubljana. Each assignment builds incrementally on the previous one, guiding students from lexical analysis through to a working interpreter -- growing from 12 Java source files to 73 files. The course framework includes a clean visitor-based architecture, external semantic maps (NodeDescription<T>), progressive pretty-printers, and an annotation-driven CLI.
Architecture
The architecture uses the visitor pattern for phase separation -- an 18-overload Visitor interface where each compiler phase is a separate implementation. External semantic maps via NodeDescription<T> (a generic HashMap<Ast, T> wrapper) attach semantic information to AST nodes without mutating them. Phase-gated execution chains phases sequentially with early termination, letting students test each assignment in isolation.
Key concepts
NodeDescription<T> External Semantic Maps
A generic HashMap<Ast, T> wrapper that attaches semantic information (definitions, types, frames, accesses) to AST nodes without mutating them. Each phase creates its own NodeDescription and passes it to subsequent phases, enforcing clean phase separation and making semantic analysis results explicit.
Code highlights
public class NodeDescription<T> {
private Map<Ast, T> storage = new HashMap<>();
public Optional<T> valueFor(Ast node) {
return Optional.ofNullable(storage.get(node));
}
public boolean store(T value, Ast forNode) {
return storage.put(forNode, value) == null;
}
}Highlights
- — Designed a complete 8-assignment compiler course from lexical analysis to a working interpreter (12 to 73 source files incrementally)
- — NodeDescription<T> as central teaching abstraction: semantic analysis results as maps from AST nodes to values, enforcing phase separation
- — Progressive pretty-printers (V1-V4) where each version accumulates more semantic data, visualizing compiler understanding growth
- — Course framework directly derived from own BSc/MSc compilers, compressed into an accessible educational format
Related projects
Blang (Bitis)
Lazy functional language with compile-time ownership and borrowing instead of garbage collection
View →Atheris
Complete compiler for a Swift-like OOP language with vtables and polymorphic dispatch
View →SML-to-Racket
Source-to-source compiler with lambda calculus IR and Church-encoded algebraic datatypes
View →