commit c547d90d0bc02b9ee28046f8946a04c28aac0e55 Author: b1ek Date: Tue Aug 22 17:28:55 2023 +1000 init repo diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..2c0284d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "brainrust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/examples/hello_world.rs b/examples/hello_world.rs new file mode 100644 index 0000000..458535b --- /dev/null +++ b/examples/hello_world.rs @@ -0,0 +1,16 @@ +use brainrust::*; + +fn main() { + let eval = eval( + &( + "+++++[>+++++++++<-],[[>--.++>+<<-]>+.->[<.>-]<<,]" + ) + ); + if eval.is_err() { + let err = eval.unwrap_err(); + if err == "Stdin closed" { + return + } + eprintln!("Program failed: {}", err); + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..cfbeeca --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,94 @@ +#![forbid(unsafe_code)] + +use std::io::{stdout, Write, Read, stdin}; + +// struct BrainFuckProgram { +// memory: [u8; 30000], +// pointer: usize, +// source: String +// } + +pub fn eval_mem(bf_str: &&str, mem: &mut [u8], pointer: &mut usize) -> Result<(), String> { + + let mut pos = 0 as usize; + let progsize = bf_str.len(); + let chars = bf_str.chars().collect::>(); + + let mut loop_stack: Vec = vec![]; + + loop { + if pos == progsize { + break + } + + let char = chars[pos]; + + pos += 1; + + if char == '>' { + *pointer += 1; + continue + } + if char == '<' { + *pointer -= 1; + continue + } + if char == '+' { + mem[*pointer] += 1; + continue + } + if char == '-' { + mem[*pointer] -= 1; + continue + } + if char == '.' { + print!("{}", mem[*pointer] as char); + stdout().flush().unwrap(); + continue + } + if char == ',' { + let byte = stdin().bytes().next(); + if byte.is_none() { + return Err("Stdin closed".into()); + } + let byte = byte.unwrap(); + if byte.is_err() { + return Err(byte.unwrap_err().to_string()); + } + mem[*pointer] = byte.unwrap(); + continue + } + if char == '[' { + loop_stack.push(pos); + continue + } + if char == ']' { + + if loop_stack.len() == 0 { + return Err(format!("Invalid loop at position {pos}")); + } + + if mem[*pointer] == 0 { + loop_stack.pop(); + continue + } else { + pos = loop_stack.last().unwrap().clone(); + continue + } + } + } + + Ok(()) +} + +pub fn eval(bf_str: &&str) -> Result<[u8; 30000], String> { + let mut memory: [u8; 30000] = core::array::from_fn(|_| 0); + let mut pointer = 0 as usize; + + let e = eval_mem(bf_str, &mut memory, &mut pointer); + if e.is_err() { + return Err(e.unwrap_err()); + } + + Ok(memory) +} \ No newline at end of file