comment parsing, marbles pass through spaces in comments. fix crash on division by zero
This commit is contained in:
parent
64dd244459
commit
1f9d07c862
2 changed files with 59 additions and 12 deletions
28
programs/adder.mbl
Normal file
28
programs/adder.mbl
Normal 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
|
43
src/main.rs
43
src/main.rs
|
@ -22,6 +22,7 @@ enum Tile {
|
||||||
#[default]
|
#[default]
|
||||||
Blank,
|
Blank,
|
||||||
Block,
|
Block,
|
||||||
|
Comment(u8),
|
||||||
Bag {
|
Bag {
|
||||||
count: u8,
|
count: u8,
|
||||||
},
|
},
|
||||||
|
@ -179,12 +180,17 @@ impl Machine {
|
||||||
let tile = self.grid.get((x, y).into());
|
let tile = self.grid.get((x, y).into());
|
||||||
if let Tile::Marble { value, dir } = tile {
|
if let Tile::Marble { value, dir } = tile {
|
||||||
marbles_on_row.push((value, dir));
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
let mut powered = false;
|
let mut powered = false;
|
||||||
let c = match tile {
|
let c = match tile {
|
||||||
Tile::Marble { value: _, dir: _ } => unreachable!(),
|
Tile::Marble { value: _, dir: _ } => unreachable!(),
|
||||||
|
Tile::Comment(_) => unreachable!(),
|
||||||
Tile::Blank => ' ',
|
Tile::Blank => ' ',
|
||||||
Tile::Block => '#',
|
Tile::Block => '#',
|
||||||
Tile::Bag { count: _ } => 'B',
|
Tile::Bag { count: _ } => 'B',
|
||||||
|
@ -223,12 +229,12 @@ impl Machine {
|
||||||
if powered {
|
if powered {
|
||||||
print!("{}", c.red());
|
print!("{}", c.red());
|
||||||
} else {
|
} else {
|
||||||
print!("{c}");
|
print!("{}", c.cyan());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print!(" :: ");
|
print!(" :: ");
|
||||||
for (val, dir) in marbles_on_row {
|
for (val, dir) in marbles_on_row {
|
||||||
print!("{}", format!("{}{:<3} ", dir.char(), val).green())
|
print!("{}", format!("{}{:<3} ", dir.char(), val).magenta())
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
|
@ -337,13 +343,7 @@ impl Machine {
|
||||||
new_tile = Some(Tile::Blank);
|
new_tile = Some(Tile::Blank);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Tile::Block => (),
|
_ => (),
|
||||||
_ => {
|
|
||||||
new_tile = Some(Tile::Marble {
|
|
||||||
value,
|
|
||||||
dir: dir.opposite(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(t) = new_tile {
|
if let Some(t) = new_tile {
|
||||||
|
@ -416,8 +416,8 @@ impl Machine {
|
||||||
MathOp::Add => val_a.wrapping_add(val_b),
|
MathOp::Add => val_a.wrapping_add(val_b),
|
||||||
MathOp::Sub => val_a.wrapping_sub(val_b),
|
MathOp::Sub => val_a.wrapping_sub(val_b),
|
||||||
MathOp::Mul => val_a.wrapping_mul(val_b),
|
MathOp::Mul => val_a.wrapping_mul(val_b),
|
||||||
MathOp::Div => val_a / val_b,
|
MathOp::Div => val_a.checked_div(val_b).unwrap_or_default(),
|
||||||
MathOp::Rem => val_a % val_b,
|
MathOp::Rem => val_a.checked_rem(val_b).unwrap_or_default(),
|
||||||
};
|
};
|
||||||
println!("{op:?} a:{val_a} b:{val_b}");
|
println!("{op:?} a:{val_a} b:{val_b}");
|
||||||
*self.grid.get_mut(front_pos) = Tile::Marble { value: result, dir };
|
*self.grid.get_mut(front_pos) = Tile::Marble { value: result, dir };
|
||||||
|
@ -468,6 +468,7 @@ impl Machine {
|
||||||
| Tile::Digit(_)
|
| Tile::Digit(_)
|
||||||
| Tile::Mirror(_)
|
| Tile::Mirror(_)
|
||||||
| Tile::Arrow(_)
|
| Tile::Arrow(_)
|
||||||
|
| Tile::Comment(_)
|
||||||
| Tile::Block
|
| Tile::Block
|
||||||
| Tile::Blank => (),
|
| Tile::Blank => (),
|
||||||
}
|
}
|
||||||
|
@ -575,7 +576,20 @@ fn parse(source: &str) -> (Vec<Vec<Tile>>, Vec<Pos>) {
|
||||||
for (y, line) in source.lines().enumerate() {
|
for (y, line) in source.lines().enumerate() {
|
||||||
width = width.max(line.len());
|
width = width.max(line.len());
|
||||||
let mut tiles = Vec::new();
|
let mut tiles = Vec::new();
|
||||||
|
let mut in_comment = false;
|
||||||
for (x, char) in line.chars().enumerate() {
|
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 {
|
tiles.push(match char {
|
||||||
'o' => {
|
'o' => {
|
||||||
marbles.push((x, y).into());
|
marbles.push((x, y).into());
|
||||||
|
@ -609,6 +623,11 @@ fn parse(source: &str) -> (Vec<Vec<Tile>>, Vec<Pos>) {
|
||||||
'B' => Tile::Bag { count: 0 },
|
'B' => Tile::Bag { count: 0 },
|
||||||
d @ '0'..='9' => Tile::Digit(d as u8),
|
d @ '0'..='9' => Tile::Digit(d as u8),
|
||||||
'#' => Tile::Block,
|
'#' => Tile::Block,
|
||||||
|
' ' => Tile::Blank,
|
||||||
|
'(' => {
|
||||||
|
in_comment = true;
|
||||||
|
Tile::Comment(b'(')
|
||||||
|
}
|
||||||
_ => Tile::Blank,
|
_ => Tile::Blank,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue