15 releases
| 0.9.0-rc.5 | Oct 13, 2025 |
|---|---|
| 0.9.0-rc.3 | Sep 27, 2025 |
| 0.1.6 |
|
#455 in Parser implementations
Used in 29 crates
625KB
12K
SLoC
Lava / MuMu — Core Interpreter
MuMu doesn’t embed into apps, apps embed into MuMu.
The language is the platform; plugins are compiled software that adopt MuMu’s rules and interoperate by construction.
Repository: https://gitlab.com/tofo/core-mumu · Homepage: https://lava.nu11.uk
License: MIT OR Apache-2.0
Lava vs MuMu ?
MuMu is the host runtime and Lava is the language. Both are contained in core-mumu
- Lexer + precedence parser with template strings and regex literals
- Interpreter with
Value/FunctionValueand first‑class functions - Typed data: ints/longs/floats/bools/strings; arrays & 2D matrices; keyed maps; iterators; streams; regex;
MixedArray - Semantics:
- const‑by‑default;
^for scoped mutables;#name = arraydeep‑freezes content TypeName @ exprcasts (right‑associative); assignment is an expression- partial application by default +
_placeholders
- const‑by‑default;
- REPL with history/autocomplete; cooperative pollers keep it responsive
- Plugin system (
extend("ns")) with namespace reservation and dynamic registry safety
Produces one binary: lava (CLI + REPL)
Philosophy — “software embeds into MuMu”
MuMu is a small core. Everything else is software that compiles into the runtime as a plugin and adopts MuMu’s calling & typing rules.
+---------------------+ +------------------------------+
| Lava CLI / REPL | | Guests (compiled plugins) |
| include(), extend()|---->| array:, math:, flow:, av:, |
| history/autocomplete | sqlite:, … |
+---------------------+ | register_all + Cargo_lock |
| +------------------------------+
v
+--------------------------+
| Core Runtime |
| - Value/FunctionValue |
| - namespace reservation |
| - dynamic registry |
| - parser/interpreter |
+--------------------------+
Why this is unique in practice
- Guests are compiled (Rust crates) → clear ABI; no ad‑hoc FFI bridging at call sites
- All guests share one call model (partials,
_), one value space (typed arrays, keyed maps), one error shape (KeyedError) - Plugins compose across namespaces without glue code
The Bridge Contract (for all plugins)
- Register functions as dynamics and bind a same‑name variable:
interp.register_dynamic_function("array:map", func); interp.set_variable("array:map", Value::Function(Box::new(FunctionValue::Named("array:map".into())))); - Host entry‐point for
extend("…"):#[no_mangle] pub unsafe extern "C" fn Cargo_lock(interp: *mut c_void, _extra: *const c_void) -> i32 { register_all(&mut *(interp as *mut Interpreter)); 0 } - Adopt MuMu semantics:
- partials +
_where natural; data‑last ergonomics for transforms - typed results (
IntArray/Float2DArray/ …);MixedArraywhen heterogeneous - errors are strings or
KeyedError; truthiness matches core rules
- partials +
- Namespace hygiene:
extend("ns")reservesns:*; don’t overwrite other dynamics
Follow this and your software becomes part of the language — not an add‑on.
6) Language surface (core)
- Lambdas
(x,y)=>…with capture; partials by default;_placeholders anywhere - Casts
Type @ expr(right‑associative): scalar/array/matrix/mixed/regex/undefined - Arrays auto‑upcast numeric only when needed; negative indexing; growth on assign
- Literals: backtick templates
${…}(nested OK); regex/…/imsx - Operators: arithmetic, comparisons, logical, bitwise (&|^<<>>), NAND
~, ternary?:, prefix/postfix++/-- - Assignment is an expression (right‑assoc), including compound forms
- Variables: const‑by‑default;
^to declare scoped mutables;#name = arraydeep‑freezes content
7) Host vs Web
- Host (default feature
host): REPL + dynamic loading + host helpers (flow:h*) - WASM (feature
wasm): same language/runtime; host‑only surfaces return “unavailable”
Environment knobs:
LAVA_VERBOSE=1— verbose bridges/REPLLAVA_TIMING_VERBOSE=1— poll/await/drop timingLAVA_AWAIT_MAX_MS=<ms>— cap idle‑await loopLAVA_UNLOAD_PLUGINS=1— dlclose plugins at shutdown (default is leak‑on‑exit to avoid buggy dtors)
8) File layout (selected)
src/
main.rs, lib.rs
parser/
lexer.rs, ast.rs, core/{precedence,primary,stmt,driver}.rs
interpreter/
core.rs (scopes, dyn registry, namespace reservation)
eval/{expr,statement,regex,indexing}.rs
apply.rs, lambda.rs, partial.rs, array_runtime.rs, numeric.rs, utils.rs
modules/
compose.rs, type.rs, slog.rs, sput.rs, step.rs, include.rs, try.rs, flow_host.rs
modules/repl/
core/{parse,helpers,print,main_loop}.rs, input.rs, autocomplete.rs, render.rs
examples/ tests/
9) Why this scales
One language → many compiled guests → zero impedance mismatch.
Batch jobs, REPL sessions, streaming pipelines (flow:), audio (av:), databases (sqlite:) — all share MuMu’s values, partials, and errors, so they compose like built‑ins.
10) Credits & license
- Author & Maintainer: Tom Fotheringham (
@tofo) - Thanks: the MuMu community across
core-mumu,array-mumu,math-mumu,flow-mumu,av-mumu,sqlite-mumu
Dual‑licensed under MIT OR Apache‑2.0
SPDX-License-Identifier: MIT OR Apache-2.0
Dependencies
~2.7–4.5MB
~72K SLoC