1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use crate::{
error::{ BrainfuckError, },
instruction::{ Instruction },
components::{ Tape, Memory, IO, },
};
use std::{
iter::FromIterator,
fmt::{ self, Debug, Display },
};
pub struct Interpreter {
tape: Tape,
memory: Memory,
io: IO,
} impl Interpreter {
pub fn new(tape: Tape, input: Option<Vec<u8>>) -> Self {
let io = if input.is_some() { IO::new(input.unwrap()) } else { IO::default() };
Interpreter {
tape,
memory: Memory::new(),
io,
}
}
fn step(&mut self) -> Result<Option<Vec<u8>>, BrainfuckError> {
match self.tape.get_instruction() {
Instruction::IncPtr => {
self.memory.inc_ptr()?;
},
Instruction::DecPtr => {
self.memory.dec_ptr();
},
Instruction::IncVal => {
self.memory.inc_val();
},
Instruction::DecVal => {
self.memory.dec_val();
},
Instruction::Input => {
self.io.write_to(&mut self.memory);
},
Instruction::Output => {
self.io.pull_from(&mut self.memory);
},
Instruction::SetJump => {
if self.memory.pull() == 0 {
self.tape.jump_forward()?;
}
},
Instruction::Jump => {
if self.memory.pull() != 0 {
self.tape.jump_back()?;
}
},
Instruction::EOF => {
return Ok(Some(self.io.output()))
},
Instruction::NOP => {
return Ok(None)
},
Instruction::Debug => {
eprintln!("{:?};\n{:?};\n{:?};", self.memory, self.io, self.tape)
}
};
Ok(None)
}
pub fn eval(&mut self) -> Result<InterpreterOutput, BrainfuckError> {
loop {
match self.step() {
Err(e) => return Err(e),
Ok(Some(output)) => return Ok(InterpreterOutput(output)),
Ok(None) => (),
}
}
}
}
pub struct InterpreterOutput(Vec<u8>);
impl InterpreterOutput {
pub fn to_string(&self) -> String {
String::from_iter(self.0.iter().map(|byte| *byte as char))
}
pub fn to_vec(&self) -> Vec<u8> {
self.0.clone()
}
}
impl Debug for InterpreterOutput {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self.0)
}
}
impl Display for InterpreterOutput {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.to_string())
}
}
pub fn eval_string(code: &'static str, input: Option<Vec<u8>>) -> Result<InterpreterOutput, BrainfuckError> {
Interpreter::new(Tape::from_string(code), input).eval()
}