use parze::prelude::*;
#[derive(Debug)]
struct BrainfuckError {
found: Option<char>,
expected: Vec<char>, }
impl<'a> ParseError<'a, char> for BrainfuckError {
fn unexpected(c: char) -> Self {
Self { found: Some(c), expected: Vec::new() }
}
fn unexpected_end() -> Self {
Self { found: None, expected: Vec::new() }
}
fn combine(mut self, mut other: Self) -> Self {
self.expected.append(&mut other.expected);
self
}
}
#[derive(Clone, Debug, PartialEq)]
enum Instr {
Add,
Sub,
Left,
Right,
In,
Out,
Loop(Vec<Instr>),
}
fn expect<'a>(c: char) -> Parser<'a, char, (), BrainfuckError> {
sym(c).discard().map_err(move |mut err: BrainfuckError| {
err.expected.push(c);
err
})
}
fn main() {
parsers! {
bf: Parser<_, _, BrainfuckError> = {
( { expect('+') } -> { Instr::Add }
| { expect('-') } -> { Instr::Sub }
| { expect('<') } -> { Instr::Left }
| { expect('>') } -> { Instr::Right }
| { expect(',') } -> { Instr::In }
| { expect('.') } -> { Instr::Out }
| { expect('[') } -& bf &- { expect(']') } => { |i| Instr::Loop(i) }
)*
}
}
println!("{:?}", bf.parse("[+++".chars().collect::<Vec<_>>()));
}