diff --git a/src/bf_interpreter/error.rs b/src/bf_interpreter/error.rs index 9f6c867..41047c9 100644 --- a/src/bf_interpreter/error.rs +++ b/src/bf_interpreter/error.rs @@ -1,4 +1,4 @@ -use std::fmt::{Debug, Formatter, Display}; +use std::fmt::{Debug, Display, Formatter}; #[derive(PartialEq)] pub struct InterpreterError { @@ -62,10 +62,15 @@ impl InterpreterErrorKind { impl Display for InterpreterErrorKind { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { match self { - InterpreterErrorKind::PointerOutOfBounds(pointer) => write!(f, "Pointer out of bounds {}", pointer), + InterpreterErrorKind::PointerOutOfBounds(pointer) => { + write!(f, "Pointer out of bounds {}", pointer) + } InterpreterErrorKind::ValueOutOfBounds => write!(f, "Value out of bounds"), - InterpreterErrorKind::IoError(error) => - write!(f, "Failed to read byte from stdin: no bytes available: {}", error), + InterpreterErrorKind::IoError(error) => write!( + f, + "Failed to read byte from stdin: no bytes available: {}", + error + ), InterpreterErrorKind::FlushError(e) => write!(f, "Failed to flush stdout: {}", e), InterpreterErrorKind::UnmatchedBracket => write!(f, "Unmatched bracket"), InterpreterErrorKind::InvalidUtf8 => write!(f, "Invalid utf8"), @@ -88,8 +93,13 @@ mod tests { assert_eq!(error.to_string(), "Value out of bounds"); assert_eq!(error.code, 12); - let error = InterpreterErrorKind::IoError(std::io::Error::new(std::io::ErrorKind::Other, "test")).to_error(); - assert_eq!(error.to_string(), "Failed to read byte from stdin: no bytes available: test"); + let error = + InterpreterErrorKind::IoError(std::io::Error::new(std::io::ErrorKind::Other, "test")) + .to_error(); + assert_eq!( + error.to_string(), + "Failed to read byte from stdin: no bytes available: test" + ); assert_eq!(error.code, 13); /*let error = InterpreterErrorKind::FlushError(e).to_error(); diff --git a/src/bf_interpreter/interpreter.rs b/src/bf_interpreter/interpreter.rs index a72d921..e8f1b00 100644 --- a/src/bf_interpreter/interpreter.rs +++ b/src/bf_interpreter/interpreter.rs @@ -12,10 +12,7 @@ pub struct Interpreter { } impl Interpreter { - pub fn new( - array_size: usize, - features: Vec, - ) -> Self { + pub fn new(array_size: usize, features: Vec) -> Self { Self { cells: vec![0; array_size], pointer: 0, @@ -34,7 +31,6 @@ impl Interpreter { } } - // +[>++<-] fn iterate(&mut self, code: &Vec) -> Result<(), InterpreterError> { trace!("Iterate: {:?}", code); @@ -189,11 +185,9 @@ fn to_bf_commands(bf_code: Vec) -> Result, InterpreterError bf_commands.push(BfCommand::Loop(to_bf_commands(bf_code[i + 1..j].to_vec())?)); i = j; } - _ => { - match BfCommand::from(bf_code[i]) { - Some(command) => bf_commands.push(command), - None => (), - } + _ => match BfCommand::from(bf_code[i]) { + Some(command) => bf_commands.push(command), + None => (), }, } i += 1; @@ -218,27 +212,24 @@ impl BfCommand { #[cfg(test)] mod tests { use super::*; - use pretty_assertions::assert_eq; // for testing only use crate::utils; + use pretty_assertions::assert_eq; // for testing only #[test] fn print_h_combine_repl() { - let mut interpreter = Interpreter::new( - 30000, - vec![], - ); + let mut interpreter = Interpreter::new(30000, vec![]); - assert_eq!(interpreter.run(String::from(">+++++++++[<++++ ++++>-]<.")), Ok(0)); + assert_eq!( + interpreter.run(String::from(">+++++++++[<++++ ++++>-]<.")), + Ok(0) + ); println!(); } #[test] fn print_h_repl() { - let mut interpreter = Interpreter::new( - 30000, - vec![], - ); + let mut interpreter = Interpreter::new(30000, vec![]); assert_eq!(interpreter.run(String::from(">+++++++++")), Ok(0)); assert_eq!(interpreter.run(String::from("[<++++ ++++>-]<.")), Ok(0)); @@ -248,10 +239,7 @@ mod tests { #[test] fn nested_loop_level_1_combine() { - let mut interpreter = Interpreter::new( - 5, - vec![], - ); + let mut interpreter = Interpreter::new(5, vec![]); assert_eq!(interpreter.run(String::from("++[>++[>+<-]<-]")), Ok(0)); assert_eq!(interpreter.cells[2], 4); @@ -259,113 +247,107 @@ mod tests { println!(); } - #[test] fn execute_hello_world_from_file() { - let mut interpreter = Interpreter::new( - 30000, - vec![], - ); - + let mut interpreter = Interpreter::new(30000, vec![]); println!(); - assert_eq!(interpreter.run( - utils::read_brainfuck_code( - &String::from("test_code/hello_world.bf"))), Ok(0)); + assert_eq!( + interpreter.run(utils::read_brainfuck_code(&String::from( + "test_code/hello_world.bf" + ))), + Ok(0) + ); } #[test] fn execute_print_hi_from_file() { - let mut interpreter = Interpreter::new( - 30000, - vec![], - ); + let mut interpreter = Interpreter::new(30000, vec![]); println!(); - assert_eq!(interpreter.run( - utils::read_brainfuck_code(&String::from("test_code/print_hi.bf"))), Ok(0)); + assert_eq!( + interpreter.run(utils::read_brainfuck_code(&String::from( + "test_code/print_hi.bf" + ))), + Ok(0) + ); } #[test] fn execute_print_hi_yooo_from_file() { - let mut interpreter = Interpreter::new( - 30000, - vec![], - ); + let mut interpreter = Interpreter::new(30000, vec![]); println!(); - assert_eq!(interpreter.run( - utils::read_brainfuck_code(&String::from("test_code/print_hi_yooo.bf"))), - Ok(0)); + assert_eq!( + interpreter.run(utils::read_brainfuck_code(&String::from( + "test_code/print_hi_yooo.bf" + ))), + Ok(0) + ); } #[test] fn execute_print_my_first_name_from_formatted_file() { - let mut interpreter = Interpreter::new( - 30000, - vec![], - ); + let mut interpreter = Interpreter::new(30000, vec![]); println!(); - assert_eq!(interpreter.run( - utils::read_brainfuck_code(&String::from("test_code/print_my_first_name_formatted.bf"))), - Ok(0)); + assert_eq!( + interpreter.run(utils::read_brainfuck_code(&String::from( + "test_code/print_my_first_name_formatted.bf" + ))), + Ok(0) + ); } #[test] fn execute_print_my_first_name_from_file() { - let mut interpreter = Interpreter::new( - 30000, - vec![], - ); + let mut interpreter = Interpreter::new(30000, vec![]); println!(); - assert_eq!(interpreter.run( - utils::read_brainfuck_code(&String::from("test_code/print_my_first_name.bf"))), - Ok(0)); + assert_eq!( + interpreter.run(utils::read_brainfuck_code(&String::from( + "test_code/print_my_first_name.bf" + ))), + Ok(0) + ); } #[test] fn execute_print_my_first_name_and_last_name_from_formatted_file() { - let mut interpreter = Interpreter::new( - 30000, - vec![], - ); + let mut interpreter = Interpreter::new(30000, vec![]); println!(); - assert_eq!(interpreter.run( - utils::read_brainfuck_code( - &String::from("test_code/print_my_first_name_and_last_name_formatted.bf"))), - Ok(0)); + assert_eq!( + interpreter.run(utils::read_brainfuck_code(&String::from( + "test_code/print_my_first_name_and_last_name_formatted.bf" + ))), + Ok(0) + ); } #[test] fn execute_print_my_first_name_and_last_name_from_file() { - let mut interpreter = Interpreter::new( - 30000, - vec![], - ); + let mut interpreter = Interpreter::new(30000, vec![]); println!(); - assert_eq!(interpreter.run(utils::read_brainfuck_code( - &String::from("test_code/print_my_first_name_and_last_name.bf"))), - Ok(0)); + assert_eq!( + interpreter.run(utils::read_brainfuck_code(&String::from( + "test_code/print_my_first_name_and_last_name.bf" + ))), + Ok(0) + ); } #[test] fn reset() { - let mut interpreter = Interpreter::new( - 30000, - vec![], - ); - + let mut interpreter = Interpreter::new(30000, vec![]); assert_eq!(interpreter.run(String::from(">++++")), Ok(0)); diff --git a/src/bf_interpreter/mod.rs b/src/bf_interpreter/mod.rs index fb262d8..502ad3d 100644 --- a/src/bf_interpreter/mod.rs +++ b/src/bf_interpreter/mod.rs @@ -1,2 +1,2 @@ +pub mod error; pub mod interpreter; -pub mod error; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index ab4fd0b..059dc23 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,7 @@ mod arguments; +mod bf_interpreter; mod repl; mod utils; -mod bf_interpreter; - use clap::Parser; extern crate pretty_env_logger; @@ -21,24 +20,33 @@ fn main() { info!("Parsed command line arguments: {:?}", args); info!("Initializing interpreter"); - let mut interpreter = Interpreter::new( - args.array_size, - args.features.unwrap_or_else(|| vec![]), - ); + let mut interpreter = + Interpreter::new(args.array_size, args.features.unwrap_or_else(|| vec![])); match args.source { Some(source) => { info!("Running brainfuck source code from file: {}", source); match interpreter.run(utils::read_brainfuck_code(&source)) { Ok(exit_code) => { - info!("Finished running brainfuck source code from file: {}", source); + info!( + "Finished running brainfuck source code from file: {}", + source + ); if !args.without_tiles { - println!("{}", format!( - "Successfully ran brainfuck source code from file: {}", - source - ).bold().green()); - println!("{}{}", "Exiting with code: ".truecolor(33, 97, 61), - exit_code.to_string().bold().green()); + println!( + "{}", + format!( + "Successfully ran brainfuck source code from file: {}", + source + ) + .bold() + .green() + ); + println!( + "{}{}", + "Exiting with code: ".truecolor(33, 97, 61), + exit_code.to_string().bold().green() + ); std::process::exit(exit_code); } } diff --git a/src/repl.rs b/src/repl.rs index c54c9ce..1550b9c 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -1,7 +1,6 @@ use crate::bf_interpreter::interpreter::Interpreter; -use std::io::{Write, BufRead}; use colored::Colorize; - +use std::io::Write; struct Repl { pub interpreter: Interpreter, @@ -27,12 +26,13 @@ impl Repl { // #[no_panic] pub fn run(mut self) -> Result<(), std::io::Error> { loop { - print!("{}", - if self.loop_depth != 0 { - "........ ".yellow() - } else { - PROMPT.to_string().truecolor(54, 76, 76) - } + print!( + "{}", + if self.loop_depth != 0 { + "........ ".yellow() + } else { + PROMPT.to_string().truecolor(54, 76, 76) + } ); std::io::stdout().flush()?; @@ -119,13 +119,22 @@ impl Repl { println!("{}", format!("Current array: {:?}", self.interpreter.cells)); } "array_size" | "as" => { - println!("{}", format!("Current array size: {}", - self.interpreter.cells.len() - .to_string().bold().green())); + println!( + "{}", + format!( + "Current array size: {}", + self.interpreter.cells.len().to_string().bold().green() + ) + ); } "pointer" | "p" => { - println!("{}", format!("Current pointer: {}", - self.interpreter.pointer.to_string().bold().green())); + println!( + "{}", + format!( + "Current pointer: {}", + self.interpreter.pointer.to_string().bold().green() + ) + ); } "pointer_value" | "pv" => { println!( @@ -143,11 +152,17 @@ impl Repl { "save" | "s" => { let file_name = cmd.next().unwrap_or(HISTORY_FILE); - println!("{}", format!("Saving history to file: {file_name}").yellow()); + println!( + "{}", + format!("Saving history to file: {file_name}").yellow() + ); match std::fs::write(file_name, self.history.join("\n")) { Ok(_) => { - println!("{}", format!("Successfully saved history to file: {file_name}") - .green()); + println!( + "{}", + format!("Successfully saved history to file: {file_name}") + .green() + ); } Err(e) => { error!("Failed to save history to file: {}", e); @@ -157,11 +172,17 @@ impl Repl { "load" | "l" => { let file_name = cmd.next().unwrap_or(HISTORY_FILE); - println!("{}", format!("Loading history from file: {file_name}").yellow()); + println!( + "{}", + format!("Loading history from file: {file_name}").yellow() + ); match std::fs::read_to_string(file_name) { Ok(history) => { - println!("{}", format!("Successfully loaded history from file: {file_name}") - .green()); + println!( + "{}", + format!("Successfully loaded history from file: {file_name}") + .green() + ); self.history = history.split("\n").map(|s| s.to_string()).collect(); // Run all commands in history @@ -192,7 +213,8 @@ impl Repl { self.history = Vec::new(); } "help" => { - println!("!array, !a: print the current array\n\ + println!( + "!array, !a: print the current array\n\ !array_size, !as: print the current array size\n\ !pointer, !p: print the current pointer\n\ !pointer_value, !pv: print the current pointer value\n\ @@ -201,11 +223,18 @@ impl Repl { !load, !l: load the REPL history from a file\n\ !reset, !r: reset the REPL\n\ !help: print this help message\n\ - !fuck: exit the REPL"); + !fuck: exit the REPL" + ); } - _ => println!("{}", format!("Unknown command: {}, type {} to show the help", - user_input, (COMMAND_PREFIX.to_string() + "help").green() - ).red()), + _ => println!( + "{}", + format!( + "Unknown command: {}, type {} to show the help", + user_input, + (COMMAND_PREFIX.to_string() + "help").green() + ) + .red() + ), } } None => {} @@ -218,17 +247,20 @@ impl Repl { /// * `interpreter` - The interpreter to use pub fn start(interpreter: Interpreter) { info!("Entering REPL mode"); - println!("{}\n\ + println!( + "{}\n\ Brainfuck interpreter v {}\nBy {}\n\ {}\n\ Type {} to exit :D\n\ type {} to get more fu*king help", - "Welcome to the brainfuck REPL mode! :)".green(), - clap::crate_version!().to_string().yellow(), - clap::crate_authors!().to_string().green(), - "Enter your brainfuck code and press enter to run it.".italic().blue(), - (COMMAND_PREFIX.to_string() + "fuck").bold().red(), - (COMMAND_PREFIX.to_string() + "help").bold().green(), + "Welcome to the brainfuck REPL mode! :)".green(), + clap::crate_version!().to_string().yellow(), + clap::crate_authors!().to_string().green(), + "Enter your brainfuck code and press enter to run it." + .italic() + .blue(), + (COMMAND_PREFIX.to_string() + "fuck").bold().red(), + (COMMAND_PREFIX.to_string() + "help").bold().green(), ); match Repl::new(interpreter).run() { @@ -249,10 +281,7 @@ mod tests { #[test] fn nested_loop_level_1() { - let interpreter = Interpreter::new( - 4, - vec![], - ); + let interpreter = Interpreter::new(4, vec![]); let mut repl = Repl::new(interpreter); @@ -270,10 +299,7 @@ mod tests { #[test] fn nested_loop_level_2() { - let interpreter = Interpreter::new( - 4, - vec![], - ); + let interpreter = Interpreter::new(4, vec![]); let mut repl = Repl::new(interpreter); @@ -294,10 +320,7 @@ mod tests { #[test] fn print_my_first_name() { - let interpreter = Interpreter::new( - 10, - vec![], - ); + let interpreter = Interpreter::new(10, vec![]); let mut repl = Repl::new(interpreter); @@ -348,7 +371,11 @@ mod tests { >>+++ <<- ] - >>. Print s".to_string().split("\n").map(|s| s.to_string()).collect::>(); + >>. Print s" + .to_string() + .split("\n") + .map(|s| s.to_string()) + .collect::>(); for line in code { repl.process(line); @@ -357,25 +384,20 @@ mod tests { #[test] fn print_my_first_name_in_one_command() { - let interpreter = Interpreter::new( - 10, - vec![], - ); + let interpreter = Interpreter::new(10, vec![]); let mut repl = Repl::new(interpreter); let code = "++++++++[>++++[>++<-]>>>>>>++[<<<->>>-]<<<<<<<-]>>+.<<++++[>+++ - [>+++<-]>++<<-]>>+.<<+++[>+++[>-<-]>-<<-]>>-.<<++++++[>>+++<<-]>>.".to_string(); + [>+++<-]>++<<-]>>+.<<+++[>+++[>-<-]>-<<-]>>-.<<++++++[>>+++<<-]>>." + .to_string(); repl.process(code); } #[test] fn print_hello_world() { - let interpreter = Interpreter::new( - 10, - vec![], - ); + let interpreter = Interpreter::new(10, vec![]); let mut repl = Repl::new(interpreter); @@ -415,6 +437,9 @@ mod tests { +++.------.--------. Cell #3 for 'rl' and 'd' >>+. Add 1 to Cell #5 gives us an exclamation point >++. And finally a newline from Cell #6 - ".to_string().split("\n").for_each(|s| repl.process(s.to_string())); + " + .to_string() + .split("\n") + .for_each(|s| repl.process(s.to_string())); } -} \ No newline at end of file +}