Format the code 🦀
This commit is contained in:
parent
0d66ddde35
commit
6c3f121111
5 changed files with 45 additions and 45 deletions
|
@ -1,7 +1,7 @@
|
||||||
use std::io::{Read, Write};
|
|
||||||
use std::usize;
|
|
||||||
use crate::arguments;
|
use crate::arguments;
|
||||||
use crate::interpreter::error::InterpreterError;
|
use crate::interpreter::error::InterpreterError;
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
use std::usize;
|
||||||
|
|
||||||
pub struct Interpreter {
|
pub struct Interpreter {
|
||||||
pub cells: Vec<u8>,
|
pub cells: Vec<u8>,
|
||||||
|
@ -13,9 +13,11 @@ pub struct Interpreter {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpreter {
|
impl Interpreter {
|
||||||
pub fn new(array_size: usize,
|
pub fn new(
|
||||||
bf_code: Option<String>,
|
array_size: usize,
|
||||||
features: Vec<arguments::Feature>) -> Self {
|
bf_code: Option<String>,
|
||||||
|
features: Vec<arguments::Feature>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
cells: vec![0; array_size],
|
cells: vec![0; array_size],
|
||||||
pointer: 0,
|
pointer: 0,
|
||||||
|
@ -32,12 +34,12 @@ impl Interpreter {
|
||||||
self.bf_code.push_str(&*bf_code);
|
self.bf_code.push_str(&*bf_code);
|
||||||
bf_code
|
bf_code
|
||||||
}
|
}
|
||||||
None => self.bf_code.clone()
|
None => self.bf_code.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
match self.run_brainfuck_code(&bf_code) {
|
match self.run_brainfuck_code(&bf_code) {
|
||||||
Ok(_) => Ok(0),
|
Ok(_) => Ok(0),
|
||||||
Err(e) => Err(e)
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +51,6 @@ impl Interpreter {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn run_brainfuck_code(&mut self, bf_code: &str) -> Result<(), error::InterpreterError> {
|
fn run_brainfuck_code(&mut self, bf_code: &str) -> Result<(), error::InterpreterError> {
|
||||||
for (i, ch) in bf_code.chars().enumerate() {
|
for (i, ch) in bf_code.chars().enumerate() {
|
||||||
match BfCommand::from_char(ch, i) {
|
match BfCommand::from_char(ch, i) {
|
||||||
|
@ -93,17 +94,17 @@ impl Interpreter {
|
||||||
} else {
|
} else {
|
||||||
self.pointer -= 1;
|
self.pointer -= 1;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
BfCommand::IncVal => {
|
BfCommand::IncVal => {
|
||||||
self.cells[self.pointer] = self.cells[self.pointer].wrapping_add(1);
|
self.cells[self.pointer] = self.cells[self.pointer].wrapping_add(1);
|
||||||
},
|
}
|
||||||
BfCommand::DecVal => {
|
BfCommand::DecVal => {
|
||||||
self.cells[self.pointer] = self.cells[self.pointer].wrapping_sub(1);
|
self.cells[self.pointer] = self.cells[self.pointer].wrapping_sub(1);
|
||||||
},
|
}
|
||||||
BfCommand::Print => {
|
BfCommand::Print => {
|
||||||
print!("{}", self.cells[self.pointer] as char);
|
print!("{}", self.cells[self.pointer] as char);
|
||||||
std::io::stdout().flush().unwrap();
|
std::io::stdout().flush().unwrap();
|
||||||
},
|
}
|
||||||
BfCommand::Read => {
|
BfCommand::Read => {
|
||||||
self.cells[self.pointer] = match std::io::stdin().bytes().next() {
|
self.cells[self.pointer] = match std::io::stdin().bytes().next() {
|
||||||
Some(Ok(byte)) => byte,
|
Some(Ok(byte)) => byte,
|
||||||
|
@ -120,10 +121,10 @@ impl Interpreter {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
BfCommand::LoopStart(i) => {
|
BfCommand::LoopStart(i) => {
|
||||||
self.brackets.push(BfCommand::LoopStart(i));
|
self.brackets.push(BfCommand::LoopStart(i));
|
||||||
},
|
}
|
||||||
BfCommand::LoopEnd(i) => {
|
BfCommand::LoopEnd(i) => {
|
||||||
let open_bracket = self.brackets.pop();
|
let open_bracket = self.brackets.pop();
|
||||||
match open_bracket {
|
match open_bracket {
|
||||||
|
@ -132,7 +133,7 @@ impl Interpreter {
|
||||||
let code = self.bf_code[j..i].to_string();
|
let code = self.bf_code[j..i].to_string();
|
||||||
self.iterate(code)?;
|
self.iterate(code)?;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(error::InterpreterError::new(
|
return Err(error::InterpreterError::new(
|
||||||
format!("Unmatched closing bracket at position {}", i),
|
format!("Unmatched closing bracket at position {}", i),
|
||||||
|
@ -152,7 +153,6 @@ impl Interpreter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
enum BfCommand {
|
enum BfCommand {
|
||||||
IncPtr,
|
IncPtr,
|
||||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -1,7 +1,7 @@
|
||||||
mod arguments;
|
mod arguments;
|
||||||
mod interpreter;
|
mod interpreter;
|
||||||
mod utils;
|
|
||||||
mod repl;
|
mod repl;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ fn main() {
|
||||||
let mut interpreter = interpreter::Interpreter::new(
|
let mut interpreter = interpreter::Interpreter::new(
|
||||||
args.array_size,
|
args.array_size,
|
||||||
utils::read_brainfuck_code_if_any(&args.source),
|
utils::read_brainfuck_code_if_any(&args.source),
|
||||||
args.features.unwrap_or_else(|| vec![])
|
args.features.unwrap_or_else(|| vec![]),
|
||||||
);
|
);
|
||||||
|
|
||||||
match args.source {
|
match args.source {
|
||||||
|
@ -30,7 +30,10 @@ fn main() {
|
||||||
info!("Running brainfuck source code from file: {}", source);
|
info!("Running brainfuck source code from file: {}", source);
|
||||||
match interpreter.run(None) {
|
match interpreter.run(None) {
|
||||||
Ok(exit_code) => {
|
Ok(exit_code) => {
|
||||||
println!("Successfully ran brainfuck source code from file: {}", source);
|
println!(
|
||||||
|
"Successfully ran brainfuck source code from file: {}",
|
||||||
|
source
|
||||||
|
);
|
||||||
println!("Exiting with code: {exit_code}");
|
println!("Exiting with code: {exit_code}");
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
|
@ -40,9 +43,6 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => repl::start(interpreter),
|
||||||
repl::start(interpreter)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
36
src/repl.rs
36
src/repl.rs
|
@ -1,5 +1,5 @@
|
||||||
use std::io::Write;
|
|
||||||
use crate::interpreter::Interpreter;
|
use crate::interpreter::Interpreter;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
struct Repl {
|
struct Repl {
|
||||||
interpreter: Interpreter,
|
interpreter: Interpreter,
|
||||||
|
@ -71,8 +71,7 @@ impl Repl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"save" | "s" => {
|
"save" | "s" => {
|
||||||
let file_name = cmd.next()
|
let file_name = cmd.next().unwrap_or("brainfuck_repl_history.bfr");
|
||||||
.unwrap_or("brainfuck_repl_history.bfr");
|
|
||||||
|
|
||||||
println!("Saving history to file: {file_name}");
|
println!("Saving history to file: {file_name}");
|
||||||
match std::fs::write(file_name, self.history.join("\n")) {
|
match std::fs::write(file_name, self.history.join("\n")) {
|
||||||
|
@ -85,25 +84,27 @@ impl Repl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"load" | "l" => {
|
"load" | "l" => {
|
||||||
let file_name = cmd.next()
|
let file_name = cmd.next().unwrap_or("brainfuck_repl_history.bfr");
|
||||||
.unwrap_or("brainfuck_repl_history.bfr");
|
|
||||||
|
|
||||||
println!("Loading history from file: {file_name}");
|
println!("Loading history from file: {file_name}");
|
||||||
match std::fs::read_to_string(file_name) {
|
match std::fs::read_to_string(file_name) {
|
||||||
Ok(history) => {
|
Ok(history) => {
|
||||||
info!("Successfully loaded history from file: {file_name}");
|
info!("Successfully loaded history from file: {file_name}");
|
||||||
self.history = history.split("\n")
|
self.history = history.split("\n").map(|s| s.to_string()).collect();
|
||||||
.map(|s| s.to_string())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// Run all commands in history
|
// Run all commands in history
|
||||||
for cmd in self.history.iter() {
|
for cmd in self.history.iter() {
|
||||||
match self.interpreter.run(Some(cmd.clone())) {
|
match self.interpreter.run(Some(cmd.clone())) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
info!("Successfully ran brainfuck source code from REPL");
|
info!(
|
||||||
|
"Successfully ran brainfuck source code from REPL"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Failed to run brainfuck source code from REPL: {}", e);
|
error!(
|
||||||
|
"Failed to run brainfuck source code from REPL: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,10 +129,9 @@ impl Repl {
|
||||||
println!("!help: show this fu*king help message");
|
println!("!help: show this fu*king help message");
|
||||||
println!("!fuck: exit the REPL mode");
|
println!("!fuck: exit the REPL mode");
|
||||||
}
|
}
|
||||||
_ => println!("Unknown command: {}, type !help to show the help",
|
_ => println!("Unknown command: {}, type !help to show the help", input),
|
||||||
input)
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,12 +140,14 @@ impl Repl {
|
||||||
pub fn start(interpreter: Interpreter) {
|
pub fn start(interpreter: Interpreter) {
|
||||||
info!("Entering REPL mode");
|
info!("Entering REPL mode");
|
||||||
println!("Welcome to the brainfuck REPL mode! :)");
|
println!("Welcome to the brainfuck REPL mode! :)");
|
||||||
println!("Brainfuck interpreter v {}\nBy {}",
|
println!(
|
||||||
clap::crate_version!(), clap::crate_authors!());
|
"Brainfuck interpreter v {}\nBy {}",
|
||||||
|
clap::crate_version!(),
|
||||||
|
clap::crate_authors!()
|
||||||
|
);
|
||||||
println!("Enter your brainfuck code and press enter to run it.");
|
println!("Enter your brainfuck code and press enter to run it.");
|
||||||
println!("Enter !fuck to exit :D");
|
println!("Enter !fuck to exit :D");
|
||||||
println!("Enter !help fuck to get more help");
|
println!("Enter !help fuck to get more help");
|
||||||
|
|
||||||
Repl::new(interpreter)
|
Repl::new(interpreter).run();
|
||||||
.run();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,7 @@ pub(crate) fn read_brainfuck_code_if_any(source: &Option<String>) -> Option<Stri
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
None => {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue