From 7bab256fc8f48652f5245f8d84951869062d3c3a Mon Sep 17 00:00:00 2001 From: aaron Date: Wed, 8 Jul 2026 19:29:24 +0200 Subject: [PATCH] wrote interpreter source code --- src/main.rs | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index e7a11a9..045d85d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,97 @@ -fn main() { - println!("Hello, world!"); +use anyhow::Result; +use anyhow::anyhow; +use std::collections::HashMap; +use std::io::{self, Read, Write}; +use std::fs; +fn clean_code(code: &str) -> Vec { + let vec: Vec = code.chars().collect(); + let clean = vec + .into_iter() + .filter(|b| "+-<>,.[]".contains(*b)) + .collect(); + clean +} +fn precompute_jump_table(code: &[char]) -> Result> { + let mut jump_table = HashMap::new(); + let mut stack = Vec::new(); + for (i, &char) in code.iter().enumerate() { + if char == '[' { + stack.push(i); + } else if char == ']' { + match stack.pop() { + Some(start_index) => { + jump_table.insert(start_index, i); + jump_table.insert(i, start_index); + } + None => { + return Err(anyhow!("miss matching closing brackets at index {}", i)); + } + } + } + } + if !stack.is_empty() { + return Err(anyhow!("open brackets unclosed")); + } + Ok(jump_table) +} +fn execute(raw_code: &str) -> Result<()> { + let clean = clean_code(raw_code); + let jump_table = precompute_jump_table(&clean)?; + let mut tape: [u8; 30000] = [0; 30000]; + let mut data_ptr: usize = 0; + let mut exec_ptr: usize = 0; + while exec_ptr < clean.len() { + let cmd = clean[exec_ptr]; + match cmd { + '+' => { + tape[data_ptr] = tape[data_ptr].wrapping_add(1); + } + '-' => { + tape[data_ptr] = tape[data_ptr].wrapping_sub(1); + } + '>' => { + data_ptr += 1; + if data_ptr > 29999 { + data_ptr = 0; + } + } + '<' => { + if data_ptr == 0 { + data_ptr = 29999; + } + else { + data_ptr -= 1; + } + } + ',' => { + let mut buf = [0; 1]; +if io::stdin().read_exact(&mut buf).is_ok() { + tape[data_ptr] = buf[0]; +} + } + '.' => { + print!("{}", tape[data_ptr] as char); + let _ = io::stdout().flush(); + } + '[' => { + if tape[data_ptr] == 0 { + exec_ptr = *jump_table.get(&exec_ptr).unwrap(); + } + } + ']' => { + if tape[data_ptr] != 0 { + exec_ptr = *jump_table.get(&exec_ptr).unwrap(); + } + } + _ => {} + } + exec_ptr += 1; + } + Ok(()) +} +fn main() -> Result<()> { + let code_path = std::env::args().nth(1).ok_or_else(|| anyhow!("Usage: bf "))?; + let code = fs::read_to_string(&code_path)?; + execute(&code)?; + Ok(()) }