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 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);
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
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);
Sourcepub 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);