1use std::io::{Read, Write};
23
24use crate::memory::Memory;
25
26pub struct Interpreter<'a, R, W>
28where
29 R: Read,
30 W: Write,
31{
32 memory: Memory<u8>,
33 input: &'a mut R,
34 output: &'a mut W,
35}
36
37impl<'a, R, W> Interpreter<'a, R, W>
38where
39 R: Read,
40 W: Write,
41{
42 pub fn new(input: &'a mut R, output: &'a mut W, memory_size: usize) -> Interpreter<'a, R, W> {
44 Interpreter {
45 memory: Memory::new(memory_size),
46 input,
47 output,
48 }
49 }
50
51 pub fn execute(&mut self, source_code: &str) {
53 self.memory.clear();
54 let instructions = parse(&mut source_code.chars());
55 self.execute_instructions(&instructions);
56 }
57
58 fn execute_instructions(&mut self, instructions: &Vec<Instruction>) {
59 for instruction in instructions {
60 match instruction {
61 Instruction::NextCell => self.memory.next(),
62 Instruction::PreviousCell => self.memory.previous(),
63 Instruction::IncrementData => self.memory.increment(),
64 Instruction::DecrementData => self.memory.decrement(),
65 Instruction::OutputData => {
66 let value = self.memory.read();
67 self.output.write(&[*value]).unwrap();
68 }
69 Instruction::InputData => {
70 let mut value = [0_u8];
71 if self.input.read_exact(&mut value).is_ok() {
72 self.memory.write(value[0]);
73 }
74 }
75 Instruction::Loop(loop_instructions) => {
76 while *self.memory.read() != 0 {
77 self.execute_instructions(loop_instructions)
78 }
79 }
80 }
81 }
82 }
83}
84
85#[derive(PartialEq, Debug)]
86enum Instruction {
87 NextCell,
88 PreviousCell,
89 IncrementData,
90 DecrementData,
91 OutputData,
92 InputData,
93 Loop(Vec<Instruction>),
94}
95
96fn parse(chars: &mut impl Iterator<Item = char>) -> Vec<Instruction> {
97 let mut instructions: Vec<Instruction> = Vec::new();
98
99 while let Some(char) = chars.next() {
100 instructions.push(match char {
101 '>' => Instruction::NextCell,
102 '<' => Instruction::PreviousCell,
103 '+' => Instruction::IncrementData,
104 '-' => Instruction::DecrementData,
105 '.' => Instruction::OutputData,
106 ',' => Instruction::InputData,
107 '[' => Instruction::Loop(parse(chars)),
108 ']' => break,
109 _ => continue,
110 });
111 }
112
113 instructions
114}
115
116#[cfg(test)]
117mod tests {
118 use std::io::Cursor;
119
120 use super::*;
121
122 #[test]
123 fn interpreter_can_be_created() {
124 let mut input = Cursor::new(vec![]);
125 let mut output = vec![];
126 let _interpreter = Interpreter::new(&mut input, &mut output, 1);
127 }
128
129 #[test]
130 fn interpreter_can_execute_code() {
131 let mut input = Cursor::new(vec![]);
132 let mut output = vec![];
133 let mut interpreter = Interpreter::new(&mut input, &mut output, 1);
134 interpreter.execute("");
135 }
136
137 #[test]
138 fn interpreter_ignores_non_instructions() {
139 let mut input = Cursor::new(vec![]);
140 let mut output = vec![];
141 let mut interpreter = Interpreter::new(&mut input, &mut output, 1);
142 interpreter.execute(" !\"#$%&'()*/0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz{|}~");
143 let expected: Vec<u8> = vec![];
144 assert_eq!(expected, output)
145 }
146
147 #[test]
148 fn interpreter_outputs_default_cell_value_of_zero() {
149 let mut input = Cursor::new(vec![]);
150 let mut output = vec![];
151 let mut interpreter = Interpreter::new(&mut input, &mut output, 1);
152 interpreter.execute(".");
153 assert_eq!(vec![0], output)
154 }
155
156 #[test]
157 fn interpreter_inputs_and_outputs_value() {
158 let mut input = Cursor::new(vec![1]);
159 let mut output = vec![];
160 let mut interpreter = Interpreter::new(&mut input, &mut output, 1);
161 interpreter.execute(",.");
162 assert_eq!(vec![1], output)
163 }
164
165 #[test]
166 fn interpreter_inputs_and_outputs_multiple_value() {
167 let mut input = Cursor::new(vec![1, 2]);
168 let mut output = vec![];
169 let mut interpreter = Interpreter::new(&mut input, &mut output, 1);
170 interpreter.execute(".,.,.");
171 assert_eq!(vec![0, 1, 2], output)
172 }
173
174 #[test]
175 fn interpreter_does_not_change_anything_if_no_input_value() {
176 let mut input = Cursor::new(vec![]);
177 let mut output = vec![];
178 let mut interpreter = Interpreter::new(&mut input, &mut output, 1);
179 interpreter.execute(",.");
180 assert_eq!(vec![0], output)
181 }
182
183 #[test]
184 fn interpreter_increments_cell() {
185 let mut input = Cursor::new(vec![]);
186 let mut output = vec![];
187 let mut interpreter = Interpreter::new(&mut input, &mut output, 1);
188 interpreter.execute("+.");
189 assert_eq!(vec![1], output)
190 }
191
192 #[test]
193 fn interpreter_decrements_cell() {
194 let mut input = Cursor::new(vec![2]);
195 let mut output = vec![];
196 let mut interpreter = Interpreter::new(&mut input, &mut output, 1);
197 interpreter.execute(",.-.");
198 assert_eq!(vec![2, 1], output)
199 }
200
201 #[test]
202 fn interpreter_increments_and_decrements_cell_multiple_times() {
203 let mut input = Cursor::new(vec![]);
204 let mut output = vec![];
205 let mut interpreter = Interpreter::new(&mut input, &mut output, 1);
206 interpreter.execute(".+.+.+.-.-.-.");
207 assert_eq!(vec![0, 1, 2, 3, 2, 1, 0], output)
208 }
209
210 #[test]
211 fn interpreter_moves_to_next_cell() {
212 let mut input = Cursor::new(vec![]);
213 let mut output = vec![];
214 let mut interpreter = Interpreter::new(&mut input, &mut output, 2);
215 interpreter.execute(".+.>.");
216 assert_eq!(vec![0, 1, 0], output)
217 }
218
219 #[test]
220 fn interpreter_moves_back_and_forth() {
221 let mut input = Cursor::new(vec![]);
222 let mut output = vec![];
223 let mut interpreter = Interpreter::new(&mut input, &mut output, 2);
224 interpreter.execute(".+.>.+.+.<.-.>.");
225 assert_eq!(vec![0, 1, 0, 1, 2, 1, 0, 2], output)
226 }
227
228 #[test]
229 fn interpreter_goes_back_to_first_cell_after_reaching_the_end() {
230 let mut input = Cursor::new(vec![1, 2, 3]);
231 let mut output = vec![];
232 let mut interpreter = Interpreter::new(&mut input, &mut output, 3);
233 interpreter.execute(",>,>,>.>.>.");
234 assert_eq!(vec![1, 2, 3], output)
235 }
236
237 #[test]
238 fn interpreter_goes_back_to_the_end_if_going_back_from_the_first_cell() {
239 let mut input = Cursor::new(vec![1, 2, 3]);
240 let mut output = vec![];
241 let mut interpreter = Interpreter::new(&mut input, &mut output, 3);
242 interpreter.execute(",>,>,><.<.<.");
243 assert_eq!(vec![3, 2, 1], output)
244 }
245
246 #[test]
247 fn interpreter_skips_loop_if_current_cell_is_zero() {
248 let mut input = Cursor::new(vec![]);
249 let mut output = vec![];
250 let mut interpreter = Interpreter::new(&mut input, &mut output, 1);
251 interpreter.execute(".[.].");
252 assert_eq!(vec![0, 0], output)
253 }
254
255 #[test]
256 fn interpreter_executes_loop_once_if_current_cell_is_non_zero() {
257 let mut input = Cursor::new(vec![]);
258 let mut output = vec![];
259 let mut interpreter = Interpreter::new(&mut input, &mut output, 1);
260 interpreter.execute(".+[.-].");
261 assert_eq!(vec![0, 1, 0], output)
262 }
263
264 #[test]
265 fn interpreter_executes_loop_twice_if_current_cell_is_two() {
266 let mut input = Cursor::new(vec![]);
267 let mut output = vec![];
268 let mut interpreter = Interpreter::new(&mut input, &mut output, 1);
269 interpreter.execute(".++[.-].");
270 assert_eq!(vec![0, 2, 1, 0], output)
271 }
272
273 #[test]
274 fn interpreter_executes_embedded_loops() {
275 let mut input = Cursor::new(vec![]);
276 let mut output = vec![];
277 let mut interpreter = Interpreter::new(&mut input, &mut output, 2);
278 interpreter.execute("+[>++[.-].<.-].");
279 assert_eq!(vec![2, 1, 0, 1, 0], output)
280 }
281
282 #[test]
283 fn interpreter_executes_two_embedded_loops() {
284 let mut input = Cursor::new(vec![]);
285 let mut output = vec![];
286 let mut interpreter = Interpreter::new(&mut input, &mut output, 3);
287 interpreter.execute("+[>+[.-]+[.-].<.-].");
288 assert_eq!(vec![1, 1, 0, 1, 0], output)
289 }
290
291 #[test]
292 fn interpreter_executes_double_embedded_loops() {
293 let mut input = Cursor::new(vec![]);
294 let mut output = vec![];
295 let mut interpreter = Interpreter::new(&mut input, &mut output, 3);
296 interpreter.execute("+[->++[->+[.-]<]]");
297 assert_eq!(vec![1, 1], output)
298 }
299
300 #[test]
301 fn interpreter_executes_no_end_loop() {
302 let mut input = Cursor::new(vec![]);
303 let mut output = vec![];
304 let mut interpreter = Interpreter::new(&mut input, &mut output, 3);
305 interpreter.execute(".+.[-.");
306 assert_eq!(vec![0, 1, 0], output)
307 }
308
309 #[test]
310 fn interpreter_executes_embedded_no_end_loop() {
311 let mut input = Cursor::new(vec![]);
312 let mut output = vec![];
313 let mut interpreter = Interpreter::new(&mut input, &mut output, 2);
314 interpreter.execute("+[>++[.-].<.-");
315 assert_eq!(vec![2, 1, 0, 1], output)
316 }
317
318 #[test]
319 fn interpreter_executes_no_embedded_end_loop() {
320 let mut input = Cursor::new(vec![]);
321 let mut output = vec![];
322 let mut interpreter = Interpreter::new(&mut input, &mut output, 2);
323 interpreter.execute("+[>++[.-.<.-].");
324 assert_eq!(vec![2, 1, 1, 0], output)
325 }
326
327 #[test]
328 fn interpreter_executes_embedded_no_end_loops() {
329 let mut input = Cursor::new(vec![]);
330 let mut output = vec![];
331 let mut interpreter = Interpreter::new(&mut input, &mut output, 2);
332 interpreter.execute("+[>++[.-.<.-");
333 assert_eq!(vec![2, 1, 1], output)
334 }
335
336 #[test]
337 fn interpreter_executes_two_embedded_no_end_loop() {
338 let mut input = Cursor::new(vec![]);
339 let mut output = vec![];
340 let mut interpreter = Interpreter::new(&mut input, &mut output, 2);
341 interpreter.execute("+[>+[.-]+[.-].<.-].");
342 assert_eq!(vec![1, 1, 0, 1, 0], output)
343 }
344
345 #[test]
346 fn interpreter_executes_double_embedded_no_end_loops() {
347 let mut input = Cursor::new(vec![]);
348 let mut output = vec![];
349 let mut interpreter = Interpreter::new(&mut input, &mut output, 2);
350 interpreter.execute("+[->++[->+[.-<]]");
351 assert_eq!(vec![1, 1], output)
352 }
353
354 #[test]
355 fn interpreter_executes_only_end_loop() {
356 let mut input = Cursor::new(vec![]);
357 let mut output = vec![];
358 let mut interpreter = Interpreter::new(&mut input, &mut output, 2);
359 interpreter.execute(".].");
360 assert_eq!(vec![0], output)
361 }
362}