pub struct Debugger<Machine, S: Symbol>where
Machine: TuringMachine<S>,{ /* private fields */ }Expand description
Debugger is an super useful TuringMachine for debugging another
Turing machine! This machine debugged all Turing machines in tests.
Note: this machine is not implementing crate::With.
§Examples
use std::cell::RefCell;
use std::ops::Deref;
use std::rc::Rc;
use turing_machine_rs::TuringMachine;
use turing_machine_rs::instruction::{Move, State};
use turing_machine_rs::machines::{Debugger, Classic};
use turing_machine_rs::program::{Extend, Program};
use turing_machine_rs::state::{Configuration, Tape};
fn main() -> Result<(), String> {
let mut program = Program::new(vec![' '], State(1));
program.extend([(1, ' ', 1, ' ', Move::Right)])?;
let machine = Classic::new(program, ' ')?;
let mut debugger = Debugger::new(machine);
let conf = Configuration::new_nrm(Tape::from(" "))?;
let buffer = Rc::new(RefCell::new(String::new()));
let c_buffer = buffer.clone();
debugger.set_c_handler(move |_| {
let mut buffer = c_buffer.borrow_mut();
buffer.push('c');
});
let conf = debugger.execute_once(conf)?;
debugger.execute_once(conf)?;
assert_eq!(String::from("cc"), buffer.deref().borrow().as_ref());
Ok(())
}Implementations§
Source§impl<Machine, S: Symbol> Debugger<Machine, S>where
Machine: TuringMachine<S>,
impl<Machine, S: Symbol> Debugger<Machine, S>where
Machine: TuringMachine<S>,
Sourcepub fn new(machine: Machine) -> Self
pub fn new(machine: Machine) -> Self
Constructs a new Debugger with a TuringMachine and no handlers.
For setup handlers, use the Debugger::set_c_handler
and the Debugger::set_i_handler methods.
Sourcepub fn set_c_handler(&mut self, c_handler: impl Fn(&Configuration<S>) + 'static)
pub fn set_c_handler(&mut self, c_handler: impl Fn(&Configuration<S>) + 'static)
Sets a handler for configurations. Handler must implement
[Fn(&Configuration<Symbol>)] trait.
This function is not permanent so handler can be changed.
Sourcepub fn set_i_handler(
&mut self,
i_handler: impl Fn(&Head<S>, &Tail<S>) + 'static,
)
pub fn set_i_handler( &mut self, i_handler: impl Fn(&Head<S>, &Tail<S>) + 'static, )
Sets a handler for instructions. Handler must implement
[Fn(&Head<Symbol>, &Tail<Symbol>)] trait.
This function is not permanent so handler can be changed.
Trait Implementations§
Source§impl<Machine, S: Symbol> TuringMachine<S> for Debugger<Machine, S>where
Machine: TuringMachine<S>,
impl<Machine, S: Symbol> TuringMachine<S> for Debugger<Machine, S>where
Machine: TuringMachine<S>,
Source§fn execute_once(
&self,
conf: Configuration<S>,
) -> Result<Configuration<S>, String>
fn execute_once( &self, conf: Configuration<S>, ) -> Result<Configuration<S>, String>
Executes Configuration once by mutation.
Works quickly when no handler is set (but you probably don’t want to use the debugger without the debugging).
§Panics
Debugger could panic only if source code is broken - this would be a bug.
All match cases must and are covered.
So you could open an issue on GitHub.
Source§fn execute_until(
&self,
conf: Configuration<S>,
until: impl Fn(&Configuration<S>) -> bool,
) -> Result<Configuration<S>, String>
fn execute_until( &self, conf: Configuration<S>, until: impl Fn(&Configuration<S>) -> bool, ) -> Result<Configuration<S>, String>
Executes Configuration until predicate is false by mutation.
Uses the Debugger::execute_once method in the loop. Works quickly
when no handler set (but probably you don’t wnat to use the debugger without tools).
Source§fn execute(&self, conf: Configuration<S>) -> Result<Configuration<S>, String>
fn execute(&self, conf: Configuration<S>) -> Result<Configuration<S>, String>
crate::program::Program and returns a mutated Configuration
using the TuringMachine::execute_until method with the conf.state == 0
predicate. This is the most commonly used method for crate::program::Program execution.Source§fn translate_std(&self, tape: Tape<S>) -> Result<Tape<S>, String>
fn translate_std(&self, tape: Tape<S>) -> Result<Tape<S>, String>
Tape using the TuringMachine::execute
method as the Configuration::new_std.Source§fn translate_nrm(&self, tape: Tape<S>) -> Result<Tape<S>, String>
fn translate_nrm(&self, tape: Tape<S>) -> Result<Tape<S>, String>
Tape using the TuringMachine::execute
method as the Configuration::new_nrm.