Struct arithmetic_eval::exec::ExecutableModule  
source · pub struct ExecutableModule<T> { /* private fields */ }Expand description
Executable module together with its imports.
An ExecutableModule is a result of compiling a Block of statements. A module can import
Values, such as commonly used functions. Importing is performed
when building the module.
After the module is created, it can be associated with an environment via Self::with_env()
and run.
If the last statement of the block is an expression (that is, not terminated with a ;),
it is the result of the execution; otherwise, the result is Value::void().
In some cases (e.g., when building a REPL) it is useful to get not only the outcome
of the module execution, but the intermediate results as well. Use Self::with_mutable_env()
for such cases.
ExecutableModules are generic with respect to the primitive value type, just like Value.
§Examples
§Basic usage
use arithmetic_parser::grammars::{F32Grammar, Parse, Untyped};
use arithmetic_eval::{env, fns, Environment, ExecutableModule, Value};
let module = Untyped::<F32Grammar>::parse_statements(
    "xs.fold(-INFINITY, max)",
)?;
let module = ExecutableModule::new("test", &module)?;
let mut env = Environment::new();
env.insert("INFINITY", Value::Prim(f32::INFINITY))
    .insert("xs", Value::void())
    .extend(env::Prelude::iter().chain(env::Comparisons::iter()));
// With the original imports, the returned value is `-INFINITY`.
assert_eq!(module.with_env(&env)?.run()?, Value::Prim(f32::NEG_INFINITY));
// Imports can be changed. Let's check that `xs` is indeed an import.
assert!(module.is_import("xs"));
// It's possible to iterate over imports, too.
let imports = module.import_names().collect::<HashSet<_>>();
assert!(imports.is_superset(&HashSet::from_iter(vec!["max", "fold"])));
// Change the `xs` import and run the module again.
let array = [1.0, -3.0, 2.0, 0.5].iter().copied()
    .map(Value::Prim)
    .collect();
env.insert("xs", Value::Tuple(array));
assert_eq!(module.with_env(&env)?.run()?, Value::Prim(2.0));§Reusing a module
The same module can be run with multiple imports:
let block = Untyped::<F32Grammar>::parse_statements("x + y")?;
let module = ExecutableModule::new("test", &block)?;
let mut env = Environment::new();
env.insert("x", Value::Prim(3.0)).insert("y", Value::Prim(5.0));
assert_eq!(module.with_env(&env)?.run()?, Value::Prim(8.0));
env.insert("x", Value::Prim(-1.0));
assert_eq!(module.with_env(&env)?.run()?, Value::Prim(4.0));§Behavior on errors
Self::with_mutable_env() modifies the environment even if an error occurs during execution:
let module = Untyped::<F32Grammar>::parse_statements("x = 5; assert_eq(x, 4);")?;
let module = ExecutableModule::new("test", &module)?;
let mut env = Environment::new();
env.extend(Assertions::iter());
assert!(module.with_mutable_env(&mut env)?.run().is_err());
assert_eq!(env["x"], Value::Prim(5.0));Implementations§
source§impl<T: Clone + Debug> ExecutableModule<T>
 
impl<T: Clone + Debug> ExecutableModule<T>
source§impl<T> ExecutableModule<T>
 
impl<T> ExecutableModule<T>
sourcepub fn import_names(&self) -> impl Iterator<Item = &str> + '_
 
pub fn import_names(&self) -> impl Iterator<Item = &str> + '_
Returns a shared reference to imports of this module.
sourcepub fn with_env<'s>(
    &'s self,
    env: &'s Environment<T>,
) -> Result<WithEnvironment<'s, T>, Error>
 
pub fn with_env<'s>( &'s self, env: &'s Environment<T>, ) -> Result<WithEnvironment<'s, T>, Error>
Combines this module with the specified Environment. The environment must contain
all module imports; otherwise, an error will be raised.
§Errors
Returns an error if the environment does not contain all variables imported by this module.
sourcepub fn with_mutable_env<'s>(
    &'s self,
    env: &'s mut Environment<T>,
) -> Result<WithEnvironment<'s, T>, Error>
 
pub fn with_mutable_env<'s>( &'s self, env: &'s mut Environment<T>, ) -> Result<WithEnvironment<'s, T>, Error>
Analogue of Self::with_env() that modifies the provided Environment
when the module is run.
§Errors
Returns an error if the environment does not contain all variables imported by this module.
Trait Implementations§
source§impl<T: Clone> Clone for ExecutableModule<T>
 
impl<T: Clone> Clone for ExecutableModule<T>
source§fn clone(&self) -> ExecutableModule<T>
 
fn clone(&self) -> ExecutableModule<T>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
 
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl<T> Freeze for ExecutableModule<T>
impl<T> !RefUnwindSafe for ExecutableModule<T>
impl<T> Send for ExecutableModule<T>
impl<T> Sync for ExecutableModule<T>
impl<T> Unpin for ExecutableModule<T>where
    T: Unpin,
impl<T> !UnwindSafe for ExecutableModule<T>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
    T: ?Sized,
 
impl<T> BorrowMut<T> for Twhere
    T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
 
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
    T: Clone,
 
impl<T> CloneToUninit for Twhere
    T: Clone,
source§default unsafe fn clone_to_uninit(&self, dst: *mut T)
 
default unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit)