Rust ยท scripting language
Sprite is a tiny, embeddable scripting language in Rust. Lexer, parser,
tree-walking interpreter, one eval call to drop into any Rust program.
Try it below, right in your browser.
This box runs a small JavaScript
reimplementation of a subset of Sprite (expressions, let, print,
if/else, while) so you can poke at the syntax here. The real
interpreter is the Rust crate.
Lua and Rhai are excellent and much more capable. Sprite is the other end of the spectrum: a scripting language in Rust small enough that reading the whole interpreter is a reasonable way to spend an afternoon.
Lexer, parser, and interpreter are a few hundred lines each. No bytecode compiler, no VM, no parser generator.
sprite::eval(source) returns a Value. A
Session keeps state alive across calls for a REPL or a
long-lived embedding.
Lex, parse, and runtime errors are all typed results. Deeply nested or hostile input returns an error, not a crash.
Variables, arithmetic, comparisons, booleans, control flow, functions, closures, and string concatenation.
# variables and arithmetic let x = 2 + 3 * 4 print(x) # 14 # recursive functions fn fact(n) { if n <= 1 { return 1 } return n * fact(n - 1) } print(fact(5)) # 120 # while loops let i = 1 let sum = 0 while i <= 10 { sum = sum + i i = i + 1 } print(sum) # 55 # closures fn make_counter() { let count = 0 fn increment() { count = count + 1 return count } return increment } let counter = make_counter() print(counter()) # 1 print(counter()) # 2
A clean API for dropping a scripting layer into any Rust program.
let value = sprite::eval(
"2 + 3 * 4"
).unwrap();
assert_eq!(
value.to_string(),
"14"
);
let mut s = sprite::Session::new();
s.run("let score = 0").unwrap();
s.run("score = score + 10").unwrap();
let v = s.run("score").unwrap();
assert_eq!(v.to_string(), "10");