EvalContext

Struct EvalContext 

Source
pub struct EvalContext {
    pub variables: VariableMap,
    pub constants: ConstantMap,
    pub arrays: ArrayMap,
    pub attributes: AttributeMap,
    pub nested_arrays: NestedArrayMap,
    pub native_functions: Rc<NativeFunctionMap>,
    pub parent: Option<Rc<EvalContext>>,
}
Expand description

Evaluation context for expressions.

This is the main configuration object that holds variables, constants, arrays, functions, and other settings for evaluating expressions. You typically create an EvalContext, add your variables and functions, and then pass it to the interp function.

§Examples

use exp_rs::context::EvalContext;
use exp_rs::engine::interp;
use exp_rs::Real;
use std::rc::Rc;

let mut ctx = EvalContext::new();

// Add variables
ctx.set_parameter("x", 5.0 as Real);
ctx.set_parameter("y", 10.0 as Real);

// Add a constant
ctx.constants.insert("PI_SQUARED".try_into().unwrap(), 9.8696 as Real).unwrap();

// Register a custom function
ctx.register_native_function("multiply", 2, |args| args[0] * args[1]);

// Evaluate expressions using this context
let result = interp("x + y * PI_SQUARED", Some(Rc::new(ctx.clone()))).unwrap();
let result2 = interp("multiply(x, y)", Some(Rc::new(ctx))).unwrap();

Contexts can be nested to create scopes:

use exp_rs::context::EvalContext;
use exp_rs::Real;
use std::rc::Rc;

let mut parent = EvalContext::new();
parent.set_parameter("x", 1.0 as Real);

let mut child = EvalContext::new();
child.set_parameter("y", 2.0 as Real);
child.parent = Some(Rc::new(parent));

// The child context can access both its own variables and the parent's

Fields§

§variables: VariableMap

Variables that can be modified during evaluation

§constants: ConstantMap

Constants that cannot be modified during evaluation

§arrays: ArrayMap

Arrays of values that can be accessed using array[index] syntax

§attributes: AttributeMap

Object attributes that can be accessed using object.attribute syntax

§nested_arrays: NestedArrayMap

Multi-dimensional arrays (not yet fully supported)

§native_functions: Rc<NativeFunctionMap>

Registry of functions available in this context

§parent: Option<Rc<EvalContext>>

Optional parent context for variable/function inheritance

Implementations§

Source§

impl EvalContext

Source

pub fn new() -> Self

Creates a new empty evaluation context.

The context starts with no variables, constants, arrays, or functions. You can add these elements using the appropriate methods and fields.

§Examples
use exp_rs::context::EvalContext;

let ctx = EvalContext::new();
// Now add variables, constants, functions, etc.
Source

pub fn with_default_functions() -> Self

Creates a new context with default math functions registered.

This is a convenience method for creating a context with all standard math functions already registered. It’s equivalent to calling new() since default functions are now always registered.

Kept for backward compatibility.

Source

pub fn empty() -> Self

Creates an evaluation context without any pre-registered functions.

This creates a context with no built-in functions or constants. Note that basic operators (+, -, *, /, %, <, >, <=, >=, ==, !=) are still available as they are handled by the parser, not the function registry.

§Examples
use exp_rs::context::EvalContext;

let mut ctx = EvalContext::empty();
// Basic operators still work
// But functions like sin, cos, abs, etc. must be registered manually
ctx.register_native_function("abs", 1, |args| args[0].abs());
ctx.register_native_function("sin", 1, |args| args[0].sin());
Source

pub fn set_parameter( &mut self, name: &str, value: Real, ) -> Result<Option<Real>, ExprError>

Sets a parameter (variable) in the context.

This method adds or updates a variable in the context. Variables can be used in expressions and their values can be changed between evaluations.

§Parameters
  • name: The name of the variable
  • value: The value to assign to the variable
§Returns

The previous value of the variable, if it existed

§Examples
use exp_rs::context::EvalContext;
use exp_rs::engine::interp;
use exp_rs::Real;
use std::rc::Rc;

let mut ctx = EvalContext::new();
ctx.set_parameter("x", 42.0 as Real);

let result = interp("x * 2", Some(Rc::new(ctx))).unwrap();
assert_eq!(result, 84.0);
Source

