Core Design Principles
Query-Based Architecture
Elara uses a query-based compilation system powered by the Rock library. Instead of sequential passes that run eagerly, compilation stages are defined as queries that:- Are lazy - only computed when needed
- Are memoized - results are cached to avoid recomputation
- Support cycle detection - prevents infinite loops in mutual dependencies
- Enable incremental compilation - only recompile what changed
The query system is defined in
src/Elara/Query.hs and implemented in src/Elara/Rules.hs.Effect System
The compiler uses the Effectful library to manage side effects in a pure, composable way:Module Organization
The compiler source code is organized into focused modules:Frontend Modules
Lexer (Elara.Lexer)
Lexer (Elara.Lexer)
Tokenizes source code and handles layout rules:
Elara.Lexer.Token- Token definitionsElara.Lexer.Reader- Lexical analysisElara.Lexer.Utils- Lexer utilities and errors
Parser (Elara.Parse)
Parser (Elara.Parse)
Builds the Frontend AST from tokens:
Elara.Parse.Module- Module structureElara.Parse.Expression- Expression parsingElara.Parse.Declaration- Top-level declarationsElara.Parse.Type- Type expressionsElara.Parse.Pattern- Pattern matching
Desugarer (Elara.Desugar)
Desugarer (Elara.Desugar)
Converts Frontend AST to Desugared AST:
- Multi-argument lambdas → nested single-argument lambdas
- Let bindings → lambdas
- Merges declarations with identical names
Renamer (Elara.Rename)
Renamer (Elara.Rename)
Performs name resolution:
- Resolves names to fully qualified names
- Generates unique names for local variables
Elara.Rename.Imports- Import handlingElara.Rename.State- Renaming state management
Shunter (Elara.Shunt)
Shunter (Elara.Shunt)
Applies operator precedence and associativity:
- Reassociates binary operators
- Converts operators to prefix function calls
Elara.Shunt.Operator- Operator table management
Type System Modules
Type Inference (Elara.TypeInfer)
Type Inference (Elara.TypeInfer)
Hindley-Milner type inference with effects:
Elara.TypeInfer.ConstraintGeneration- Generate type constraintsElara.TypeInfer.Monad- Type inference monadElara.TypeInfer.Environment- Type environmentElara.TypeInfer.Generalise- Type generalizationElara.TypeInfer.Context- Type context management
Kind Inference (Elara.Data.Kind)
Kind Inference (Elara.Data.Kind)
Infers kinds for user-defined types:
Elara.Data.Kind.Infer- Kind inference algorithm
Core Language Modules
Core IR (Elara.Core)
Core IR (Elara.Core)
Simple typed lambda calculus (similar to GHC Core):
Elara.Core.Module- Core module representationElara.Core.Pretty- Pretty printingElara.Core.TypeCheck- Core type checking
ToCore (Elara.ToCore)
ToCore (Elara.ToCore)
Converts Typed AST to Core:
Elara.ToCore.Match- Pattern match compilation- Extensive desugaring to 8 core constructors
Core Transformations (Elara.CoreToCore)
Core Transformations (Elara.CoreToCore)
Optimizes Core IR:
Elara.Core.ToANF- A-Normal Form conversionElara.Core.LiftClosures- Closure lifting
Backend Modules
JVM Backend (Elara.JVM)
JVM Backend (Elara.JVM)
Compiles Core to JVM bytecode:
Elara.JVM.IR- JVM intermediate representationElara.JVM.Lower- Core → JVM IR loweringElara.JVM.Emit- JVM IR → bytecode emissionElara.JVM.Lower.Match- Pattern match compilationElara.JVM.Lower.Function- Function compilationElara.JVM.Emit.Lambda- Lambda lifting
Interpreter (Elara.Interpreter)
Interpreter (Elara.Interpreter)
Direct Core interpreter for rapid development and testing
Key Data Structures
Abstract Syntax Trees
Elara uses a tagless final encoding for ASTs with multiple representations:Compiler Settings
Which compilation stages to dump for debugging
How to run the compiled program:
RunWithNone- Compile onlyRunWithInterpreter- Run using the Core interpreterRunWithJVM- Run as JVM bytecode
The main source file to compile
Additional directories to search for source files
Arguments to pass to the compiled program
Build System Integration
The compiler generates output in thebuild/ directory:
Error Handling
Elara uses a sophisticated error reporting system:- Diagnostic Writer - Collects warnings and errors
- ReportableError trait - All errors implement this for consistent formatting
- Source-mapped errors - Errors include precise source locations
- Unicode diagnostics - Beautiful error messages with colors and arrows
Performance Characteristics
Compilation Speed
The query-based architecture provides:- Incremental compilation - Only recompile changed modules
- Parallel query execution - Independent queries run concurrently
- Memoization - Expensive computations cached automatically
Memory Usage
- Queries are garbage collected after use
- Memoization uses weak references where appropriate
- Large ASTs are streamed rather than materialized entirely
Related Pages
Compilation Pipeline
Detailed walkthrough of the 9 compilation passes
CLI Reference
Complete command-line interface documentation