add BrainFuckError to pass memory with the error message

This commit is contained in:
b1ek 2023-08-22 23:49:44 +10:00
parent 1d50dd259b
commit 4d93b7c0d6
Signed by: blek
GPG Key ID: 14546221E3595D0C
1 changed files with 35 additions and 12 deletions

View File

@ -2,6 +2,17 @@
use std::io::{stdout, Write, Read, stdin}; 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 * Check code for syntax errors
*/ */
@ -49,7 +60,7 @@ pub fn lint_code(code: &&str) -> Result<(), Vec<String>> {
Ok(()) 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 mut pos = 0 as usize;
let progsize = bf_str.len(); 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 char == '>' {
if (*pointer) + 1 == 30000 { 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; *pointer += 1;
continue continue
} }
if char == '<' { if char == '<' {
if *pointer == 0 { 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; *pointer -= 1;
continue continue
@ -108,7 +123,9 @@ pub fn eval_mem(bf_str: &&str, mem: &mut [u8], pointer: &mut usize) -> Result<()
} }
let byte = byte.unwrap(); let byte = byte.unwrap();
if byte.is_err() { 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(); mem[*pointer] = byte.unwrap();
continue continue
@ -120,7 +137,9 @@ pub fn eval_mem(bf_str: &&str, mem: &mut [u8], pointer: &mut usize) -> Result<()
if char == ']' { if char == ']' {
if loop_stack.len() == 0 { if loop_stack.len() == 0 {
return Err(format!("Unmatched ']' ({})", pos)); return Err(
BrainFuckError::new(format!("Unmatched ']' ({})", pos), mem)
);
} }
if mem[*pointer] == 0 { 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 { 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(()) 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> { 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 // first check the code
let lint = lint_code(bf_str); let lint = lint_code(bf_str);
@ -156,24 +180,23 @@ pub fn eval(bf_str: &&str) -> Result<[u8; 30000], String> {
// then actually run it // 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); let e = eval_mem(bf_str, &mut memory, &mut pointer);
if e.is_err() { if e.is_err() {
return Err(e.unwrap_err()); let err = e.unwrap_err();
return Err(err.error);
} }
Ok(memory) 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 memory: [u8; 30000] = core::array::from_fn(|_| 0);
let mut pointer = 0 as usize; let mut pointer = 0 as usize;
let e = eval_mem(bf_str, &mut memory, &mut pointer); let e = eval_mem(bf_str, &mut memory, &mut pointer);
if e.is_err() { if e.is_err() {
return Err(e.unwrap_err()); let err = e.unwrap_err();
return Err(err.error);
} }
Ok(memory) Ok(memory)