Debugger

Struct Debugger 

Source
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>,

Source

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.

Source

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.

Source

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>,

Source§

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>

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>

Executes the 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>

Translates and returns a mutated Tape using the TuringMachine::execute method as the Configuration::new_std.
Source§

fn translate_nrm(&self, tape: Tape<S>) -> Result<Tape<S>, String>

Translates and returns a mutated Tape using the TuringMachine::execute method as the Configuration::new_nrm.

Auto Trait Implementations§

§

impl<Machine, S> Freeze for Debugger<Machine, S>
where Machine: Freeze,

§

impl<Machine, S> !RefUnwindSafe for Debugger<Machine, S>

§

impl<Machine, S> !Send for Debugger<Machine, S>

§

impl<Machine, S> !Sync for Debugger<Machine, S>

§

impl<Machine, S> Unpin for Debugger<Machine, S>
where Machine: Unpin,

§

impl<Machine, S> !UnwindSafe for Debugger<Machine, S>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.