Created
July 11, 2022 08:23
-
-
Save garryspins/1f15e8caf0b930db7c90158165d5b175 to your computer and use it in GitHub Desktop.
Brainfuck in Rust!?!??!?!?!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::io::BufRead; | |
pub struct Interpreter { | |
tape: Option<Vec<u8>>, | |
loopv: Option<Vec<usize>>, | |
index: usize, | |
ptr: usize, | |
} | |
impl Interpreter { | |
pub fn new() -> Self { | |
Self { | |
tape: None, | |
loopv: None, | |
index: 0, | |
ptr: 0, | |
} | |
} | |
fn reset(&mut self) { | |
self.tape = Some(vec![0]); | |
self.loopv = Some(vec![]); | |
self.index = 0; | |
self.ptr = 0; | |
} | |
pub fn run(&mut self, code: &[u8]) -> Result<(), &str> { | |
self.reset(); | |
if let Some(ref mut tape) = self.tape { | |
while self.index < code.len() { | |
match code[self.index] { | |
b'*' => { | |
println!("tape: {:?}", tape); | |
println!("ptr: {:?}", self.ptr); | |
if let Some(ref mut loops) = self.loopv { | |
println!("loops: {:?}", loops); | |
} | |
} | |
b'+' => { | |
tape[self.ptr] = tape[self.ptr].wrapping_add(1); | |
} | |
b'-' => { | |
tape[self.ptr] = tape[self.ptr].wrapping_sub(1); | |
} | |
b'>' => { | |
if self.ptr == (tape.len() - 1) { | |
tape.push(0); | |
} | |
self.ptr += 1; | |
} | |
b'<' => { | |
if self.ptr != 0 { | |
self.ptr -= 1; | |
} | |
} | |
b'.' => { | |
print!("{}", tape[self.ptr] as char); | |
} | |
b',' => { | |
let mut buff = String::new(); | |
std::io::stdin().lock().read_line(&mut buff).unwrap(); | |
tape[self.ptr] = buff.as_bytes()[0]; | |
} | |
b'[' => { | |
if let Some(ref mut loops) = self.loopv { | |
loops.push(self.index); | |
if tape[self.ptr] == 0 { | |
while (self.index < code.len()) && !loops.is_empty() { | |
self.index += 1; | |
match code[self.index] { | |
b'[' => { | |
loops.push(0); | |
} | |
b']' => { | |
loops.pop(); | |
} | |
_ => {} | |
} | |
} | |
if !loops.is_empty() { | |
return Err("Unclosed Noop Loop"); | |
} | |
} | |
} | |
} | |
b']' => { | |
if let Some(ref mut loops) = self.loopv { | |
match loops.last() { | |
Some(ch) => { | |
if tape[self.ptr] == 0 { | |
loops.pop(); | |
} else { | |
self.index = *ch; | |
} | |
} | |
None => { | |
return Err("Closing an unopened loop"); | |
} | |
} | |
} | |
} | |
_ => {} | |
} | |
self.index += 1; | |
} | |
Ok(()) | |
} else { | |
Err("Failed to find tape") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment