[−][src]Struct arithmetic_eval::ExecutableModule
Executable module together with its imports.
An ExecutableModule
is a result of compiling a Block
of statements. A module can import
Value
s, such as commonly used functions. Importing is performed
when building the module.
After the module is created, it can be 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()
. It is possible to run a module multiple times
and to change imports by using Self::set_import()
.
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::run_in_env()
for such cases.
Examples
Basic usage
use arithmetic_parser::grammars::{F32Grammar, Parse, Untyped}; use arithmetic_eval::{fns, Comparisons, ExecutableModule, Prelude, Value}; let module = Untyped::<F32Grammar>::parse_statements("xs.fold(-INFINITY, max)")?; let mut module = ExecutableModule::builder("test", &module)? .with_imports_from(&Prelude) .with_imports_from(&Comparisons) .with_import("INFINITY", Value::Number(f32::INFINITY)) // Set remaining imports to a fixed value. .set_imports(|_| Value::void()); // With the original imports, the returned value is `-INFINITY`. assert_eq!(module.run()?, Value::Number(f32::NEG_INFINITY)); // Imports can be changed. Let's check that `xs` is indeed an import. assert!(module.imports().contains("xs")); // ...or even assert!(module.imports()["fold"].is_function()); // It's possible to iterate over imports, too. let imports = module.imports().iter() .map(|(name, _)| name) .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::Number) .collect(); module.set_import("xs", Value::Tuple(array)); assert_eq!(module.run()?, Value::Number(2.0));
Reusing a module
The same module can be run with multiple imports:
let block = Untyped::<F32Grammar>::parse_statements("x + y")?; let mut module = ExecutableModule::builder("test", &block)? .with_import("x", Value::Number(3.0)) .with_import("y", Value::Number(5.0)) .build(); assert_eq!(module.run()?, Value::Number(8.0)); let mut env = Environment::from_iter(module.imports()); env.insert("x", Value::Number(-1.0)); assert_eq!(module.run_in_env(&mut env)?, Value::Number(4.0));
Behavior on errors
run_in_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::builder("test", &module)? .with_imports_from(&Assertions) .build(); let mut env = Environment::from_iter(module.imports()); assert!(module.run_in_env(&mut env).is_err()); assert_eq!(env["x"], Value::Number(5.0));
Implementations
impl<'a, T> ExecutableModule<'a, T>
[src]
pub fn id(&self) -> &dyn ModuleId
[src]
Gets the identifier of this module.
pub fn set_import(&mut self, name: &str, value: Value<'a, T>) -> &mut Self
[src]
Sets the value of an imported variable.
Panics
Panics if the variable with the specified name is not an import. Check
that the import exists beforehand via imports().contains()
if this is
unknown at compile time.
pub fn imports(&self) -> &ModuleImports<'a, T>
[src]
Returns shared reference to imports of this module.
pub fn with_arithmetic<'s>(
&'s self,
arithmetic: &'s dyn OrdArithmetic<T>
) -> WithArithmetic<'s, 'a, T>
[src]
&'s self,
arithmetic: &'s dyn OrdArithmetic<T>
) -> WithArithmetic<'s, 'a, T>
Combines this module with the specified arithmetic
.
impl<'a, T: Clone + Debug> ExecutableModule<'a, T>
[src]
pub fn builder<G, Id>(
id: Id,
block: &Block<'a, G>
) -> Result<ExecutableModuleBuilder<'a, T>, Error<'a>> where
Id: ModuleId,
G: Grammar<Lit = T>,
[src]
id: Id,
block: &Block<'a, G>
) -> Result<ExecutableModuleBuilder<'a, T>, Error<'a>> where
Id: ModuleId,
G: Grammar<Lit = T>,
Starts building a new module.
impl<'a, T: Clone + Debug> ExecutableModule<'a, T> where
StdArithmetic: OrdArithmetic<T>,
[src]
StdArithmetic: OrdArithmetic<T>,
pub fn run(&self) -> Result<Value<'a, T>, ErrorWithBacktrace<'a>>
[src]
Runs the module with the current values of imports. This is a read-only operation; neither the imports, nor other module state are modified by it.
pub fn run_in_env(
&self,
env: &mut Environment<'a, T>
) -> Result<Value<'a, T>, ErrorWithBacktrace<'a>>
[src]
&self,
env: &mut Environment<'a, T>
) -> Result<Value<'a, T>, ErrorWithBacktrace<'a>>
Runs the module with the specified Environment
. The environment may contain some of
module imports; they will be used to override imports defined in the module.
On execution, the environment is modified to reflect assignments in the topmost scope of the module. The modification takes place regardless of whether or not the execution succeeds. That is, if an error occurs, all preceding assignments in the topmost scope still take place. See the relevant example.
Trait Implementations
impl<T: Clone, '_> Clone for ExecutableModule<'_, T>
[src]
pub fn clone(&self) -> Self
[src]
pub fn clone_from(&mut self, source: &Self)
1.0.0[src]
impl<'a, T: Debug> Debug for ExecutableModule<'a, T>
[src]
impl<T: 'static + Clone, '_> StripCode for ExecutableModule<'_, T>
[src]
type Stripped = ExecutableModule<'static, T>
Resulting type after code stripping.
pub fn strip_code(self) -> Self::Stripped
[src]
Auto Trait Implementations
impl<'a, T> !RefUnwindSafe for ExecutableModule<'a, T>
impl<'a, T> !Send for ExecutableModule<'a, T>
impl<'a, T> !Sync for ExecutableModule<'a, T>
impl<'a, T> Unpin for ExecutableModule<'a, T> where
T: Unpin,
T: Unpin,
impl<'a, T> !UnwindSafe for ExecutableModule<'a, T>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Conv for T
impl<T> Conv for T
impl<T> FmtForward for T
pub fn fmt_binary(self) -> FmtBinary<Self> where
Self: Binary,
Self: Binary,
pub fn fmt_display(self) -> FmtDisplay<Self> where
Self: Display,
Self: Display,
pub fn fmt_lower_exp(self) -> FmtLowerExp<Self> where
Self: LowerExp,
Self: LowerExp,
pub fn fmt_lower_hex(self) -> FmtLowerHex<Self> where
Self: LowerHex,
Self: LowerHex,
pub fn fmt_octal(self) -> FmtOctal<Self> where
Self: Octal,
Self: Octal,
pub fn fmt_pointer(self) -> FmtPointer<Self> where
Self: Pointer,
Self: Pointer,
pub fn fmt_upper_exp(self) -> FmtUpperExp<Self> where
Self: UpperExp,
Self: UpperExp,
pub fn fmt_upper_hex(self) -> FmtUpperHex<Self> where
Self: UpperHex,
Self: UpperHex,
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> Pipe for T where
T: ?Sized,
T: ?Sized,
pub fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
pub fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R where
R: 'a,
R: 'a,
pub fn pipe_ref_mut<'a, R>(
&'a mut self,
func: impl FnOnce(&'a mut Self) -> R
) -> R where
R: 'a,
&'a mut self,
func: impl FnOnce(&'a mut Self) -> R
) -> R where
R: 'a,
pub fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R where
B: 'a + ?Sized,
R: 'a,
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
Self: Borrow<B>,
pub fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R
) -> R where
B: 'a + ?Sized,
R: 'a,
Self: BorrowMut<B>,
&'a mut self,
func: impl FnOnce(&'a mut B) -> R
) -> R where
B: 'a + ?Sized,
R: 'a,
Self: BorrowMut<B>,
pub fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R where
R: 'a,
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
Self: AsRef<U>,
U: 'a + ?Sized,
pub fn pipe_as_mut<'a, U, R>(
&'a mut self,
func: impl FnOnce(&'a mut U) -> R
) -> R where
R: 'a,
Self: AsMut<U>,
U: 'a + ?Sized,
&'a mut self,
func: impl FnOnce(&'a mut U) -> R
) -> R where
R: 'a,
Self: AsMut<U>,
U: 'a + ?Sized,
pub fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R where
R: 'a,
Self: Deref<Target = T>,
T: 'a + ?Sized,
R: 'a,
Self: Deref<Target = T>,
T: 'a + ?Sized,
pub fn pipe_deref_mut<'a, T, R>(
&'a mut self,
func: impl FnOnce(&'a mut T) -> R
) -> R where
R: 'a,
Self: DerefMut<Target = T> + Deref,
T: 'a + ?Sized,
&'a mut self,
func: impl FnOnce(&'a mut T) -> R
) -> R where
R: 'a,
Self: DerefMut<Target = T> + Deref,
T: 'a + ?Sized,
impl<T> Pipe for T
impl<T> PipeAsRef for T
pub fn pipe_as_ref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R where
R: 'a,
Self: AsRef<T>,
T: 'a,
R: 'a,
Self: AsRef<T>,
T: 'a,
pub fn pipe_as_mut<'a, T, R>(
&'a mut self,
func: impl FnOnce(&'a mut T) -> R
) -> R where
R: 'a,
Self: AsMut<T>,
T: 'a,
&'a mut self,
func: impl FnOnce(&'a mut T) -> R
) -> R where
R: 'a,
Self: AsMut<T>,
T: 'a,
impl<T> PipeBorrow for T
pub fn pipe_borrow<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R where
R: 'a,
Self: Borrow<T>,
T: 'a,
R: 'a,
Self: Borrow<T>,
T: 'a,
pub fn pipe_borrow_mut<'a, T, R>(
&'a mut self,
func: impl FnOnce(&'a mut T) -> R
) -> R where
R: 'a,
Self: BorrowMut<T>,
T: 'a,
&'a mut self,
func: impl FnOnce(&'a mut T) -> R
) -> R where
R: 'a,
Self: BorrowMut<T>,
T: 'a,
impl<T> PipeDeref for T
pub fn pipe_deref<'a, R>(
&'a self,
func: impl FnOnce(&'a Self::Target) -> R
) -> R where
R: 'a,
Self: Deref,
&'a self,
func: impl FnOnce(&'a Self::Target) -> R
) -> R where
R: 'a,
Self: Deref,
pub fn pipe_deref_mut<'a, R>(
&'a mut self,
func: impl FnOnce(&'a mut Self::Target) -> R
) -> R where
R: 'a,
Self: DerefMut,
&'a mut self,
func: impl FnOnce(&'a mut Self::Target) -> R
) -> R where
R: 'a,
Self: DerefMut,
impl<T> PipeRef for T
pub fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R where
R: 'a,
R: 'a,
pub fn pipe_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R where
R: 'a,
R: 'a,
impl<T> Tap for T
pub fn tap(self, func: impl FnOnce(&Self)) -> Self
pub fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self
pub fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self where
B: ?Sized,
Self: Borrow<B>,
B: ?Sized,
Self: Borrow<B>,
pub fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self where
B: ?Sized,
Self: BorrowMut<B>,
B: ?Sized,
Self: BorrowMut<B>,
pub fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self where
R: ?Sized,
Self: AsRef<R>,
R: ?Sized,
Self: AsRef<R>,
pub fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self where
R: ?Sized,
Self: AsMut<R>,
R: ?Sized,
Self: AsMut<R>,
pub fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self where
Self: Deref<Target = T>,
T: ?Sized,
Self: Deref<Target = T>,
T: ?Sized,
pub fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self where
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
pub fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
pub fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
pub fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self where
B: ?Sized,
Self: Borrow<B>,
B: ?Sized,
Self: Borrow<B>,
pub fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self where
B: ?Sized,
Self: BorrowMut<B>,
B: ?Sized,
Self: BorrowMut<B>,
pub fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self where
R: ?Sized,
Self: AsRef<R>,
R: ?Sized,
Self: AsRef<R>,
pub fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self where
R: ?Sized,
Self: AsMut<R>,
R: ?Sized,
Self: AsMut<R>,
pub fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self where
Self: Deref<Target = T>,
T: ?Sized,
Self: Deref<Target = T>,
T: ?Sized,
pub fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self where
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
impl<T> Tap for T
pub fn tap<F, R>(self, func: F) -> Self where
F: FnOnce(&Self) -> R,
F: FnOnce(&Self) -> R,
pub fn tap_dbg<F, R>(self, func: F) -> Self where
F: FnOnce(&Self) -> R,
F: FnOnce(&Self) -> R,
pub fn tap_mut<F, R>(self, func: F) -> Self where
F: FnOnce(&mut Self) -> R,
F: FnOnce(&mut Self) -> R,
pub fn tap_mut_dbg<F, R>(self, func: F) -> Self where
F: FnOnce(&mut Self) -> R,
F: FnOnce(&mut Self) -> R,
impl<T, U> TapAsRef<U> for T where
U: ?Sized,
U: ?Sized,
pub fn tap_ref<F, R>(self, func: F) -> Self where
F: FnOnce(&T) -> R,
Self: AsRef<T>,
F: FnOnce(&T) -> R,
Self: AsRef<T>,
pub fn tap_ref_dbg<F, R>(self, func: F) -> Self where
F: FnOnce(&T) -> R,
Self: AsRef<T>,
F: FnOnce(&T) -> R,
Self: AsRef<T>,
pub fn tap_ref_mut<F, R>(self, func: F) -> Self where
F: FnOnce(&mut T) -> R,
Self: AsMut<T>,
F: FnOnce(&mut T) -> R,
Self: AsMut<T>,
pub fn tap_ref_mut_dbg<F, R>(self, func: F) -> Self where
F: FnOnce(&mut T) -> R,
Self: AsMut<T>,
F: FnOnce(&mut T) -> R,
Self: AsMut<T>,
impl<T, U> TapBorrow<U> for T where
U: ?Sized,
U: ?Sized,
pub fn tap_borrow<F, R>(self, func: F) -> Self where
F: FnOnce(&T) -> R,
Self: Borrow<T>,
F: FnOnce(&T) -> R,
Self: Borrow<T>,
pub fn tap_borrow_dbg<F, R>(self, func: F) -> Self where
F: FnOnce(&T) -> R,
Self: Borrow<T>,
F: FnOnce(&T) -> R,
Self: Borrow<T>,
pub fn tap_borrow_mut<F, R>(self, func: F) -> Self where
F: FnOnce(&mut T) -> R,
Self: BorrowMut<T>,
F: FnOnce(&mut T) -> R,
Self: BorrowMut<T>,
pub fn tap_borrow_mut_dbg<F, R>(self, func: F) -> Self where
F: FnOnce(&mut T) -> R,
Self: BorrowMut<T>,
F: FnOnce(&mut T) -> R,
Self: BorrowMut<T>,
impl<T> TapDeref for T
pub fn tap_deref<F, R>(self, func: F) -> Self where
F: FnOnce(&Self::Target) -> R,
Self: Deref,
F: FnOnce(&Self::Target) -> R,
Self: Deref,
pub fn tap_deref_dbg<F, R>(self, func: F) -> Self where
F: FnOnce(&Self::Target) -> R,
Self: Deref,
F: FnOnce(&Self::Target) -> R,
Self: Deref,
pub fn tap_deref_mut<F, R>(self, func: F) -> Self where
F: FnOnce(&mut Self::Target) -> R,
Self: DerefMut,
F: FnOnce(&mut Self::Target) -> R,
Self: DerefMut,
pub fn tap_deref_mut_dbg<F, R>(self, func: F) -> Self where
F: FnOnce(&mut Self::Target) -> R,
Self: DerefMut,
F: FnOnce(&mut Self::Target) -> R,
Self: DerefMut,
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
pub fn to_owned(&self) -> T
[src]
pub fn clone_into(&self, target: &mut T)
[src]
impl<T> TryConv for T
impl<T> TryConv for T
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
pub fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
V: MultiLane<T>,