Function statically_evaluate

Source
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.