rbf/
alloc.rs

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            //println!("{}", self);
40            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 { //Skip to next ]
56                        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 { //Jump to previous [
66                        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}