From e010163faaca10c20d5301af99f1505bb361d5a9 Mon Sep 17 00:00:00 2001 From: elioat <{ID}+{username}@users.noreply.github.com> Date: Fri, 20 Sep 2024 17:15:11 -0400 Subject: * --- rust/bf/src/main.rs | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 rust/bf/src/main.rs (limited to 'rust/bf/src/main.rs') diff --git a/rust/bf/src/main.rs b/rust/bf/src/main.rs new file mode 100644 index 0000000..9257ae2 --- /dev/null +++ b/rust/bf/src/main.rs @@ -0,0 +1,91 @@ +use std::io::{self, Read}; +use std::env; +use std::process; + +fn interpret_brainfuck(code: &str) { + let mut memory = vec![0u8; 30000]; // 30,000 cells of memory initialized to 0 + let mut pointer: usize = 0; // data pointer starts at the first cell + let mut pc: usize = 0; // program counter for the Brainfuck code + let code_chars: Vec = code.chars().collect(); // convert the Brainfuck code to a vector of characters + + // Stack to keep track of [ and ] for loops + let mut loop_stack: Vec = Vec::new(); + + while pc < code_chars.len() { + match code_chars[pc] { + '>' => { + pointer += 1; + if pointer >= memory.len() { + panic!("Pointer out of bounds"); + } + } + '<' => { + if pointer == 0 { + panic!("Pointer out of bounds"); + } + pointer -= 1; + } + '+' => { + memory[pointer] = memory[pointer].wrapping_add(1); // increment with wrap around + } + '-' => { + memory[pointer] = memory[pointer].wrapping_sub(1); // decrement with wrap around + } + '.' => { + print!("{}", memory[pointer] as char); + } + ',' => { + let mut input = [0u8]; + io::stdin().read_exact(&mut input).expect("Failed to read input"); + memory[pointer] = input[0]; + } + '[' => { + if memory[pointer] == 0 { + // Jump to the matching ']' if the current cell is 0 + let mut open_brackets = 1; + while open_brackets > 0 { + pc += 1; + if pc >= code_chars.len() { + panic!("Unmatched ["); + } + if code_chars[pc] == '[' { + open_brackets += 1; + } else if code_chars[pc] == ']' { + open_brackets -= 1; + } + } + } else { + // Push the current position to the stack if not jumping + loop_stack.push(pc); + } + } + ']' => { + if memory[pointer] != 0 { + // Jump back to the matching '[' if the current cell is nonzero + if let Some(loop_start) = loop_stack.last() { + pc = *loop_start; + } else { + panic!("Unmatched ]"); + } + } else { + // Pop the stack if done with the loop + loop_stack.pop(); + } + } + _ => {} // Ignore any non-Brainfuck commands + } + pc += 1; // Move to the next instruction + } +} + +fn main() { + let args: Vec = env::args().collect(); + if args.len() != 2 || !args[1].ends_with(".bf") { + eprintln!("Usage: {} ", args[0]); + process::exit(1); + } + + let filename = &args[1]; + let code = std::fs::read_to_string(filename).expect("Failed to read the file"); + interpret_brainfuck(&code); +} -- cgit 1.4.1-2-gfad0