pub struct Machine<Op, Val, F, E> where
Val: Debug + PartialEq,
F: FnMut(&mut Stack<Val>, &Op, &mut ConditionStack) -> Result<(), E>, { /* private fields */ }
Expand description
Implementations
sourceimpl<Op, Val, F, E> Machine<Op, Val, F, E> where
Op: Debug + Eq,
Val: Debug + PartialEq + Clone,
F: FnMut(&mut Stack<Val>, &Op, &mut ConditionStack) -> Result<(), E>,
impl<Op, Val, F, E> Machine<Op, Val, F, E> where
Op: Debug + Eq,
Val: Debug + PartialEq + Clone,
F: FnMut(&mut Stack<Val>, &Op, &mut ConditionStack) -> Result<(), E>,
sourcepub fn new(op_sys: F) -> Self
pub fn new(op_sys: F) -> Self
A simple factory that helps constructing a Machine
around a existing operator system, be
it user defined or any of the ones in the op_systems
module.
This method initializes the internal stack to be empty.
Examples
use scriptful::prelude::*;
use scriptful::op_systems::simple_math::simple_math_op_sys;
// Instantiate the machine with a reference to your operator system, or any of the ones in
// the `op_systems` module.
let machine = Machine::new(&simple_math_op_sys);
// Make sure the stack is initialized to be empty.
assert_eq!(machine.stack_length(), 0);
Runsourcepub fn operate(&mut self, item: &Item<Op, Val>) -> Result<Option<&Val>, E>
pub fn operate(&mut self, item: &Item<Op, Val>) -> Result<Option<&Val>, E>
The simplest way to make a Machine
evaluate a single Item
, be it a Value
or
Operator
.
Note that the preferred way to evaluate multiple Item
s at once is through the
run_script
method, which instead of single Item
s takes a
Script
, i.e. an array of Item
s.
Panics
Operating on a Machine
that has an empty Stack
can cause a panic if the
Item
is an operator that tries to pop from it.
Examples
use scriptful::prelude::*;
use scriptful::core::value::Value::*;
use scriptful::op_systems::simple_math::*;
// Instantiate the machine with a reference to your operator system, or any of the ones in
// the `op_systems` module.
let mut machine = Machine::new(&simple_math_op_sys);
// Operating a `Value::Integer(1)` should simply push it into the stack.
let result = machine.operate(&Item::Value(Integer(1)));
// Make sure the value gets pushed.
assert_eq!(result, Some(&Integer(1)));
// The length of the stack should be 1.
assert_eq!(machine.stack_length(), 1);
// Operating a `Value::Integer(2)` should simply push it into the stack.
let result = machine.operate(&Item::Value(Integer(2)));
// Make sure the value gets pushed.
assert_eq!(result, Some(&Integer(2)));
// The length of the stack should be 2.
assert_eq!(machine.stack_length(), 2);
// Operating an `MathOperator::Add` should pop the two topmost values in the stack, add them
// together, and push the result back into the stack.
let result = machine.operate(&Item::Operator(MathOperator::Add));
// Make sure the result is 3.
assert_eq!(result, Some(&Integer(3)));
// The final length of the stack should be 1 again.
assert_eq!(machine.stack_length(), 1);
Runsourcepub fn run_script(
&mut self,
script: ScriptRef<'_, Op, Val>
) -> Result<Option<&Val>, E>
pub fn run_script(
&mut self,
script: ScriptRef<'_, Op, Val>
) -> Result<Option<&Val>, E>
Evaluates a Script
in the context of a Machine
.
Panics
Operating on a Machine
that has an empty Stack
can cause a panic if any of the
Item
s in the Script
is an operator that tries to pop from it.
Examples
use scriptful::prelude::*;
use scriptful::core::value::Value::*;
use scriptful::op_systems::simple_math::*;
// Instantiate the machine with a reference to your operator system, or any of the ones in
// the `op_systems` module.
let mut machine = Machine::new(&simple_math_op_sys);
// Run a script that simply adds 1 and 2.
let result = machine.run_script(&Vec::from([
Item::Value(Integer(1)),
Item::Value(Integer(2)),
Item::Operator(MathOperator::Add),
]));
// The result should unsurprisingly be 3.
assert_eq!(result, Some(&Integer(3)));
// The final length of the stack should be 1.
assert_eq!(machine.stack_length(), 1);
Runsourcepub fn stack_length(&self) -> usize
pub fn stack_length(&self) -> usize
Returns the number of Value
s currently in the Stack
.
Examples
use scriptful::prelude::*;
use scriptful::core::value::Value::*;
use scriptful::op_systems::simple_math::*;
// Instantiate the machine with a reference to your operator system, or any of the ones in
// the `op_systems` module.
let mut machine = Machine::new(&simple_math_op_sys);
// Run a script that simply pushes 4 values into the stack.
machine.run_script(&Vec::from([
Item::Value(Boolean(true)),
Item::Value(Float(3.141592)),
Item::Value(Integer(1337)),
Item::Value(String("foo".into()))
]));
// The final length of the stack should be 4.
assert_eq!(machine.stack_length(), 4);
RunTrait Implementations
sourceimpl<Op, Val, F, E> Debug for Machine<Op, Val, F, E> where
Op: Debug + Eq,
Val: Debug + PartialEq + Clone,
F: FnMut(&mut Stack<Val>, &Op, &mut ConditionStack) -> Result<(), E>,
impl<Op, Val, F, E> Debug for Machine<Op, Val, F, E> where
Op: Debug + Eq,
Val: Debug + PartialEq + Clone,
F: FnMut(&mut Stack<Val>, &Op, &mut ConditionStack) -> Result<(), E>,
Debugging of Machine
only shows the internal Stack
, but not the operator system.
The explanation for this is straightforward: how do you print a dynamic reference to a function?
Auto Trait Implementations
impl<Op, Val, F, E> RefUnwindSafe for Machine<Op, Val, F, E> where
F: RefUnwindSafe,
Val: RefUnwindSafe,
impl<Op, Val, F, E> Send for Machine<Op, Val, F, E> where
F: Send,
Val: Send,
impl<Op, Val, F, E> Sync for Machine<Op, Val, F, E> where
F: Sync,
Val: Sync,
impl<Op, Val, F, E> Unpin for Machine<Op, Val, F, E> where
F: Unpin,
Val: Unpin,
impl<Op, Val, F, E> UnwindSafe for Machine<Op, Val, F, E> where
F: UnwindSafe,
Val: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more