From 1f9d07c86207a1997725135e0a4e0b4d616c9963 Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Mon, 30 Sep 2024 20:21:52 +0200 Subject: [PATCH] comment parsing, marbles pass through spaces in comments. fix crash on division by zero --- programs/adder.mbl | 28 ++++++++++++++++++++++++++++ src/main.rs | 43 +++++++++++++++++++++++++++++++------------ 2 files changed, 59 insertions(+), 12 deletions(-) create mode 100644 programs/adder.mbl diff --git a/programs/adder.mbl b/programs/adder.mbl new file mode 100644 index 0000000..397aa9d --- /dev/null +++ b/programs/adder.mbl @@ -0,0 +1,28 @@ +(print sum of 123 and 45) + + o + > 123 B + vo A-+ + > 45 B| + o --+ + > * B + o + (check if 0) + o 1 +v < B=- 0 + v o * D- (div/10) +v B * < + +v> * 1 o ^ + F -R0 * 4 B +*| # < -A8 v + | # < +#| + -| v < + | *-|o + F +B * ^ + #< \F---- +(ascii digit s) +(printed in)*-| +(reverse) P- + B \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 4c6da8c..1f2f935 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,6 +22,7 @@ enum Tile { #[default] Blank, Block, + Comment(u8), Bag { count: u8, }, @@ -179,12 +180,17 @@ impl Machine { let tile = self.grid.get((x, y).into()); if let Tile::Marble { value, dir } = tile { marbles_on_row.push((value, dir)); - print!("{}", 'o'.green()); + print!("{}", 'o'.magenta()); + continue; + } + if let Tile::Comment(c) = tile { + print!("{}", (c as char).yellow()); continue; } let mut powered = false; let c = match tile { Tile::Marble { value: _, dir: _ } => unreachable!(), + Tile::Comment(_) => unreachable!(), Tile::Blank => ' ', Tile::Block => '#', Tile::Bag { count: _ } => 'B', @@ -223,12 +229,12 @@ impl Machine { if powered { print!("{}", c.red()); } else { - print!("{c}"); + print!("{}", c.cyan()); } } print!(" :: "); for (val, dir) in marbles_on_row { - print!("{}", format!("{}{:<3} ", dir.char(), val).green()) + print!("{}", format!("{}{:<3} ", dir.char(), val).magenta()) } println!(); } @@ -337,13 +343,7 @@ impl Machine { new_tile = Some(Tile::Blank); } } - Tile::Block => (), - _ => { - new_tile = Some(Tile::Marble { - value, - dir: dir.opposite(), - }); - } + _ => (), } if let Some(t) = new_tile { @@ -416,8 +416,8 @@ impl Machine { MathOp::Add => val_a.wrapping_add(val_b), MathOp::Sub => val_a.wrapping_sub(val_b), MathOp::Mul => val_a.wrapping_mul(val_b), - MathOp::Div => val_a / val_b, - MathOp::Rem => val_a % val_b, + MathOp::Div => val_a.checked_div(val_b).unwrap_or_default(), + MathOp::Rem => val_a.checked_rem(val_b).unwrap_or_default(), }; println!("{op:?} a:{val_a} b:{val_b}"); *self.grid.get_mut(front_pos) = Tile::Marble { value: result, dir }; @@ -468,6 +468,7 @@ impl Machine { | Tile::Digit(_) | Tile::Mirror(_) | Tile::Arrow(_) + | Tile::Comment(_) | Tile::Block | Tile::Blank => (), } @@ -575,7 +576,20 @@ fn parse(source: &str) -> (Vec>, Vec) { for (y, line) in source.lines().enumerate() { width = width.max(line.len()); let mut tiles = Vec::new(); + let mut in_comment = false; for (x, char) in line.chars().enumerate() { + if in_comment { + if char == ')' { + in_comment = false; + } + if char == ' ' { + // allow marbles to pass through gaps in comments + tiles.push(Tile::Blank); + } else { + tiles.push(Tile::Comment(char as u8)); + } + continue; + } tiles.push(match char { 'o' => { marbles.push((x, y).into()); @@ -609,6 +623,11 @@ fn parse(source: &str) -> (Vec>, Vec) { 'B' => Tile::Bag { count: 0 }, d @ '0'..='9' => Tile::Digit(d as u8), '#' => Tile::Block, + ' ' => Tile::Blank, + '(' => { + in_comment = true; + Tile::Comment(b'(') + } _ => Tile::Blank, }); }