diff --git a/src/lib.rs b/src/lib.rs index bb2744f..dc7d132 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,17 @@ use std::io::{stdout, Write, Read, stdin}; +pub struct BrainFuckError<'a> { + pub error: String, + pub mem: &'a [u8] +} + +impl BrainFuckError<'_> { + pub fn new(error: String, mem: &[u8]) -> BrainFuckError { + BrainFuckError { error, mem } + } +} + /** * Check code for syntax errors */ @@ -49,7 +60,7 @@ pub fn lint_code(code: &&str) -> Result<(), Vec> { Ok(()) } -pub fn eval_mem(bf_str: &&str, mem: &mut [u8], pointer: &mut usize) -> Result<(), String> { +pub fn eval_mem<'a>(bf_str: &&str, mem: &'a mut [u8], pointer: &mut usize) -> Result<(), BrainFuckError<'a>> { let mut pos = 0 as usize; let progsize = bf_str.len(); @@ -68,14 +79,18 @@ pub fn eval_mem(bf_str: &&str, mem: &mut [u8], pointer: &mut usize) -> Result<() if char == '>' { if (*pointer) + 1 == 30000 { - return Err(format!("Attempt to increase pointer exceeding memory size ({})", pos)); + return Err( + BrainFuckError::new(format!("Attempt to increase pointer exceeding memory size ({})", pos), mem) + ); } *pointer += 1; continue } if char == '<' { if *pointer == 0 { - return Err(format!("Attempt to reduce pointer to less than 0 ({})", pos)); + return Err( + BrainFuckError::new(format!("Attempt to reduce pointer to less than 0 ({})", pos), mem) + ); } *pointer -= 1; continue @@ -108,7 +123,9 @@ pub fn eval_mem(bf_str: &&str, mem: &mut [u8], pointer: &mut usize) -> Result<() } let byte = byte.unwrap(); if byte.is_err() { - return Err(byte.unwrap_err().to_string()); + return Err( + BrainFuckError::new(byte.unwrap_err().to_string(), mem) + ); } mem[*pointer] = byte.unwrap(); continue @@ -120,7 +137,9 @@ pub fn eval_mem(bf_str: &&str, mem: &mut [u8], pointer: &mut usize) -> Result<() if char == ']' { if loop_stack.len() == 0 { - return Err(format!("Unmatched ']' ({})", pos)); + return Err( + BrainFuckError::new(format!("Unmatched ']' ({})", pos), mem) + ); } if mem[*pointer] == 0 { @@ -134,7 +153,9 @@ pub fn eval_mem(bf_str: &&str, mem: &mut [u8], pointer: &mut usize) -> Result<() } if loop_stack.len() != 0 { - return Err(format!("Unmatched '[' ({})", loop_stack.last().unwrap())); + return Err( + BrainFuckError::new(format!("Unmatched '[' ({})", loop_stack.last().unwrap()), mem) + ); } Ok(()) @@ -142,6 +163,9 @@ pub fn eval_mem(bf_str: &&str, mem: &mut [u8], pointer: &mut usize) -> Result<() 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; + // first check the code let lint = lint_code(bf_str); @@ -156,24 +180,23 @@ pub fn eval(bf_str: &&str) -> Result<[u8; 30000], String> { // then actually run it - 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()); + let err = e.unwrap_err(); + return Err(err.error); } Ok(memory) } -pub fn eval_no_lint(bf_str: &&str) -> Result<[u8; 30000], String> { +pub fn eval_no_lint<'a>(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()); + let err = e.unwrap_err(); + return Err(err.error); } Ok(memory)