Created
September 9, 2020 21:31
-
-
Save Benricheson101/76c48d74e036dc7afd538aa43b90205f to your computer and use it in GitHub Desktop.
brainfuck but its all `a`s
This file contains hidden or 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
ââââââââÄÁââââÄÁââÁâââÁâââÁâÀÀÀÀãäÁâÁâÁãÁÁâÄÀäÀãäÁÁàÁãããàâââââââààâââàÁÁàÀãàÀàâââàããããããàããããããããàÁÁâàÁââà |
This file contains hidden or 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; | |
use unicode_segmentation::UnicodeSegmentation; | |
#[derive(PartialEq)] | |
enum BFOperations { | |
IncreasePointer, | |
DecreasePointer, | |
IncreaseCell, | |
DecreaseCell, | |
ReadStdin, | |
WriteStdout, | |
StartLoop, | |
EndLoop, | |
WriteToDebugTape, | |
Other, | |
} | |
pub struct BF { | |
tape: Vec<char>, | |
instructions: Vec<BFOperations>, | |
pos: usize, | |
cell: usize, | |
debug: Vec<char> | |
} | |
impl BF { | |
pub fn new(code: String) -> Self { | |
Self { | |
tape: Vec::new(), | |
instructions: UnicodeSegmentation::graphemes(&code[..], true).map(Self::map_chars).collect::<Vec<BFOperations>>(), | |
pos: 0, | |
cell: 0, | |
debug: Vec::new(), | |
} | |
} | |
fn map_chars(c: &str) -> BFOperations { | |
match c { | |
"Á" => BFOperations::IncreasePointer, | |
"À" => BFOperations::DecreasePointer, | |
"â" => BFOperations::IncreaseCell, | |
"ã" => BFOperations::DecreaseCell, | |
"á" => BFOperations::ReadStdin, | |
"à" => BFOperations::WriteStdout, | |
"Ä" => BFOperations::StartLoop, | |
"ä" => BFOperations::EndLoop, | |
"?" => BFOperations::WriteToDebugTape, | |
_ => BFOperations::Other, | |
} | |
} | |
fn exec(&mut self, skip: bool) -> bool { | |
while self.pos < self.instructions.len() { | |
if self.cell >= self.tape.len() { | |
self.tape.push('\0'); | |
} | |
if self.instructions[self.pos] == BFOperations::StartLoop { | |
self.pos += 1; | |
let old = self.pos; | |
while self.exec(self.tape[self.cell] == '\0') == true { | |
self.pos = old; | |
} | |
} else if self.instructions[self.pos] == BFOperations::EndLoop { | |
return self.tape[self.cell] != '\0'; | |
} else if skip == false { | |
match self.instructions[self.pos] { | |
BFOperations::IncreasePointer => self.cell += 1, | |
BFOperations::DecreasePointer => self.cell -= 1, | |
BFOperations::IncreaseCell => { | |
let i = self.tape[self.cell] as u8; | |
self.tape[self.cell] = if i == 255 { | |
'\0' | |
} else { | |
(i + 1u8) as char | |
} | |
}, | |
BFOperations::DecreaseCell => { | |
let i = self.tape[self.cell] as u8; | |
self.tape[self.cell] = if i == 0 { | |
254u8 as char | |
} else { | |
(i - 1u8) as char | |
} | |
}, | |
BFOperations::WriteStdout => print!("{}", self.tape[self.cell]), | |
BFOperations::ReadStdin => { | |
let mut input = String::new(); | |
io::stdin() | |
.read_line(&mut input) | |
.expect("Failed to read line"); | |
let bytes = input.bytes().nth(0).expect("no byte read") as char; | |
self.tape[self.cell] = bytes; | |
}, | |
BFOperations::WriteToDebugTape => self.debug.push(self.tape[self.cell]), | |
_ => { | |
self.pos += 1; | |
continue; | |
}, | |
}; | |
}; | |
self.pos += 1; | |
}; | |
return false; | |
} | |
pub fn run(&mut self) { | |
self.exec(false); | |
} | |
} | |
#[cfg(test)] | |
mod test { | |
use super::BF; | |
#[test] | |
fn hello_world() { | |
let mut b = BF::new( | |
String::from("ââââââââÄÁââââÄÁââÁâââÁâââÁâÀÀÀÀãäÁâÁâÁãÁÁâÄÀäÀãäÁÁ?Áããã?âââââââ??âââ?ÁÁ?Àã?À?âââ?ãããããã?ãããããããã?ÁÁâ?") | |
); | |
b.run(); | |
assert_eq!( | |
b.debug, | |
vec!['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!'] | |
) | |
} | |
} | |
This file contains hidden or 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
mod interpreter; | |
use std::{env, fs}; | |
fn main() { | |
let path = env::args() | |
.nth(1) | |
.expect("no path given"); | |
let contents = fs::read_to_string(path).expect("Error opening file"); | |
interpreter::BF::new(contents).run(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment