Skip to main content

amethyst/
tape.rs

1use colored::*;
2use core::fmt::Display;
3
4#[derive(Debug, Clone)]
5pub struct Tape {
6    left: Vec<char>,
7    right: Vec<char>,
8}
9
10impl Default for Tape {
11    fn default() -> Self {
12        Self {
13            left: Vec::new(),
14            right: Vec::new(),
15        }
16    }
17}
18
19impl Display for Tape {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        write!(
22            f,
23            "..@{}|{}|@..",
24            self.left
25                .iter()
26                .flat_map(|sym| ['|', *sym])
27                .collect::<String>(),
28            self.right
29                .iter()
30                .rev()
31                .flat_map(|sym| ['|', *sym])
32                .skip(1)
33                .collect::<String>()
34        )
35    }
36}
37
38impl Tape {
39    pub fn read(&self) -> char {
40        *self.right.last().unwrap_or(&'@')
41    }
42    pub fn write(&mut self, symbol: char) {
43        self.right.pop();
44        self.right.push(symbol);
45    }
46    pub fn move_left(&mut self) {
47        let character = match self.left.pop() {
48            Some(x) => x,
49            None => '@',
50        };
51        self.right.push(character);
52    }
53    pub fn move_right(&mut self) {
54        let character = match self.right.pop() {
55            Some(x) => x,
56            None => '@',
57        };
58        self.left.push(character);
59    }
60    pub fn shift_left(&mut self) {
61        self.left.pop();
62    }
63    pub fn shift_right(&mut self) {
64        let character = match self.right.last() {
65            Some(x) => *x,
66            None => '@',
67        };
68        self.left.push(character);
69    }
70    pub fn initialize(&mut self, input: String) {
71        input
72            .chars()
73            .rev()
74            .for_each(|character| self.right.push(character));
75    }
76    pub fn memory(&self) -> usize {
77        self.left.len() + self.right.len()
78    }
79    pub fn show_output(&self) {
80        println!("{}", "Output:".bright_blue());
81        let output = self
82            .right
83            .iter()
84            .rev()
85            .filter(|sym| **sym != '@')
86            .collect::<String>();
87        println!(
88            "{}",
89            if output == "" {
90                "@".to_string()
91            } else {
92                output
93            }
94        );
95    }
96    pub fn show_tape(&self) {
97        println!("{}", "Tape:".bright_blue());
98        let header = self.left.len();
99        println!(
100            "..@{}|{}|@..",
101            self.left
102                .iter()
103                .flat_map(|sym| ['|', *sym])
104                .collect::<String>(),
105            if self.right.is_empty() {
106                "@".to_owned()
107            } else {
108                self.right
109                    .iter()
110                    .rev()
111                    .flat_map(|sym| ['|', *sym])
112                    .skip(1)
113                    .collect::<String>()
114            }
115        );
116        println!("{}^", " ".repeat(header * 2 + 4));
117    }
118}