comment parsing, marbles pass through spaces in comments. fix crash on division by zero

This commit is contained in:
Crispy 2024-09-30 20:21:52 +02:00
parent 64dd244459
commit 1f9d07c862
2 changed files with 59 additions and 12 deletions

28
programs/adder.mbl Normal file
View file

@ -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

View file

@ -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<Tile>>, Vec<Pos>) {
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<Tile>>, Vec<Pos>) {
'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,
});
}