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}