A compiler for MML (Modern ML), a strictly-typed, functional-first systems language with ML-style syntax.
- ✅ Hindley-Milner Type Inference with mandatory top-level annotations
- ✅ Algebraic Data Types (ADTs) with pattern matching
- ✅ Exhaustiveness Checking for match expressions
- ✅ First-Class Functions and closures with environment capture
- ✅ Module System using structs as first-class modules
- ✅ Privacy Control with
pubkeyword - ✅ Records with field access and sorted field ordering
- ✅ Tuples with projection
- ✅ External Function Interface (FFI) for C interop
- ✅ LLVM Backend generating optimized native code
- ✅ Executable Programs with C runtime linking
- Hindley-Milner type inference with let-generalization
- Polymorphic type schemes
- ADTs with nullary and unary constructors
- Record types with structural typing
- Function types with automatic currying
- Type annotations required at top level
type Option t = | None | Some t;
type Result t e = | Ok t | Err e;
val unwrap_or : Option I32 -> I32 -> I32 = fn opt => fn default =>
match opt with
| None => default
| Some(x) => x;
val classify : I32 -> String = fn n =>
match n with
| 0 => "zero"
| 1 => "one"
| _ => "many";
val compose : (I32 -> I32) -> (I32 -> I32) -> I32 -> I32 =
fn f => fn g => fn x => f(g(x));
val double : I32 -> I32 = fn x => x * 2;
val triple : I32 -> I32 = fn x => x * 3;
val times6 : I32 -> I32 = compose(double)(triple);
struct Math = {
pub val pi = 3.14;
pub val double = fn (x : I32) => x * 2;
pub val add = fn (x : I32) => fn (y : I32) => x + y;
};
val result : I32 = Math.double(21);
external puts : String -> I32 = "puts" [];
external printf : String -> I32 = "printf" [];
val main : I32 = puts("Hello, World!");
cargo build --release# Build to LLVM IR
cargo run -- build input.mml
# Build and run
cargo run -- run input.mmlbuild <input>- Compile to LLVM IR-o, --output <file>- Specify output file (default: out.ll)
run <input>- Compile and executetest- Run built-in testsrepl- Interactive REPL (TODO)fmt <paths>- Format source code (TODO)
See the examples/ directory for complete programs:
hello_world.mml- Basic "Hello, World!" programclosures.mml- Higher-order functions and closuresoption_type.mml- Option type with utility functionsmodules.mml- Module system with structs
MML Source → Lexer → Parser → Desugar → Type Checker → Code Generator → LLVM IR → Native Binary
-
Lexing (
src/lexer.rs)- Token-based lexer using
logos - Handles keywords, identifiers, literals, operators
- Token-based lexer using
-
Parsing (
src/parser.rs)- Parser combinator using
chumsky - Produces surface AST (
src/ast.rs)
- Parser combinator using
-
Desugaring (
src/desugar.rs)- Converts surface AST to core AST
- Simplifies complex patterns
- Desugars syntactic sugar
-
Type Checking (
src/typechecker.rs)- Hindley-Milner type inference
- Exhaustiveness checking for patterns
- Module and signature conformance checking
-
Code Generation (
src/codegen.rs)- LLVM IR generation using
inkwell - Closure conversion with environment capture
- ADT representation as tagged unions
- C-compatible main function generation
- LLVM IR generation using
- Closures:
{fn_ptr: ptr, env_ptr: ptr}- 16 bytes - ADTs:
{tag: i64, data: i64}- 16 bytes - Records: Sorted field array of i64 values
- Tuples: Array of i64 values
All types are represented internally as:
I32,I64- Integer typesF64- Float typeBool- Boolean typeString- String typet -> u- Function types(t1, t2, ...)- Tuple types{field1: t1, field2: t2, ...}- Record typesCon args- Type constructors
Tests are organized in the tests/ directory:
tests/
├── phase1/ # Core language features
├── phase2/ # Type system and error handling
├── phase3/ # Module system
├── phase4/ # Executable programs
├── integration/ # Full integration tests
└── bugs/ # Bug reproduction and regression tests
# Run Rust tests
cargo test
# Run all phase tests
for f in tests/phase*/*.mml; do
cargo run -- run "$f"
done
# Run integration tests
for f in tests/integration/*.mml; do
cargo run -- run "$f"
done
# Run specific test
cargo run -- run tests/phase1/test_phase1.mmlSee tests/README.md for detailed test documentation.
- Constructor applications in function bodies may cause forward reference issues in some cases
- No proper string operations beyond literal strings
- No standard library beyond basic C FFI
- No garbage collection (uses malloc without free)
- Limited error messages
- REPL implementation
- Code formatter
- Comprehensive standard library
- Better error messages with suggestions
- Implicit structs and type classes
- Task/concurrency primitives
- Garbage collection or ownership system
MIT License
- MML Language Specification - Version 4.0, 2026 Edition
- Based on ML family languages (OCaml, SML, F#)
- Type system: Hindley-Milner with extensions