dew-core
Minimal expression language, multiple backends.
This crate provides a simple expression parser that compiles string expressions into evaluable ASTs. Variables and functions are provided by the caller—nothing is hardcoded—making it suitable for user-facing expression inputs, shader parameter systems, and dynamic computation pipelines.
Design Philosophy
- Minimal by default: Core supports only arithmetic and variables
- Opt-in complexity: Enable
condfor conditionals,funcfor function calls - No runtime dependencies: Pure Rust, no allocations during evaluation
- Backend-agnostic: AST can be compiled to WGSL, Lua, Cranelift, or evaluated directly
Features
| Feature | Description |
|---|---|
introspect |
AST introspection (free_vars, etc.) - enabled by default |
cond |
Conditionals (if/then/else), comparisons (<, <=, etc.), boolean logic (and, or, not) |
func |
Function calls via [ExprFn] trait and [FunctionRegistry] |
Syntax Reference
Operators (by precedence, low to high)
| Precedence | Operators | Description |
|---|---|---|
| 1 | if c then a else b |
Conditional (requires cond) |
| 2 | a or b |
Logical OR, short-circuit (requires cond) |
| 3 | a and b |
Logical AND, short-circuit (requires cond) |
| 4 | < <= > >= == != |
Comparison (requires cond) |
| 5 | a + b, a - b |
Addition, subtraction |
| 6 | a * b, a / b |
Multiplication, division |
| 7 | a ^ b |
Exponentiation (right-associative) |
| 8 | -a, not a |
Negation, logical NOT (not requires cond) |
| 9 | (a), f(a, b) |
Grouping, function calls (calls require func) |
Literals and Identifiers
- Numbers:
42,3.14,.5,1.0 - Variables: Any identifier (
x,time,my_var) - Functions: Identifier followed by parentheses (
sin(x),clamp(x, 0, 1))
Boolean Semantics (with cond feature)
0.0is false, any non-zero value is true- Comparisons and boolean operators return
1.0(true) or0.0(false) and/oruse short-circuit evaluation
Examples
Basic Arithmetic
use Expr;
use HashMap;
let expr = parse.unwrap;
let mut vars = new;
vars.insert;
vars.insert;
#
let value = expr.eval.unwrap;
#
# let value = expr.eval.unwrap;
assert_eq!; // 3 * 2 + 1 = 7
Working with the AST
use ;
let expr = parse.unwrap;
// Inspect the AST structure
match expr.ast
Custom Functions (with func feature)
use wick_core::{Expr, ExprFn, FunctionRegistry, Ast}; use std::collections::HashMap;
struct Clamp; impl ExprFn for Clamp { fn name(&self) -> &str { "clamp" } fn arg_count(&self) -> usize { 3 } fn call(&self, args: &[f32]) -> f32 { args[0].clamp(args[1], args[2]) } }
let mut registry = FunctionRegistry::new(); registry.register(Clamp);
let expr = Expr::parse("clamp(x, 0, 1)").unwrap(); let mut vars = HashMap::new(); vars.insert("x".to_string(), 1.5);
let value = expr.eval(&vars, ®istry).unwrap(); assert_eq!(value, 1.0); // clamped to [0, 1]
### Conditionals
use Expr;
use HashMap;
let expr = parse.unwrap; // absolute value
let mut vars = new;
vars.insert;
#
let value = expr.eval.unwrap;
#
# let value = expr.eval.unwrap;
assert_eq!;