pub struct Machine<Op, Val, F, E>{ /* private fields */ }Expand description
Implementations§
Source§impl<Op, Val, F, E> Machine<Op, Val, F, E>
impl<Op, Val, F, E> Machine<Op, Val, F, 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);Sourcepub 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 Items at once is through the
run_script method, which instead of single Items takes a
Script, i.e. an array of Items.
§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);Sourcepub 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
Items 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);Sourcepub fn stack_length(&self) -> usize
pub fn stack_length(&self) -> usize
Returns the number of Values 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);