add BrainFuckError to pass memory with the error message
This commit is contained in:
parent
1d50dd259b
commit
4d93b7c0d6
47
src/lib.rs
47
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<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)
|
||||
|
|
Loading…
Reference in New Issue