ft: add error type instead of plain panic
This commit is contained in:
@@ -1,6 +1,13 @@
|
|||||||
use std::io::{self, Read};
|
use std::io::{self, Read};
|
||||||
|
|
||||||
pub fn interpret(code: &str) -> Vec<u8> {
|
#[derive(Debug)]
|
||||||
|
pub enum BrainFuckError {
|
||||||
|
BracketMissing,
|
||||||
|
UserInput,
|
||||||
|
EmptyStack,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn interpret(code: &str) -> Result<Vec<u8>, BrainFuckError> {
|
||||||
let mut memory = [0 as u8; 10_000];
|
let mut memory = [0 as u8; 10_000];
|
||||||
let mut head = 0 as usize;
|
let mut head = 0 as usize;
|
||||||
let mut pc = 0 as usize;
|
let mut pc = 0 as usize;
|
||||||
@@ -25,6 +32,8 @@ pub fn interpret(code: &str) -> Vec<u8> {
|
|||||||
let mut input_buf = [0u8; 1];
|
let mut input_buf = [0u8; 1];
|
||||||
if io::stdin().read_exact(&mut input_buf).is_ok() {
|
if io::stdin().read_exact(&mut input_buf).is_ok() {
|
||||||
memory[head] = input_buf[0];
|
memory[head] = input_buf[0];
|
||||||
|
} else {
|
||||||
|
return Err(BrainFuckError::UserInput);
|
||||||
}
|
}
|
||||||
log::debug!("Read user input: {}", input_buf[0]);
|
log::debug!("Read user input: {}", input_buf[0]);
|
||||||
}
|
}
|
||||||
@@ -37,7 +46,7 @@ pub fn interpret(code: &str) -> Vec<u8> {
|
|||||||
while count_brackets > 0 {
|
while count_brackets > 0 {
|
||||||
pc += 1;
|
pc += 1;
|
||||||
if pc >= code_bytes.len() {
|
if pc >= code_bytes.len() {
|
||||||
panic!("Missing closing loop!");
|
return Err(BrainFuckError::BracketMissing);
|
||||||
}
|
}
|
||||||
match code_bytes[pc] as char {
|
match code_bytes[pc] as char {
|
||||||
// closing current loop
|
// closing current loop
|
||||||
@@ -62,7 +71,7 @@ pub fn interpret(code: &str) -> Vec<u8> {
|
|||||||
if let Some(start_pc) = loop_stack.last() {
|
if let Some(start_pc) = loop_stack.last() {
|
||||||
pc = *start_pc;
|
pc = *start_pc;
|
||||||
} else {
|
} else {
|
||||||
panic!("Loop stack empty, but still called!")
|
return Err(BrainFuckError::EmptyStack);
|
||||||
}
|
}
|
||||||
// loop done, continue normally
|
// loop done, continue normally
|
||||||
} else {
|
} else {
|
||||||
@@ -76,7 +85,7 @@ pub fn interpret(code: &str) -> Vec<u8> {
|
|||||||
pc += 1;
|
pc += 1;
|
||||||
}
|
}
|
||||||
print!("\n");
|
print!("\n");
|
||||||
return out;
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -86,14 +95,14 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_h() {
|
fn test_h() {
|
||||||
let code = "+++++++++[>++++++++<-]>.";
|
let code = "+++++++++[>++++++++<-]>.";
|
||||||
let out = interpret(code);
|
let out = interpret(code).unwrap();
|
||||||
assert_eq!(std::str::from_utf8(&out).unwrap(), "H");
|
assert_eq!(std::str::from_utf8(&out).unwrap(), "H");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_hello() {
|
fn test_hello() {
|
||||||
let code = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.";
|
let code = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.";
|
||||||
let out = interpret(code);
|
let out = interpret(code).unwrap();
|
||||||
assert_eq!(std::str::from_utf8(&out).unwrap(), "Hello World!\n");
|
assert_eq!(std::str::from_utf8(&out).unwrap(), "Hello World!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,5 +18,8 @@ fn main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
println!("Running file {} with program {}", filename, code);
|
println!("Running file {} with program {}", filename, code);
|
||||||
interpret(&code);
|
match interpret(&code) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(err) => panic!("{:?}", err),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user