diff --git a/.trunk/configs/.rustfmt.toml b/.trunk/configs/.rustfmt.toml deleted file mode 100644 index 994840e..0000000 --- a/.trunk/configs/.rustfmt.toml +++ /dev/null @@ -1,4 +0,0 @@ -# See: https://rust-lang.github.io/rustfmt -normalize_comments = true -use_field_init_shorthand = true -edition = "2021" diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 3a5fb09..0693b48 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -35,12 +35,12 @@ lint: enabled: - actionlint@1.7.4 - checkov@3.2.278 - - clippy@1.65.0 + - rustfmt@2024-01-04 + - clippy@2024-01-04 - git-diff-check - markdownlint@0.42.0 - osv-scanner@1.9.1 - prettier@3.3.3 - - rustfmt@1.65.0 - shellcheck@0.10.0 - shfmt@3.6.0 - taplo@0.9.3 diff --git a/Cargo.lock b/Cargo.lock index 6d9cf7f..da80823 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" @@ -223,7 +223,7 @@ checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -234,9 +234,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.1.31" +version = "1.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +checksum = "baee610e9452a8f6f0a1b6194ec09ff9e2d85dea54432acdae41aa0761c95d70" dependencies = [ "shlex", ] @@ -278,7 +278,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -366,7 +366,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -392,7 +392,7 @@ checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -706,7 +706,7 @@ checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -769,7 +769,7 @@ checksum = "bbc159a1934c7be9761c237333a57febe060ace2bc9e3b337a59a37af206d19f" dependencies = [ "starknet-curve", "starknet-ff", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -842,9 +842,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.85" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -853,22 +853,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -900,7 +900,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1000,7 +1000,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "wasm-bindgen-shared", ] @@ -1022,7 +1022,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1146,7 +1146,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1166,5 +1166,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] diff --git a/Cargo.toml b/Cargo.toml index 87d4b7c..a752d96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,33 @@ edition = "2021" authors = ["Simon Malatrait "] description = "Brainfuck ZK-VM with STWO" +[workspace.lints] +rust.unreachable_pub = "warn" +rust.unused_must_use = "deny" +rust.rust_2018_idioms = { level = "deny", priority = -1 } +rustdoc.all = "warn" + +[workspace.lints.clippy] +# all lints that are on by default (correctness, suspicious, style, complexity, perf) +all = { level = "warn", priority = -1 } + +# new lints that are still under development +nursery = { level = "warn", priority = -1 } +# avoid lints that are too pedantic +future_not_send = "allow" +fallible_impl_from = "allow" + +# lints which are rather strict or have occasional false positives +pedantic = { level = "warn", priority = -1 } +# avoid lints that are too pedantic +must_use_candidate = "allow" +cast_possible_truncation = "allow" +cast_precision_loss = "allow" +missing_errors_doc = "allow" +missing_panics_doc = "allow" +default_trait_access = "allow" +module_name_repetitions = "allow" + [workspace.dependencies] clap = { version = "4.3.10", features = ["derive"] } stwo-prover = { git = "https://github.com/starkware-libs/stwo", rev = "f6214d1" } diff --git a/crates/brainfuck_prover/Cargo.toml b/crates/brainfuck_prover/Cargo.toml index 1d813a5..2a2f634 100644 --- a/crates/brainfuck_prover/Cargo.toml +++ b/crates/brainfuck_prover/Cargo.toml @@ -5,4 +5,7 @@ edition.workspace = true authors.workspace = true description.workspace = true +[lints] +workspace = true + [dependencies] diff --git a/crates/brainfuck_vm/Cargo.toml b/crates/brainfuck_vm/Cargo.toml index 0d90c2f..fbe450f 100644 --- a/crates/brainfuck_vm/Cargo.toml +++ b/crates/brainfuck_vm/Cargo.toml @@ -5,6 +5,9 @@ edition.workspace = true authors.workspace = true description.workspace = true +[lints] +workspace = true + [dependencies] clap = { workspace = true, features = ["derive"] } num-traits = "0.2.19" diff --git a/crates/brainfuck_vm/src/bin/brainfuck_vm.rs b/crates/brainfuck_vm/src/bin/brainfuck_vm.rs index f23ef8f..03c670d 100644 --- a/crates/brainfuck_vm/src/bin/brainfuck_vm.rs +++ b/crates/brainfuck_vm/src/bin/brainfuck_vm.rs @@ -30,12 +30,9 @@ fn main() { tracing_subscriber::fmt().with_env_filter(args.log).init(); let code = fs::read_to_string(&args.filename).expect("Failed to read file"); - let mut bf_compiler = Compiler::new(code); + let mut bf_compiler = Compiler::new(&code); let ins = bf_compiler.compile(); - tracing::info!( - "Assembled instructions: {:?}", - ins.iter().map(|x| x.0).collect::>() - ); + tracing::info!("Assembled instructions: {:?}", ins.iter().map(|x| x.0).collect::>()); tracing::info!("Program execution"); let stdin = stdin(); let stdout = stdout(); diff --git a/crates/brainfuck_vm/src/compiler.rs b/crates/brainfuck_vm/src/compiler.rs index 0c9c697..90381d4 100644 --- a/crates/brainfuck_vm/src/compiler.rs +++ b/crates/brainfuck_vm/src/compiler.rs @@ -8,12 +8,9 @@ pub struct Compiler { } impl Compiler { - pub fn new(code: String) -> Self { + pub fn new(code: &str) -> Self { let trimmed_code = code.chars().filter(|c| !c.is_whitespace()).collect(); - Self { - code: trimmed_code, - instructions: vec![], - } + Self { code: trimmed_code, instructions: vec![] } } pub fn compile(&mut self) -> Vec { @@ -30,8 +27,7 @@ impl Compiler { let start_pos = loop_stack.pop().unwrap(); let loop_end_pos = self.instructions.len() + 1; self.instructions[start_pos] = BaseField::from((loop_end_pos - 1) as u32); - self.instructions - .push(BaseField::from((start_pos + 1) as u32)); + self.instructions.push(BaseField::from((start_pos + 1) as u32)); } _ => (), } @@ -47,7 +43,7 @@ mod tests { #[test] fn test_new() { - let code = "++>,<[>+.<-]".to_string(); + let code = "++>,<[>+.<-]"; let compiler = Compiler::new(code); let expected_trimmed_code = vec!['+', '+', '>', ',', '<', '[', '>', '+', '.', '<', '-', ']']; @@ -56,7 +52,7 @@ mod tests { #[test] fn test_whitespace() { - let code = " + +> , < [> + .< - ] ".to_string(); + let code = " + +> , < [> + .< - ] "; let compiler = Compiler::new(code); let expected_trimmed_code = vec!['+', '+', '>', ',', '<', '[', '>', '+', '.', '<', '-', ']']; @@ -65,9 +61,10 @@ mod tests { #[test] fn test_compile() { - let code = "++>,<[>+.<-]".to_string(); + let code = "++>,<[>+.<-]"; let mut compiler = Compiler::new(code); let instructions = compiler.compile(); + #[allow(clippy::cast_sign_loss)] let expected_ins: Vec = vec![43, 43, 62, 44, 60, 91, 13, 62, 43, 46, 60, 45, 93, 7] .into_iter() diff --git a/crates/brainfuck_vm/src/instruction.rs b/crates/brainfuck_vm/src/instruction.rs index 8e6e3b7..27a181e 100644 --- a/crates/brainfuck_vm/src/instruction.rs +++ b/crates/brainfuck_vm/src/instruction.rs @@ -8,7 +8,7 @@ pub struct Instruction { pub argument: u8, } -#[derive(PartialEq, Debug, Clone)] +#[derive(PartialEq, Eq, Debug, Clone)] pub enum InstructionType { // '>': Increment the data pointer (to point to the next cell to the right). Right, @@ -22,9 +22,13 @@ pub enum InstructionType { PutChar, // ',': Accept one byte of input, storing its value in the byte at the data pointer. ReadChar, - // '[': If the byte at the data pointer is zero, then instead of moving the instruction pointer forward to the next command, jump it forward to the command after the matching ']' command. + // '[': If the byte at the data pointer is zero, then instead of moving the instruction + // pointer forward to the next command, jump it forward to the command after the matching ']' + // command. JumpIfZero, - // ']': If the byte at the data pointer is nonzero, then instead of moving the instruction pointer forward to the next command, jump it back to the command after the matching '[' command. + // ']': If the byte at the data pointer is nonzero, then instead of moving the instruction + // pointer forward to the next command, jump it back to the command after the matching '[' + // command. JumpIfNotZero, } @@ -33,14 +37,14 @@ impl FromStr for InstructionType { fn from_str(s: &str) -> Result { match s { - ">" => Ok(InstructionType::Right), - "<" => Ok(InstructionType::Left), - "+" => Ok(InstructionType::Plus), - "-" => Ok(InstructionType::Minus), - "." => Ok(InstructionType::PutChar), - "," => Ok(InstructionType::ReadChar), - "[" => Ok(InstructionType::JumpIfZero), - "]" => Ok(InstructionType::JumpIfNotZero), + ">" => Ok(Self::Right), + "<" => Ok(Self::Left), + "+" => Ok(Self::Plus), + "-" => Ok(Self::Minus), + "." => Ok(Self::PutChar), + "," => Ok(Self::ReadChar), + "[" => Ok(Self::JumpIfZero), + "]" => Ok(Self::JumpIfNotZero), _ => Err(()), } } @@ -49,16 +53,16 @@ impl FromStr for InstructionType { impl Display for InstructionType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let symbol = match self { - InstructionType::Right => ">", - InstructionType::Left => "<", - InstructionType::Plus => "+", - InstructionType::Minus => "-", - InstructionType::PutChar => ".", - InstructionType::ReadChar => ",", - InstructionType::JumpIfZero => "[", - InstructionType::JumpIfNotZero => "]", + Self::Right => ">", + Self::Left => "<", + Self::Plus => "+", + Self::Minus => "-", + Self::PutChar => ".", + Self::ReadChar => ",", + Self::JumpIfZero => "[", + Self::JumpIfNotZero => "]", }; - write!(f, "{}", symbol) + write!(f, "{symbol}") } } @@ -76,38 +80,14 @@ mod tests { #[test] fn test_instruction_type_from_str() { // Test valid instruction mappings - assert_eq!( - InstructionType::from_str(">").unwrap(), - InstructionType::Right - ); - assert_eq!( - InstructionType::from_str("<").unwrap(), - InstructionType::Left - ); - assert_eq!( - InstructionType::from_str("+").unwrap(), - InstructionType::Plus - ); - assert_eq!( - InstructionType::from_str("-").unwrap(), - InstructionType::Minus - ); - assert_eq!( - InstructionType::from_str(".").unwrap(), - InstructionType::PutChar - ); - assert_eq!( - InstructionType::from_str(",").unwrap(), - InstructionType::ReadChar - ); - assert_eq!( - InstructionType::from_str("[").unwrap(), - InstructionType::JumpIfZero - ); - assert_eq!( - InstructionType::from_str("]").unwrap(), - InstructionType::JumpIfNotZero - ); + assert_eq!(InstructionType::from_str(">").unwrap(), InstructionType::Right); + assert_eq!(InstructionType::from_str("<").unwrap(), InstructionType::Left); + assert_eq!(InstructionType::from_str("+").unwrap(), InstructionType::Plus); + assert_eq!(InstructionType::from_str("-").unwrap(), InstructionType::Minus); + assert_eq!(InstructionType::from_str(".").unwrap(), InstructionType::PutChar); + assert_eq!(InstructionType::from_str(",").unwrap(), InstructionType::ReadChar); + assert_eq!(InstructionType::from_str("[").unwrap(), InstructionType::JumpIfZero); + assert_eq!(InstructionType::from_str("]").unwrap(), InstructionType::JumpIfNotZero); } // Test invalid input for FromStr @@ -141,10 +121,7 @@ mod tests { assert_eq!(InstructionType::from_u8(b'.'), InstructionType::PutChar); assert_eq!(InstructionType::from_u8(b','), InstructionType::ReadChar); assert_eq!(InstructionType::from_u8(b'['), InstructionType::JumpIfZero); - assert_eq!( - InstructionType::from_u8(b']'), - InstructionType::JumpIfNotZero - ); + assert_eq!(InstructionType::from_u8(b']'), InstructionType::JumpIfNotZero); } // Test from_u8 with invalid input (should panic) @@ -157,10 +134,7 @@ mod tests { // Test Instruction struct creation #[test] fn test_instruction_creation() { - let instruction = Instruction { - ins_type: InstructionType::Right, - argument: 42, - }; + let instruction = Instruction { ins_type: InstructionType::Right, argument: 42 }; assert_eq!(instruction.ins_type, InstructionType::Right); assert_eq!(instruction.argument, 42); diff --git a/crates/brainfuck_vm/src/machine.rs b/crates/brainfuck_vm/src/machine.rs index 0e78f35..e7620b2 100644 --- a/crates/brainfuck_vm/src/machine.rs +++ b/crates/brainfuck_vm/src/machine.rs @@ -35,31 +35,23 @@ pub struct Machine { impl Machine { pub const DEFAULT_RAM_SIZE: usize = 30000; - pub fn new_with_config( - code: Vec, - input: R, - output: W, - ram_size: usize, - ) -> Machine + pub fn new_with_config(code: Vec, input: R, output: W, ram_size: usize) -> Self where R: Read + 'static, W: Write + 'static, { - Machine { + Self { program: ProgramMemory { code }, state: MutableState { ram: vec![BaseField::zero(); ram_size], registers: Registers::new(), }, - io: IO { - input: Box::new(input), - output: Box::new(output), - }, + io: IO { input: Box::new(input), output: Box::new(output) }, trace: vec![], } } - pub fn new(code: Vec, input: R, output: W) -> Machine + pub fn new(code: Vec, input: R, output: W) -> Self where R: Read + 'static, W: Write + 'static, @@ -78,7 +70,7 @@ impl Machine { }; self.write_trace(); let ins_type = InstructionType::from_u8(self.state.registers.ci.0 as u8); - self.execute_instruction(ins_type)?; + self.execute_instruction(&ins_type)?; self.next_clock_cycle(); } @@ -103,7 +95,7 @@ impl Machine { Ok(()) } - fn execute_instruction(&mut self, ins: InstructionType) -> Result<(), Box> { + fn execute_instruction(&mut self, ins: &InstructionType) -> Result<(), Box> { match ins { InstructionType::Right => { self.state.registers.mp += BaseField::one(); @@ -227,11 +219,7 @@ mod tests { #[test] fn test_left_instruction() -> Result<(), Box> { // '>><' - let code = vec![ - BaseField::from(62), - BaseField::from(62), - BaseField::from(60), - ]; + let code = vec![BaseField::from(62), BaseField::from(62), BaseField::from(60)]; let (mut machine, _) = create_test_machine(code, &[]); machine.execute()?; @@ -250,8 +238,8 @@ mod tests { assert_eq!(machine.state.registers.mv, BaseField::from(1)); Ok(()) } - #[test] + #[test] fn test_minus_instruction() -> Result<(), Box> { // '--' let code = vec![BaseField::from(45), BaseField::from(45)]; @@ -408,10 +396,7 @@ mod tests { machine.pad_trace(); let trace = machine.get_trace(); - let dummy = Registers { - clk: final_state.clk + BaseField::one(), - ..final_state - }; + let dummy = Registers { clk: final_state.clk + BaseField::one(), ..final_state }; assert_eq!(trace.len(), 4); assert_eq!(trace[0], initial_state); diff --git a/crates/brainfuck_vm/src/registers.rs b/crates/brainfuck_vm/src/registers.rs index 2d3adff..346ade9 100644 --- a/crates/brainfuck_vm/src/registers.rs +++ b/crates/brainfuck_vm/src/registers.rs @@ -3,7 +3,7 @@ use num_traits::identities::Zero; use stwo_prover::core::fields::m31::BaseField; -#[derive(PartialEq, Clone)] +#[derive(PartialEq, Eq, Clone)] pub struct Registers { /// Clock Cycle Counter pub clk: BaseField, @@ -28,8 +28,8 @@ impl Default for Registers { } impl Registers { - pub fn new() -> Registers { - Registers { + pub fn new() -> Self { + Self { clk: BaseField::zero(), ip: BaseField::zero(), ci: BaseField::zero(), @@ -76,34 +76,13 @@ mod tests { let new_registers = Registers::new(); // Check that all fields are zero - assert!( - default_registers.clk.is_zero(), - "Clock cycle should be zero" - ); - assert!( - default_registers.ip.is_zero(), - "Instruction pointer should be zero" - ); - assert!( - default_registers.ci.is_zero(), - "Current instruction should be zero" - ); - assert!( - default_registers.ni.is_zero(), - "Next instruction should be zero" - ); - assert!( - default_registers.mp.is_zero(), - "Memory pointer should be zero" - ); - assert!( - default_registers.mv.is_zero(), - "Memory value should be zero" - ); - assert!( - default_registers.mvi.is_zero(), - "Memory value inverse should be zero" - ); + assert!(default_registers.clk.is_zero(), "Clock cycle should be zero"); + assert!(default_registers.ip.is_zero(), "Instruction pointer should be zero"); + assert!(default_registers.ci.is_zero(), "Current instruction should be zero"); + assert!(default_registers.ni.is_zero(), "Next instruction should be zero"); + assert!(default_registers.mp.is_zero(), "Memory pointer should be zero"); + assert!(default_registers.mv.is_zero(), "Memory value should be zero"); + assert!(default_registers.mvi.is_zero(), "Memory value inverse should be zero"); // Ensure default() and new() produce identical results assert_eq!(default_registers.clk, new_registers.clk); @@ -128,7 +107,7 @@ mod tests { mvi: BaseField::from(7), }; - let display_string = format!("{}", registers); + let display_string = format!("{registers}"); assert_eq!( display_string, "clk:1, ip:2, ci:3, ni:4, mp:5, mv:6, mvi:7", "Display format should match expected output" diff --git a/crates/brainfuck_vm/src/test_helper.rs b/crates/brainfuck_vm/src/test_helper.rs index ccdf2a5..8b72aeb 100644 --- a/crates/brainfuck_vm/src/test_helper.rs +++ b/crates/brainfuck_vm/src/test_helper.rs @@ -1,18 +1,19 @@ use crate::machine::Machine; -use std::cell::RefCell; -use std::io::{Cursor, Write}; -use std::rc::Rc; +use std::{ + cell::RefCell, + io::{Cursor, Write}, + rc::Rc, +}; use stwo_prover::core::fields::m31::BaseField; +#[derive(Debug)] pub struct TestWriter { buffer: Rc>>, } impl TestWriter { pub fn new() -> Self { - TestWriter { - buffer: Rc::new(RefCell::new(Vec::new())), - } + Self { buffer: Rc::new(RefCell::new(Vec::new())) } } pub fn get_output(&self) -> Vec { @@ -39,7 +40,7 @@ impl Write for TestWriter { impl Clone for TestWriter { fn clone(&self) -> Self { - TestWriter { + Self { buffer: Rc::clone(&self.buffer), // This creates a new reference to the same buffer } } diff --git a/crates/brainfuck_vm/tests/integration.rs b/crates/brainfuck_vm/tests/integration.rs index a8415b5..52ac1d1 100644 --- a/crates/brainfuck_vm/tests/integration.rs +++ b/crates/brainfuck_vm/tests/integration.rs @@ -3,10 +3,9 @@ use std::fs; use stwo_prover::core::fields::m31::BaseField; fn compile_from_path(path: &str) -> Vec { - let code = fs::read_to_string(path) - .unwrap_or_else(|_| panic!("Failed to read file")) - .replace(' ', ""); - let mut bf_compiler = Compiler::new(code); + let code = + fs::read_to_string(path).unwrap_or_else(|_| panic!("Failed to read file")).replace(' ', ""); + let mut bf_compiler = Compiler::new(&code); bf_compiler.compile() } diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..60a2338 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,12 @@ +reorder_imports = true +imports_granularity = "Crate" +use_small_heuristics = "Max" +comment_width = 100 +wrap_comments = true +binop_separator = "Back" +trailing_comma = "Vertical" +trailing_semicolon = false +use_field_init_shorthand = true +format_code_in_doc_comments = true +doc_comment_code_block_width = 100 +edition = "2021"