πŸ—οΈ Compiler Architecture

Understanding the Mica compiler pipeline

Overview

Mica is designed to be a learning-sized compiler that you can read and understand in a weekend. The entire pipelineβ€”from lexing to native code generationβ€”is intentionally compact and well-documented, making it perfect for studying compiler implementation techniques.

Every stage of the compiler is exposed through CLI flags, allowing you to inspect intermediate representations and understand how your code transforms at each step.

Compiler Pipeline

The Mica compiler processes code through the following stages:

1. Lexing

--tokens

Converts source text into a stream of tokens with precise span information. Handles keywords, operators, literals, and comments.

Output: Token stream with spans

2. Parsing

--ast --pretty

Builds an Abstract Syntax Tree (AST) using recursive descent parsing with Pratt expression handling. Includes error recovery.

Output: AST with full source structure

3. Resolution

--resolve

Resolves names, builds symbol tables, and tracks capability usage. Handles imports and module graphs.

Output: Resolved symbols and capability metadata

4. Type & Effect Checking

--check

Performs type inference, exhaustiveness checking, and effect verification. Ensures capability contracts are satisfied.

Output: Fully typed and checked program

5. Lowering to HIR

--lower

Transforms AST to High-level Intermediate Representation. Desugars method calls, effects, and control flow.

Output: Simplified HIR

6. SSA IR Generation

--ir

Converts HIR to typed SSA (Static Single Assignment) form with basic blocks and instructions.

Output: Typed SSA IR

7. Backend Code Generation

--llvm --build

Generates native code via LLVM or portable C backend. Links with runtime capability providers.

Output: Native binary

8. Runtime Execution

--run

Executes the program with capability-aware runtime shims. Captures telemetry and enforces deterministic concurrency.

Output: Program results and telemetry

Source Code Organization

The repository is structured for easy navigation:

Syntax

Lexer, parser, and pretty-printer for the front-end

src/syntax/

Semantics

Name resolution, type checking, and effect analysis

src/semantics/

Lowering

AST to HIR transformation and desugaring

src/lower/

IR

Typed SSA intermediate representation

src/ir/

Backend

Code generation targets (LLVM, native C)

src/backend/

Runtime

Capability providers and task scheduler

src/runtime/

Diagnostics

Error reporting and structured warnings

src/diagnostics/

CLI

Command-line interface and tooling

src/main.rs

Pretty

Code formatting and CST handling

src/pretty/

Tests

Integration and unit test suites

src/tests/

Examples

Runnable sample programs

examples/

Documentation

Guides, roadmap, and module docs

docs/

Development Phases

Mica development follows a phased approach:

Phase 0 β€” Foundations Complete

Lexer, parser, and basic tooling infrastructure

Phase 1 β€” Semantic Core Complete

Name resolution, type checking, and effect system

Phase 2 β€” IR & Lowering Complete

HIR lowering, typed SSA IR, and purity analysis

Phase 3 β€” Backend & Runtime Active

Code generation, runtime shims, and deterministic scheduler

Phase 4 β€” Tooling & IDE Planned

Formatter, LSP server, and developer experience tools

Phase 5 β€” Ecosystem Planned

Standard library, package manager, and interop adapters

Phase 6 β€” Growth Planned

Community building, RFC process, and ecosystem expansion

Design Principles

The Mica compiler follows these core principles:

πŸ“– Learning-Sized

The entire codebase is designed to be readable in a weekend. Every module is intentionally compact and well-documented.

πŸ” Inspectable

Every compiler stage is exposed through CLI flags, making it easy to understand transformations and debug issues.

🎯 Effect-Aware

Capabilities and effects are first-class, tracked through the entire pipeline from parsing to runtime.

πŸ”’ Deterministic

Concurrency is structured and deterministic by default, with explicit capability requirements.

πŸ§ͺ Well-Tested

Comprehensive test suites cover every stage with golden snapshots and negative test cases.

πŸš€ Extensible

Clean interfaces and modular design make it easy to add new features or experiment with alternatives.

Learn More

For detailed information about each compiler module: