Dasher (Rust)
Rust LLVM-based native compiler with type inference
Repository: eddmann/santa-lang-dasher Version: 1.0.1
Overview
Dasher takes an ahead-of-time (AOT) compilation approach, using LLVM to compile santa-lang directly to native machine code.
This provides significant performance improvements for computationally intensive puzzles by generating optimized native executables. Type inference enables specialization for native LLVM operations, with unknown types falling back to runtime library calls.
Downloads
CLI
| Platform | Download |
|---|---|
| Linux (x64) | santa-lang-dasher-cli-1.0.1-linux-amd64 |
| macOS (Intel) | santa-lang-dasher-cli-1.0.1-macos-amd64 |
| macOS (ARM) | santa-lang-dasher-cli-1.0.1-macos-arm64 |
| Docker | docker pull ghcr.io/eddmann/santa-lang-dasher:cli-latest |
Installation
Using Docker (Recommended)
docker run --rm ghcr.io/eddmann/santa-lang-dasher:cli-latest -e '1 + 1'
Binary Download
# Download for your platform
curl -L -o santa https://github.com/eddmann/santa-lang-dasher/releases/download/1.0.1/santa-lang-dasher-cli-1.0.1-macos-arm64
chmod +x santa
./santa --help
Supported Runtimes
Architecture
Source Code → Lexer → Parser → Type Inference → Codegen → LLVM IR → Native Binary
│
Embedded Runtime Library
Dasher uses a multi-stage compilation pipeline:
- Lexer - Tokenization (shared with other Rust implementations)
- Parser - Pratt parser producing an AST
- Type Inference - Bidirectional type inference with unification
- Codegen - LLVM IR generation using inkwell bindings
- LLVM - Optimization and native code generation
Type System
Dasher includes a type inference engine that determines types at compile time when possible:
| Type | Description |
|---|---|
Int |
64-bit signed integer |
Decimal |
64-bit floating point |
String |
UTF-8 string |
Bool |
Boolean |
Nil |
Null value |
List<T> |
Homogeneous list |
Set<T> |
Homogeneous set |
Dict<K,V> |
Dictionary |
Function |
Callable |
Unknown |
Runtime-typed value |
TypeVar |
Inference placeholder |
NaN-Boxing
Values use NaN-boxing for efficient 64-bit representation:
┌─────────────────────────────────────────────────────────────────┐
│ 64-bit Value │
├──────────────────────────────────────────────────────────────────┤
│ Integers: 61-bit signed integer + 3-bit tag │
│ Nil: Special NaN pattern │
│ Boolean: Special NaN patterns (true/false) │
│ Heap Ptr: 48-bit pointer + tag bits │
└──────────────────────────────────────────────────────────────────┘
Heap Objects:
┌────────────┬───────────┬─────────────────────────────────────────┐
│ refcount │ type_tag │ payload │
│ (32-bit) │ (8-bit) │ (variable) │
└────────────┴───────────┴─────────────────────────────────────────┘
Native vs Runtime Dispatch
Dasher uses a two-path execution model:
Fast Path (Known Types): When types are known at compile time, operations compile directly to LLVM instructions:
a + b → LLVM add instruction (when a, b are Int)
Slow Path (Unknown Types): When types can't be determined, operations fall back to runtime library calls:
a + b → runtime_add(a, b) (when types are Unknown)
Key Implementation Details
- Type Inference: Bidirectional inference with call-site re-inference for polymorphic functions
- Closures: Compiled to structures with captured environment
- Tail-Call Optimization: Detected at compile time, implemented as jumps
- Runtime Library: Embedded compressed library extracted at link time
- Collections: Persistent data structures via
imcrate - Memoization: Runtime support for caching expensive function calls
CLI Usage
# Run a solution (compile and execute)
santa-cli solution.santa
# Run with tests
santa-cli -t solution.santa
# Evaluate inline expression
santa-cli -e '1 + 2'
# Compile to native executable
santa-cli -c solution.santa
Building from Source
Requires Rust 1.85+ and LLVM 18.
macOS
brew install llvm@18
export LLVM_SYS_180_PREFIX=$(brew --prefix llvm@18)
Linux
apt install llvm-18 llvm-18-dev
export LLVM_SYS_180_PREFIX=/usr/lib/llvm-18
Build
git clone https://github.com/eddmann/santa-lang-dasher.git
cd santa-lang-dasher
make build # Debug build
make release # Release build
make test # Run tests