Context

Struct Context 

Source
pub struct Context<'ctx, T = DefaultTypeSet>
where T: TypeSet,
{ /* private fields */ }
Expand description

The expression context, which holds variables, functions, and other state needed for evaluation.

Implementations§

Source§

impl<'ctx> Context<'ctx, DefaultTypeSet>

Source

pub fn new() -> Self

Creates a new context with default types.

Source

pub fn parse(source: &'ctx str) -> Result<Self, ExpressionError<'ctx>>

Loads the given program into a new context with default types.

Source§

impl<'ctx, T> Context<'ctx, T>
where T: TypeSet,

Source

pub fn new_with_types() -> Self

Creates a new context. The type set must be specified when using this function.

use somni_expr::{Context, TypeSet32};
let mut ctx = Context::<TypeSet32>::new_with_types();
Source

pub fn parse_with_types( source: &'ctx str, ) -> Result<Self, ExpressionError<'ctx>>

Parses the given program into a new context. The type set must be specified when using this function.

use somni_expr::{Context, TypeSet32};
let mut ctx = Context::<TypeSet32>::parse_with_types("// program source comes here").unwrap();
Source

pub fn new_from_program(source: &'ctx str, program: Program<T::Parser>) -> Self

Loads the given program into a new context.

Source

pub fn evaluate<'s, V>( &'s mut self, source: &'s str, ) -> Result<V::Output, ExpressionError<'s>>
where V: LoadOwned<T>,

Parses and evaluates an expression and returns the result as a specific value type.

This function will attempt to convert the result of the expression to the specified type V. If the conversion fails, it will return an ExpressionError.

use somni_expr::{Context, TypedValue};

let mut context = Context::new();

assert_eq!(context.evaluate::<u64>("1 + 2"), Ok(3));
assert_eq!(context.evaluate::<TypedValue>("1 + 2"), Ok(TypedValue::Int(3)));
Source

pub fn evaluate_parsed<'s, V>( &'s mut self, source: &'s str, expression: &Expression<T::Parser>, ) -> Result<V::Output, ExpressionError<'s>>
where V: LoadOwned<T>,

Evaluates a pre-parsed expression and returns the result as a specific value type.

This function will attempt to convert the result of the expression to the specified type V. If the conversion fails, it will return an ExpressionError.

use somni_expr::{Context, TypedValue};

let mut context = Context::new();

let source = "1 + 2";
let expr = somni_parser::parser::parse_expression(source).unwrap();

assert_eq!(context.evaluate_parsed::<u64>(source, &expr), Ok(3));
assert_eq!(context.evaluate_parsed::<TypedValue>(source, &expr), Ok(TypedValue::Int(3)));
Source

pub fn add_variable<V>(&mut self, name: &'ctx str, value: V)
where V: LoadStore<T>,

Defines a new variable in the context.

The variable can be any type from the current TypeSet, even TypedValue.

The variable will act as a global variable in the context of the program. Its value can be changed by expressions.

use somni_expr::{Context, TypedValue};

let mut context = Context::new();

// Variable does not exist, it can't be assigned:
assert!(context.evaluate::<()>("counter = 0").is_err());

context.add_variable::<u64>("counter", 0);

// Variable exists now, so we can use it:
assert_eq!(context.evaluate::<()>("counter = counter + 1"), Ok(()));
assert_eq!(context.evaluate::<u64>("counter"), Ok(1));
Source

pub fn add_function<F, A>(&mut self, name: &'ctx str, func: F)
where F: DynFunction<A, T> + 'ctx,

Adds a new function to the context.

use somni_expr::{Context, TypedValue};

let mut context = Context::new();

context.add_function("plus_one", |x: u64| x + 1);

assert_eq!(context.evaluate::<u64>("plus_one(2)"), Ok(3));

Trait Implementations§

Source§

impl<'ctx> Default for Context<'ctx, DefaultTypeSet>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<T> ExprContext<T> for Context<'_, T>
where T: TypeSet,

Source§

fn declare(&mut self, variable: &str, value: TypedValue<T>)

Declares a variable in the context.

Source§

fn assign_variable( &mut self, variable: &str, value: &TypedValue<T>, ) -> Result<(), Box<str>>

Assigns a new value to a variable in the context.

Source§

fn open_scope(&mut self)

Opens a new scope in the current stack frame.

Source§

fn close_scope(&mut self)

Closes the last scope in the current stack frame.

Source§

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

Returns a reference to the TypeSet.
Source§

fn try_load_variable(&mut self, variable: &str) -> Option<TypedValue<T>>

Attempts to load a variable from the context.
Source§

fn address_of(&mut self, variable: &str) -> TypedValue<T>

Returns the address of a variable in the context.
Source§

fn at_address( &mut self, address: TypedValue<T>, ) -> Result<TypedValue<T>, Box<str>>

Returns a value from the given address.
Source§

fn assign_address( &mut self, address: TypedValue<T>, value: &TypedValue<T>, ) -> Result<(), Box<str>>

Assigns a new value to a variable in the context.
Source§

fn call_function( &mut self, function_name: &str, args: &[TypedValue<T>], ) -> Result<TypedValue<T>, FunctionCallError>

Calls a function in the context.

Auto Trait Implementations§

§

impl<'ctx, T> Freeze for Context<'ctx, T>
where T: Freeze,

§

impl<'ctx, T = DefaultTypeSet> !RefUnwindSafe for Context<'ctx, T>

§

impl<'ctx, T = DefaultTypeSet> !Send for Context<'ctx, T>

§

impl<'ctx, T = DefaultTypeSet> !Sync for Context<'ctx, T>

§

impl<'ctx, T> Unpin for Context<'ctx, T>
where T: Unpin, <T as TypeSet>::Integer: Unpin, <T as TypeSet>::SignedInteger: Unpin, <T as TypeSet>::Float: Unpin, <T as TypeSet>::String: Unpin,

§

impl<'ctx, T = DefaultTypeSet> !UnwindSafe for Context<'ctx, T>

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

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

Source§

type Error = Infallible

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

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

Performs the conversion.
Source§

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

Source§

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

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

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

Performs the conversion.