use crate::prelude::*;
pub struct Machine<'a, Op, Val>
where
Val: core::fmt::Debug + core::cmp::PartialEq,
{
op_sys: &'a dyn Fn(&mut Stack<Val>, &Op),
stack: Stack<Val>,
}
impl<'a, Op, Val> Machine<'a, Op, Val>
where
Op: core::fmt::Debug + core::cmp::Eq,
Val: core::fmt::Debug + core::cmp::PartialEq + core::clone::Clone,
{
pub fn new(op_sys: &'a dyn Fn(&mut Stack<Val>, &Op)) -> Self {
Self {
op_sys,
stack: Stack::<Val>::default(),
}
}
pub fn operate(&mut self, item: &Item<Op, Val>) -> Option<&Val> {
match item {
Item::Operator(operator) => (self.op_sys)(&mut self.stack, operator),
Item::Value(value) => self.stack.push((*value).clone()),
}
self.stack.topmost()
}
pub fn run_script(&mut self, script: &Script<Op, Val>) -> Option<&Val> {
for item in script {
self.operate(item);
}
self.stack.topmost()
}
pub fn stack_length(&self) -> usize {
self.stack.length()
}
}
impl<'a, Op, Val> core::fmt::Debug for Machine<'a, Op, Val>
where
Val: core::fmt::Debug + core::cmp::PartialEq,
{
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
write!(f, "{:?}", self.stack)
}
}