pub fn statically_evaluate(expression: &dyn ExpressionLike) -> Result<Value>Expand description
Evaluate an expression statically without external context.
This function evaluates expressions that contain only literals, operators, and function calls. It cannot evaluate expressions that reference variables or perform assignments. The function uses a thread-safe singleton context with access to all the built-in functions.
§Purpose
Static evaluation is useful for:
- Constant folding and optimization
- Evaluating pure mathematical expressions
- Testing and debugging expression parsing
- Pre-computing values that don’t depend on external state
§Supported Expressions
Allowed:
- All literal values:
42,true,"hello",_ - Arithmetic operations:
1 + 2 * 3,(4 - 1) * 5 - Logical operations:
true & false | true - Relational operations:
5 > 3,2 == 1 + 1 - Conditional expressions:
true ? 1 : 2 - Type casting:
(Number) "123",(Text) 42 - Unary operations:
-5,!true,+10 - Arrays:
(1, 2, 3),(1, "hello", true) - Function calls:
abs(-5),max((1, 5, 3)),length("hello") - Method calls:
"hello".length(),3.14.round() - Complex nested expressions:
abs(-5) + max((1, 2)) * length("test")
Not Allowed:
- Variable references:
x + 5,my_var - Assignment operations:
x = 5 - Any expression requiring external context
§Thread Safety
This function uses a thread-safe singleton pattern with OnceLock<Mutex<>>
to ensure that the function registry is initialized only once and can be
safely accessed from multiple threads simultaneously.
§Examples
use aimx::{ExpressionLike, evaluate::statically_evaluate};
use aimx::expression::parse_expression;
// Basic arithmetic
let (_, expression) = parse_expression("1 + 2 * 3").unwrap();
let result = statically_evaluate(&expression).unwrap();
// Result: 7
// Function calls
let (_, expression) = parse_expression("abs(-5) + max((1, 2))").unwrap();
let result = statically_evaluate(&expression).unwrap();
// Result: 7 (5 + 2)
// Complex expressions
let (_, expression) = parse_expression("5 > 3 ? \"yes\" : \"no\"").unwrap();
let result = statically_evaluate(&expression).unwrap();
// Result: "yes"
// Array operations
let (_, expression) = parse_expression("max((1, 5, 3))").unwrap();
let result = statically_evaluate(&expression).unwrap();
// Result: 5§Errors
This function will return an error for:
- Expressions containing variable references
- Assignment operations
- Invalid syntax or parsing errors
- Runtime errors (division by zero, type mismatches, etc.)
- Function calls to undefined functions
use aimx::{ExpressionLike, evaluate::statically_evaluate};
use aimx::expression::parse_expression;
// This will fail because it references a variable
let (_, expression) = parse_expression("x + 5").unwrap();
let result = statically_evaluate(&expression);
assert!(result.is_err()); // Error: "Non-static expression"
// This will fail due to division by zero
let (_, expression) = parse_expression("10 / 0").unwrap();
let result = statically_evaluate(&expression);
assert!(result.is_err()); // Error: Division by zero§Performance
The singleton pattern ensures that function registration happens only once, making subsequent calls very efficient. The function registry is shared across all threads, minimizing memory usage.
§Arguments
expression- The evaluatable expression to statically evaluate
§Returns
Returns a Result<Value> containing the evaluated result or an error
if the expression cannot be evaluated statically.