1#[cfg(not(feature = "no_std"))]
2use std::fmt::{Display, Formatter, write};
3
4#[cfg(feature = "no_std")]
5use core::fmt::{Display, Formatter, write};
6
7#[cfg(feature = "tinix")]
8 extern crate tinix_core;
9#[cfg(feature = "tinix")]
10 use tinix_core as tinix;
11#[cfg(feature = "tinix")]
12 use tinix::println;
13
14
15
16
17#[derive(Debug, Clone)]
18pub struct BrainFuckInterpreter<'a> {
19 tape_ptr : usize,
20 program_ptr : usize,
21 program : &'a str,
22 tape : [u8;1024],
23 jump_stack : Vec<usize>,
24}
25
26impl<'a> BrainFuckInterpreter<'a> {
27 pub fn new(program : &'a str) -> BrainFuckInterpreter {
28 BrainFuckInterpreter {
29 program_ptr : 0,
30 jump_stack : Vec::new(),
31 program : program,
32 tape : [0;1024],
33 tape_ptr : 0,
34 }
35 }
36
37 pub fn run(&mut self) {
38 for _ in 0..self.program.len() {
39 match self.program.as_bytes()[self.program_ptr] {
41 b'>' => self.tape_ptr += 1,
42 b'<' => self.tape_ptr -= 1,
43 b'+' => self.tape[self.tape_ptr] += 1,
44 b'-' => self.tape[self.tape_ptr] -= 1,
45 b'.' => print!("{}",self.tape[self.tape_ptr] as char),
46 b'#' => print!("{}",self.tape[self.tape_ptr] as u8),
47 b',' => {
48 let mut buffer = String::new();
49 std::io::stdin().read_line(&mut buffer).expect("Error Reading From STDIN...");
50 let first_char = buffer.as_bytes()[0];
51 self.tape[self.tape_ptr] = first_char;
52 }
53
54 b'[' => {
55 if self.tape[self.tape_ptr] == 0 { while self.program.as_bytes()[self.program_ptr] != b']' {
57 self.program_ptr += 1;
58 }
59 } else {
60 self.jump_stack.push(self.program_ptr + 0);
61 }
62 }
63
64 b']' => {
65 if self.tape[self.tape_ptr] != 0 { self.program_ptr = *self.jump_stack.last().unwrap();
67 } else {
68 let _ = self.jump_stack.pop();
69 }
70 }
71 _ => {}
72 }
73 self.program_ptr += 1;
74 }
75 }
76
77 pub fn get_ref(&self) -> Box<&BrainFuckInterpreter> {
78 Box::new(self)
79 }
80}
81
82impl Display for BrainFuckInterpreter<'_> {
83 fn fmt(&self, f: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
84 writeln!(f, "Cell Ptr {}", self.tape_ptr);
85 writeln!(f, "Current Cell {} ({})",self.tape[self.tape_ptr], self.tape[self.tape_ptr] as char);
86 writeln!(f, "Program Counter: {}",self.program_ptr);
87 writeln!(f, "Current Command: {}", self.program.as_bytes()[self.program_ptr - 1] as char);
88 for idx in self.tape_ptr .. 256 {
89 write!(f, "{},",self.tape[idx]);
90 }
91 writeln!(f, "\nStack: {:#?}", self.jump_stack)
92 }
93}