atom parser
This commit is contained in:
parent
9e0ead7605
commit
b2b8546f20
2 changed files with 67 additions and 6 deletions
|
@ -2,10 +2,9 @@ use bng_macros::{ModifierParser, QuickModifierParser, SlopeModifierParser};
|
|||
use fasteval::Instruction;
|
||||
|
||||
mod lex;
|
||||
use lex::Token;
|
||||
|
||||
pub(super) enum Atom {
|
||||
Note(u8),
|
||||
Note(char),
|
||||
Rest,
|
||||
StartHere,
|
||||
Modifier(Modifier),
|
||||
|
@ -16,6 +15,30 @@ pub(super) enum Atom {
|
|||
Comment,
|
||||
}
|
||||
|
||||
pub(super) enum FlatAtom {
|
||||
Note(char),
|
||||
Rest,
|
||||
StartHere,
|
||||
Modifier(Modifier),
|
||||
QuickModifier(QuickModifier),
|
||||
LoopStarts(u8),
|
||||
LoopEnds,
|
||||
TupleStarts,
|
||||
TupleEnds,
|
||||
SlopeStarts(SlopeModifier, Instruction),
|
||||
SlopeEnds,
|
||||
Comment,
|
||||
}
|
||||
|
||||
impl Clone for FlatAtom {
|
||||
fn clone(&self) -> Self {
|
||||
match self {
|
||||
Self::Rest => Self::Rest,
|
||||
_ => unimplemented!("variant can't be cloned"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ModifierParser)]
|
||||
pub(super) enum Modifier {
|
||||
Volume(u8),
|
||||
|
@ -24,6 +47,12 @@ pub(super) enum Modifier {
|
|||
Tempo(u16),
|
||||
}
|
||||
|
||||
impl Default for Modifier {
|
||||
fn default() -> Self {
|
||||
Modifier::Volume(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(QuickModifierParser)]
|
||||
pub(super) enum QuickModifier {
|
||||
Volume(bool),
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use clap::builder::TypedValueParser;
|
||||
use fasteval::{Compiler, Instruction};
|
||||
use nom::{
|
||||
branch::alt,
|
||||
character::complete::{char, one_of, u8},
|
||||
combinator::value,
|
||||
bytes::complete::take_till1,
|
||||
character::complete::{anychar, char, one_of, u8},
|
||||
combinator::{map_res, value},
|
||||
multi::many0,
|
||||
sequence::{delimited, pair, preceded},
|
||||
sequence::{delimited, pair, preceded, separated_pair},
|
||||
Err, IResult, Parser,
|
||||
};
|
||||
|
||||
use crate::bng::score::{Atom, FlatAtom, Modifier, QuickModifier};
|
||||
use crate::bng::score::{Atom, FlatAtom, Modifier, QuickModifier, SlopeModifier};
|
||||
|
||||
pub(crate) trait Parse: Sized {
|
||||
fn parse(input: &str) -> IResult<&str, Self>;
|
||||
|
@ -21,5 +26,32 @@ fn atom_parser<'a>(notes: &'a str) -> impl Parser<&str, FlatAtom, nom::error::Er
|
|||
preceded(char(Atom::MODIFIER), Modifier::parse).map(FlatAtom::Modifier),
|
||||
QuickModifier::parse.map(FlatAtom::QuickModifier),
|
||||
preceded(char(Atom::LOOP.0), u8).map(FlatAtom::LoopStarts),
|
||||
value(FlatAtom::LoopEnds, char(Atom::LOOP.1)),
|
||||
value(FlatAtom::TupleStarts, char(Atom::TUPLE.0)),
|
||||
value(FlatAtom::TupleEnds, char(Atom::TUPLE.1)),
|
||||
preceded(
|
||||
char(Atom::SLOPE.0),
|
||||
separated_pair(
|
||||
SlopeModifier::parse,
|
||||
char(' '),
|
||||
map_res(take_till1(|c| c == ','), |s| {
|
||||
let parser = fasteval::Parser::new();
|
||||
let mut slab = fasteval::Slab::new();
|
||||
Result::<Instruction, nom::error::Error<&str>>::Ok(
|
||||
parser
|
||||
.parse(s, &mut slab.ps)
|
||||
.map_err(|_| nom::error::Error::new(s, nom::error::ErrorKind::Verify))?
|
||||
.from(&slab.ps)
|
||||
.compile(&slab.ps, &mut slab.cs),
|
||||
)
|
||||
}),
|
||||
),
|
||||
)
|
||||
.map(|(sm, i)| FlatAtom::SlopeStarts(sm, i)),
|
||||
value(FlatAtom::SlopeEnds, char(Atom::SLOPE.1)),
|
||||
value(
|
||||
FlatAtom::Comment,
|
||||
delimited(char(Atom::COMMENT.0), anychar, char(Atom::COMMENT.1)),
|
||||
),
|
||||
))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue