A Clojure compiler and interpreter written in Rust.
Mupy compiles Clojure source code to bytecode and executes it on a stack-based virtual machine, delivering native performance with Clojure's expressive syntax.
- Full compilation pipeline: Lexer, reader, macro expander, bytecode compiler, and VM
- 170+ core functions: Arithmetic, collections, higher-order functions, string operations, regex, set algebra
- Clojure-compatible syntax: Lists, vectors, maps, sets, keywords, destructuring, threading macros
- First-class functions: Closures, multi-arity, variadic args,
comp,partial,juxt,complement - Multimethods: Runtime polymorphic dispatch with
defmulti/defmethod - Records & Protocols:
defrecordanddefprotocolfor type-oriented programming - Atoms: Thread-safe mutable state with
swap!,reset!,compare-and-set! - Exception handling:
try/catch/throw - Namespaces:
ns,requirewith aliases and refers - Regex:
re-find,re-seq,re-matcheswith#"..."literals - Interactive REPL: Line editing, history, multi-line input
# Build
cargo build --release
# REPL
cargo run
# Run a file
cargo run -- examples/01_basics.clj
# Run tests (176 tests)
cargo test
# Run benchmarks
cargo bench$ cargo run
Mupy Clojure Compiler v0.1.0
Type expressions to evaluate. Ctrl+D to exit.
user=> (defn fib [n]
(loop [i n a 0 b 1]
(if (zero? i) a (recur (dec i) b (+ a b)))))
#'user/fib
user=> (map fib (range 10))
(0 1 1 2 3 5 8 13 21 34)
user=> (defmulti greet :lang)
#<Multimethod greet>
user=> (defmethod greet :en [_] "Hello!")
:ok
user=> (defmethod greet :pt [_] "Ola!")
:ok
user=> (greet {:lang :pt})
"Ola!"
| File | Description |
|---|---|
examples/01_basics.clj |
Literals, arithmetic, comparisons, predicates |
examples/02_collections.clj |
Vectors, lists, maps, sets, nested access |
examples/03_functions.clj |
Functions, closures, multi-arity, combinators |
examples/04_higher_order.clj |
map/filter/reduce, pipelines, merge-with |
examples/05_strings_regex.clj |
clojure.string, regex, string pipelines |
examples/06_control_flow.clj |
if/cond/case, threading, loop/recur, try/catch |
examples/07_atoms_state.clj |
Atoms, swap!, CAS, state patterns |
examples/08_multimethods.clj |
Multimethods, records, protocols |
examples/09_set_operations.clj |
clojure.set: union, intersection, relational ops |
examples/10_real_world.clj |
Word frequency, data pipelines, FizzBuzz, inventory |
Benchmarks on release build (optimized):
| Operation | Latency |
|---|---|
| VM creation | ~156 us |
Simple arithmetic (+ 1 2 3 4 5) |
~3.7 us |
fib(30) via loop/recur |
~40 us |
fib(100) via loop/recur |
~112 us |
(map inc (range 100)) |
~9 us |
(reduce + (range 100)) |
~10 us |
| Full pipeline (map+filter+reduce over 100) | ~77 us |
comp/partial call |
~3 us |
Atom swap! |
~4 us |
| Cold start (VM creation + eval) | ~130 us |
| Parsing | ~5 us |
Source (.clj) -> Lexer -> Reader -> Macros -> Compiler -> VM -> Value
- Lexer (
src/lexer.rs): Tokenizes source text - Reader (
src/reader.rs): Parses tokens into AST - Macros (
src/macros.rs): Expandsdefn,let,->,cond, etc. to primitives - Compiler (
src/compiler/): Generates bytecode (52 opcodes) - VM (
src/vm.rs): Stack-based bytecode interpreter
See docs/ARCHITECTURE.md for detailed architecture documentation. See docs/LANGUAGE_REFERENCE.md for complete language reference.
- regex (1.x): Regular expression engine
- rustyline (14.x): REPL line editing
- thiserror (2.x): Error type derivation
MIT