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};
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<String>> {
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)