pub fn register_native_function<F>( &mut self, name: &str, arity: usize, implementation: F, ) -> Result<(), ExprError>
where F: Fn(&[Real]) -> Real + 'static,

Registers a native function in the context.

Native functions are implemented in Rust and can be called from expressions. They take a slice of Real values as arguments and return a Real value.

§Parameters
  • name: The name of the function as it will be used in expressions
  • arity: The number of arguments the function expects
  • implementation: A closure or function that implements the function logic
§Examples
use exp_rs::context::EvalContext;
use exp_rs::engine::interp;
use exp_rs::Real;
use std::rc::Rc;

let mut ctx = EvalContext::new();

// Register a function that adds all its arguments
ctx.register_native_function("sum", 3, |args| {
    args.iter().sum::<Real>()
});

let result = interp("sum(10, 20, 30)", Some(Rc::new(ctx))).unwrap();
assert_eq!(result, 60.0);

Functions with variable argument counts:

use exp_rs::context::EvalContext;
use exp_rs::engine::interp;
use exp_rs::Real;
use std::rc::Rc;

let mut ctx = EvalContext::new();

// Register a function that calculates the mean of its arguments
ctx.register_native_function("mean", 5, |args| {
    args.iter().sum::<Real>() / args.len() as Real
});

let result = interp("mean(1, 2, 3, 4, 5)", Some(Rc::new(ctx))).unwrap();
assert_eq!(result, 3.0);
Source

pub fn enable_default_functions(&mut self)

Enables AST caching for this context to improve performance.

When enabled, repeated calls to interp with the same expression string will reuse the parsed AST, greatly improving performance for repeated evaluations with different variable values.

This is particularly useful in loops or when evaluating the same expression multiple times with different parameter values.

§Note

AST caching has been removed in the arena-based implementation. The arena architecture provides better performance characteristics without the need for explicit caching.

Disables AST caching and clears the cache.

This is useful if you want to free up memory or if you want to force re-parsing of expressions.

§Note

AST caching has been removed in the arena-based implementation. This functionality is no longer available.

Clear the AST cache if enabled.

Registers all built-in math functions as native functions in the context.

§Usage
let mut ctx = EvalContext::new();
ctx.register_default_math_functions();

After calling this, you can override any built-in by registering your own native function with the same name using register_native_function.

§Feature: libm

If the libm feature is enabled, this will use the libm implementations. Otherwise, it will use the standard library implementation which is not available in no_std environments.

Enables default math functions for this context.

Alias for register_default_math_functions().

Source

pub fn register_default_math_functions(&mut self)

Registers all built-in math functions as native functions in the context.

Source

pub fn get_variable(&self, name: &str) -> Option<Real>

Register a native function with the context.

§Overriding Built-ins

If a function with the same name as a built-in is registered, the user-defined function will take precedence over the built-in. This allows users to override any built-in math function at runtime.

§Disabling Built-ins

If the libm feature is not enabled, built-in math functions are not available, and users must register their own implementations for all required functions.

§Example
let mut ctx = EvalContext::new();
// Override the "sin" function
ctx.register_native_function("sin", 1, |args| 42.0);
Source

pub fn get_constant(&self, name: &str) -> Option<Real>

Source

pub fn get_array(&self, name: &str) -> Option<&Vec<Real>>

Source

pub fn set_attribute( &mut self, object_name: &str, attr_name: &str, value: Real, ) -> Result<Option<Real>, ExprError>

Helper method to set an attribute value on an object

Source

pub fn get_attribute_map( &self, base: &str, ) -> Option<&FnvIndexMap<HString, Real, { crate::types::EXP_RS_MAX_ATTR_KEYS }>>

Source

pub fn get_native_function(&self, name: &str) -> Option<&NativeFunction>

Source

pub fn list_native_functions(&self) -> Vec<String>

Get a list of all native function names in this context (including parent contexts)

Source

pub fn list_expression_functions(&self) -> Vec<String>

Get a list of all expression function names in this context (including parent contexts)

Trait Implementations§

Source§

impl Clone for EvalContext

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Default for EvalContext

Source§

fn default() -> Self

Creates a new EvalContext with default values and math functions registered. This ensures that EvalContext::default() behaves the same as

Auto Trait Implementations§

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> CloneToUninit for T
where T: Clone,

§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.