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};
|
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)
|
||||||
|
|
Loading…
Reference in New Issue