π§ Under Active Development π§
Early development. Not production-ready.
Ahead-of-time F# compiler producing native executables without managed runtime or garbage collection. Leverages F# Native Compiler Services (FNCS) for type checking and semantic analysis, generates MLIR through Alex multi-targeting layer, produces native binaries via LLVM.
Firefly implements a true nanopass compiler architecture with ~25 distinct passes from F# source to native binary. Each pass performs a single, well-defined transformation on an intermediate representation.
F# Source
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FNCS (6 phases) β
β Phase 0: FCS parse and type check β
β Phase 1: Structural construction (SynExpr β PSG) β
β Phase 2: Symbol correlation (attach FSharpSymbol) β
β Phase 3: Soft-delete reachability (mark unreachable) β
β Phase 4: Typed tree overlay (type resolution via zipper) β
β Phase 5+: Enrichment (def-use, operations, saturation) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β PSG (Program Semantic Graph)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Alex Witnesses (16 category-selective generators) β
β - ApplicationWitness: function calls β
β - LambdaWitness: function definitions β
β - ControlFlowWitness: if/while/for β
β - MemoryWitness: allocations β
β - OptionWitness, SeqWitness, LazyWitness: type constructors β
β - 10 additional witnesses for complete F# coverage β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Portable MLIR (memref, arith, func, index, scf)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MLIR Structural Passes (4 passes) β
β 1. Structural folding (deduplicate function bodies) β
β 2. Declaration collection (external function declarations) β
β 3. Type normalization (insert memref.cast at call sites) β
β 4. FFI conversion (delegated to mlir-opt) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MLIR (portable dialects)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β mlir-opt Dialect Lowering β
β - memref β LLVM struct β
β - arith β LLVM arithmetic β
β - scf β cf β LLVM control flow β
β - index β platform word size β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LLVM IR
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LLVM + Clang β
β - Optimization passes β
β - Code generation β
β - Linking β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
Native Binary (zero runtime dependencies)
1. Nanopass Throughout
Unlike traditional compilers with monolithic passes, Firefly uses single-purpose transformations at every tier. Each pass is independently testable and inspectable with -k flag.
2. Coeffects Over Runtime Pre-computed analysis (SSA assignment, platform resolution, mutability tracking) guides code generation. No runtime discovery.
3. Codata Witnesses Witnesses observe PSG structure and return MLIR operations. They do not build or transformβobservation only. This preserves PSG immutability.
4. Quotations as Semantic Carriers
F# quotations (Expr<'T>) carry platform constraints and peripheral descriptors through compilation as inspectable data structures. No runtime evaluation.
5. Zipper + XParsec Bidirectional PSG traversal with composable pattern matching. Enables local reasoning without global context threading.
6. Portable Until Proven Backend-Specific MiddleEnd emits only portable MLIR dialects (memref, arith, func, index, scf). Target-specific lowering delegated to mlir-opt and LLVM.
FNCS provides native type universe (NTUKind) at compile time. Types are compiler intrinsics, not runtime constructs:
- Primitives:
i8,i16,i32,i64,f32,f64β MLIR integer/float types - Pointers:
nativeptr<'T>β opaque pointers - Strings: Fat pointers
{ptr: memref<?xi8>, len: index}β memref operations - Structures: Records/unions β MLIR struct types with precise layout
Platform operations defined in FNCS as compiler intrinsics:
System (Sys module):
Sys.write(fd: i64, buf: nativeptr<i8>, count: i64): i64β syscallSys.read(fd: i64, buf: nativeptr<i8>, count: i64): i64β syscallSys.exit(code: i32): unitβ process termination
Memory (NativePtr module):
NativePtr.read(ptr: nativeptr<'T>): 'Tβ loadNativePtr.write(ptr: nativeptr<'T>, value: 'T): unitβ storeNativePtr.stackalloc(count: i64): nativeptr<'T>β stack allocation
All intrinsics resolve to platform-specific MLIR during Alex traversal.
module HelloWorld
[<EntryPoint>]
let main argv =
Console.write "Hello, World!"
0Compiles to native binary with:
- Zero .NET runtime dependencies
- Direct syscalls for I/O
- Stack-only allocation (no heap)
- MLIR β LLVM optimization
firefly compile HelloWorld.fidproj
./target/helloworld # Freestanding native binarySee /samples/console/FidelityHelloWorld/ for progressive examples demonstrating pipes, currying, pattern matching, closures, sequences.
.fidproj files use TOML:
[package]
name = "HelloWorld"
[compilation]
memory_model = "stack_only"
target = "native"
[build]
sources = ["HelloWorld.fs"]
output = "helloworld"
output_kind = "console" # or "freestanding"# Build compiler
cd src && dotnet build
# Compile project
firefly compile MyProject.fidproj
# Keep intermediates for inspection
firefly compile MyProject.fidproj -kWith -k flag, inspect each nanopass output in target/intermediates/:
| File | Nanopass Output |
|---|---|
01_psg0.json |
Initial PSG with reachability |
02_intrinsic_recipes.json |
Intrinsic elaboration recipes |
03_psg1.json |
PSG after intrinsic fold-in |
04_saturation_recipes.json |
Baker saturation recipes |
05_psg2.json |
Final saturated PSG to Alex |
06_coeffects.json |
SSA, platform, mutability analysis |
07_output.mlir |
Alex-generated portable MLIR |
08_after_structural_folding.mlir |
Deduplicated function bodies |
09_after_ffi_conversion.mlir |
FFI boundary preparation |
10_after_declaration_collection.mlir |
External function declarations |
11_after_type_normalization.mlir |
Call site type casts |
12_output.ll |
LLVM IR after mlir-opt lowering |
cd tests/regression
dotnet fsi Runner.fsx # All samples
dotnet fsi Runner.fsx -- --parallel # Parallel execution
dotnet fsi Runner.fsx -- --sample 01_HelloWorldDirectsrc/
βββ CLI/ Command-line interface
βββ Core/ Configuration, timing, diagnostics
βββ FrontEnd/ FNCS integration
βββ MiddleEnd/
β βββ PSGElaboration/ Coeffect analysis (SSA, platform, etc.)
β βββ Alex/ MLIR generation layer
β βββ Dialects/ MLIR type system
β βββ CodeGeneration/ Type mapping, sizing
β βββ Traversal/ PSGZipper, XParsec combinators
β βββ Witnesses/ 16 category-selective generators
β βββ Patterns/ Composable MLIR templates
β βββ Pipeline/ Orchestration, MLIR passes
βββ BackEnd/ LLVM compilation, linking
Portable MLIR enables diverse hardware targets:
| Target | Status | Lowering Path |
|---|---|---|
| x86-64 CPU | β Working | memref β LLVM struct |
| ARM Cortex-M | π§ Planned | memref β custom embedded lowering |
| CUDA GPU | π§ Planned | memref β SPIR-V/PTX lowering |
| AMD ROCm | π§ Planned | memref β SPIR-V lowering |
| Xilinx FPGA | π§ Planned | memref β HDL stream buffer |
| CGRA | π§ Planned | memref β dataflow lowering |
| NPU | π§ Planned | memref β tensor descriptor |
| WebAssembly | π§ Planned | memref β WASM linear memory |
Previously blocked by hard-coded LLVM types. Now possible via target-specific mlir-opt lowering.
| Document | Content |
|---|---|
docs/Architecture_Canonical.md |
FNCS-first architecture, intrinsic modules |
docs/PSG_Nanopass_Architecture.md |
Phase 0-5+ detailed design |
docs/TypedTree_Zipper_Design.md |
Zipper traversal, XParsec integration |
docs/XParsec_PSG_Architecture.md |
Pattern combinators, codata witnesses |
docs/Baker_Architecture.md |
Phase 4 type resolution |
docs/PRDs/INDEX.md |
Product requirement documents by category |
Development organized by category-prefixed PRDs. See docs/PRDs/INDEX.md.
Completed:
- F-01 through F-10: Foundation (samples 01-10)
- C-01 through C-07: Closures, higher-order functions, recursion, sequences
In Progress:
- A-01 through A-06: Async workflows, region-based memory
- Multi-stack targeting (ARM Cortex-M, GPU, FPGA)
Planned:
- I-01, I-02: Socket I/O, WebSocket
- T-01 through T-05: Threads, actors, parallel execution
- E-01 through E-03: Embedded MCU support
Areas of interest:
- MLIR dialect design for novel hardware targets
- Memory optimization patterns
- Nanopass transformations for advanced F# features
- F* integration for proof-carrying code
Dual-licensed under Apache License 2.0 and Commercial License. See Commercial.md for commercial use. Patent notice: U.S. Patent Application No. 63/786,247 "System and Method for Zero-Copy Inter-Process Communication Using BARE Protocol". See PATENTS.md.
- Don Syme and F# Contributors: Quotations, active patterns, computation expressions enable self-hosting
- MLIR Community: Multi-level IR infrastructure
- LLVM Project: Robust code generation
- Nanopass Framework: Compiler architecture principles
- Triton-CPU: MLIR-based compilation patterns