
Skillet — “Lightning-fast formulas, Rust-powered.”
Skillet is a tiny, embeddable expression engine (written in Rust) inspired by Excel formulas and Ruby-style chaining. It parses expressions into an AST and evaluates them with a small runtime.
This MVP supports numbers, strings, booleans, nulls, arrays, method chaining, functions (built-ins), comparisons, logical ops, ternary, array indexing/slicing, spread ..., lambdas with named parameters, and basic type casting via ::Type.
Skilled can be extended with JS, take a look at Documentation
Build
- Requirements: Rust stable (2021 edition)
- Build and test:
cargo build
cargo test
CLI (quick try)
A minimal CLI is included to evaluate expressions without external variables.
cargo run --bin sk -- "= [30,60,80,100].filter(:x > 50).map(:x * 0.9).sum()"
Notes:
- Wrap the expression in quotes in your shell.
- A leading
=is optional (supported for spreadsheet-style familiarity).
Library Usage
Add to your Cargo project (from crates.io):
[]
= "0.0.1"
Or with cargo-edit:
cargo add skillet@0.0.1
Evaluate expressions:
use ;
use HashMap;
Language Features (MVP)
- Numbers, booleans (
TRUE/FALSE), strings ('...' or "..."),NULL - Operators:
+ - * / % ^,> < >= <= == !=,AND/OR/NOT(also&&/||/!), ternary? : - Variables:
:name(provided viaevaluate_withmap) - Functions (subset):
- Math:
SUM,AVG/AVERAGE,MIN,MAX,ROUND,CEIL,FLOOR,ABS,SQRT,POW - Arrays:
ARRAY,FIRST,LAST,CONTAINS,UNIQUE,SORT,REVERSE,JOIN,FLATTEN - Strings:
CONCAT,UPPER,LOWER,TRIM,LENGTH,SPLIT,REPLACE - Logic:
ISBLANK - Functional:
FILTER(array, expr, [param]),MAP(array, expr, [param]),REDUCE(array, expr, initial, [valParam], [accParam]) - Conditional aggregations:
SUMIF(array, expr),AVGIF(array, expr),COUNTIF(array, expr)
- Math:
- Methods (subset): chaining with
.and predicates?- Numbers:
.abs() .round(n) .floor() .ceil(); predicates.positive? .negative? .zero? .even? .odd? .numeric? - Arrays:
.length() .size() .first() .last() .sum() .avg() .min() .max() .sort() .unique() .reverse() .compact() .flatten() - Strings:
.upper() .lower() .trim() .reverse()
- Numbers:
- Arrays: literals
[1, 2, 3]; indexingarr[i](negatives allowed); slicingarr[a:b] - Spread:
...exprinside arg lists - Casting:
expr::Integer|Float|String|Boolean|Array|Currency|DateTime|Json
Examples
- Arithmetic precedence:
= 2 + 3 * 4→14 - Ternary:
= :score >= 90 ? 'A' : 'B' - Named lambda param:
= [1,2,3,4].map(:v * 10, 'v')→[10,20,30,40] - Reduce with named params:
= [1,2,3].reduce(:a + :v, 0, 'v', 'a')→6 - SUMIF:
= SUMIF([1,-2,3,-4], :x > 0)→4 - FLATTEN:
= FLATTEN([1,[2,[3]],4])→[1,2,3,4]
Notes
- This is an MVP; error messages and type coverage are intentionally minimal.
- For variables beyond numbers/strings/arrays (e.g., dates, currency), see
Valueinsrc/types.rs.
Install CLI
If you want the CLI tool sk installed system-wide:
cargo install skillet
JavaScript SDK (Node)
- Node addon lives in
skillet-node(separate npm package): seeskillet-node/README.mdfor usage and build. - Quick usage (after building the addon):
import { evalFormula, evalFormulaWith } from '@skillet-lang/node'
console.log(await evalFormula('=2 + 3 * 4')) // 14
console.log(await evalFormulaWith('=SUM(:a,:b)', { a: 1, b: 2 })) // 3
Features
- Expressions: numbers, strings, booleans, nulls, arrays
- Operators: arithmetic (+ - * / % ^), comparisons (>, <, >=, <=, ==, !=), logical (AND/OR/NOT, &&/||/!)
- Methods: chaining on numbers/strings/arrays (e.g.,
.sum(),.upper()) - Functions:
SUM,AVG,MIN,MAX,ROUND,CEIL,FLOOR,ABS,SQRT,POW, more - Arrays: literals, indexing with negative indices, slicing,
...spread in arg lists - Conditionals: ternary
? :,IF,IFS,XOR,AND,OR,NOT - Functional helpers:
FILTER,MAP,REDUCE,SUMIF,AVGIF,COUNTIF - Types and casts:
::Integer|Float|String|Boolean|Array|Currency|DateTime|Json - Extensibility: register custom Rust functions; Node addon supports JS custom functions
API Surface (Rust)
parse(input: &str) -> Result<Expr, Error>: parse into ASTevaluate(input: &str) -> Result<Value, Error>: evaluate without variablesevaluate_with(input: &str, vars: &HashMap<String, Value>) -> Result<Value, Error>evaluate_with_json(input: &str, json_vars: &str) -> Result<Value, Error>evaluate_with_custom(input: &str, vars: &HashMap<String, Value>) -> Result<Value, Error>evaluate_with_json_custom(input: &str, json_vars: &str) -> Result<Value, Error>- Custom functions:
register_function(Box<dyn CustomFunction>) -> Result<(), Error>unregister_function(name: &str) -> boollist_custom_functions() -> Vec<String>
- Types:
Valueenum:Number(f64) | Array(Vec<Value>) | Boolean(bool) | String(String) | Null | Currency(f64) | DateTime(i64) | Json(String)Errorwithmessageand optionalposition
Vanilla JavaScript (Browser)
To use Skillet in plain browser JavaScript, use the WebAssembly build (@skillet-lang/wasm). This targets modern browsers and bundlers without native builds.
- Status: planned package. The Rust crate uses a few non‑WASM deps that will be feature‑gated for the WASM build (disabling plugins/SQLite).
- Expected usage:
import init, { evalFormula, evalFormulaWith } from '@skillet-lang/wasm'
await init()
console.log(evalFormula('= 2 + 3 * 4')) // 14
console.log(evalFormulaWith('=SUM(:a,:b)', { a: 1, b: 2 })) // 3
Repo folder skillet-wasm contains the scaffold; build with wasm-pack build --target bundler.
Tests
Run the test suite:
cargo test
Author
License
MIT OR Apache-2.0