tuplet and slope parser (lifetime issue)
This commit is contained in:
parent
cfdcc50973
commit
8387aa61bd
2 changed files with 62 additions and 15 deletions
|
@ -11,30 +11,25 @@ pub trait Token {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(debug_assertions, derive(Default))]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Silence;
|
||||
|
||||
impl Token for Silence {}
|
||||
|
||||
#[cfg_attr(debug_assertions, derive(Default))]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Marker;
|
||||
|
||||
impl Token for Marker {}
|
||||
|
||||
#[cfg_attr(debug_assertions, derive(Default))]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Note(pub u8);
|
||||
|
||||
impl Token for Note {}
|
||||
|
||||
#[cfg_attr(debug_assertions, derive(Default))]
|
||||
pub struct VariableChange(pub char, pub Expression);
|
||||
|
||||
impl Token for VariableChange {}
|
||||
|
||||
#[cfg_attr(debug_assertions, derive(Default))]
|
||||
pub struct Loop(pub LoopCount, pub TokenVec);
|
||||
|
||||
pub enum LoopCount {
|
||||
|
@ -50,18 +45,16 @@ impl Default for LoopCount {
|
|||
|
||||
impl Token for Loop {}
|
||||
|
||||
#[cfg_attr(debug_assertions, derive(Default))]
|
||||
pub struct Tuplet(pub TokenVec);
|
||||
|
||||
impl Token for Tuplet {}
|
||||
|
||||
#[cfg_attr(debug_assertions, derive(Default))]
|
||||
pub struct Slope(pub VariableChange, pub TokenVec);
|
||||
pub struct Slope<'a>(pub &'a VariableChange, pub TokenVec);
|
||||
|
||||
impl Token for Slope {}
|
||||
impl Token for Slope<'_> {}
|
||||
|
||||
#[derive(new)]
|
||||
#[cfg_attr(debug_assertions, derive(Debug, Default))]
|
||||
#[cfg_attr(debug_assertions, derive(Debug))]
|
||||
pub struct Expression {
|
||||
pub(crate) instruction: Instruction,
|
||||
pub(crate) slab: Slab,
|
||||
|
|
|
@ -20,7 +20,9 @@ use nom::{
|
|||
};
|
||||
use nom_locate::LocatedSpan;
|
||||
|
||||
use crate::compiler::{Expression, Loop, LoopCount, Marker, Note, Silence, Token, VariableChange};
|
||||
use crate::compiler::{
|
||||
Expression, Loop, LoopCount, Marker, Note, Silence, Slope, Token, Tuplet, VariableChange,
|
||||
};
|
||||
|
||||
#[derive(Builder)]
|
||||
pub struct Parser<'i, 'n, 's, 'v> {
|
||||
|
@ -30,7 +32,7 @@ pub struct Parser<'i, 'n, 's, 'v> {
|
|||
variables: &'v [char],
|
||||
}
|
||||
|
||||
impl<'i, 'n, 's, 'v> Parser<'i, 'n, 's, 'v> {
|
||||
impl<'i> Parser<'i, '_, '_, '_> {
|
||||
pub fn parse_all(
|
||||
&self,
|
||||
) -> Result<Vec<Box<dyn Token>>, Error<nom_locate::LocatedSpan<&'i str>>> {
|
||||
|
@ -41,7 +43,7 @@ impl<'i, 'n, 's, 'v> Parser<'i, 'n, 's, 'v> {
|
|||
}
|
||||
}
|
||||
|
||||
fn token_parser<'a, 'i, 'n, 's, 'v>(
|
||||
fn token_parser<'a>(
|
||||
parser: &Parser,
|
||||
) -> impl NomParser<
|
||||
LocatedSpan<&'a str>,
|
||||
|
@ -62,6 +64,8 @@ fn token_parser<'a, 'i, 'n, 's, 'v>(
|
|||
Note::parser(parser.notes).map(into_box),
|
||||
VariableChange::parser(parser.variables).map(into_box),
|
||||
Loop::parser(parser).map(into_box),
|
||||
Tuplet::parser(parser).map(into_box),
|
||||
Slope::parser(parser).map(into_box),
|
||||
)),
|
||||
space_or_comment(),
|
||||
))
|
||||
|
@ -132,9 +136,9 @@ impl VariableChange {
|
|||
}
|
||||
|
||||
impl Loop {
|
||||
fn parser<'a, 'i, 'n, 's, 'v>(
|
||||
fn parser<'i, 'n, 's, 'v>(
|
||||
parser: &Parser<'i, 'n, 's, 'v>,
|
||||
) -> impl Fn(LocatedSpan<&str>) -> TokenResult<Loop> {
|
||||
) -> impl Fn(LocatedSpan<&str>) -> TokenResult<Self> {
|
||||
|input| {
|
||||
delimited(
|
||||
char('('),
|
||||
|
@ -151,6 +155,56 @@ impl Loop {
|
|||
}
|
||||
}
|
||||
|
||||
impl Tuplet {
|
||||
fn parser<'i, 'n, 's, 'v>(
|
||||
parser: &Parser<'i, 'n, 's, 'v>,
|
||||
) -> impl Fn(LocatedSpan<&str>) -> TokenResult<Self> {
|
||||
|input| {
|
||||
delimited(char('['), token_parser(parser), char(']'))
|
||||
.map(Self)
|
||||
.parse(input)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s> Slope<'s> {
|
||||
fn parser<'a, 'i, 'n, 'v>(
|
||||
parser: &Parser<'i, 'n, 's, 'v>,
|
||||
) -> impl Fn(LocatedSpan<&'a str>) -> TokenResult<'a, Self> {
|
||||
|input| {
|
||||
delimited(
|
||||
char('{'),
|
||||
alt(
|
||||
parser
|
||||
.slopes
|
||||
.iter()
|
||||
.map(|(k, v)| {
|
||||
Box::new(move |input: LocatedSpan<&'a str>| {
|
||||
value(v, tag(k.as_str())).parse(input)
|
||||
})
|
||||
as Box<
|
||||
dyn Fn(
|
||||
LocatedSpan<&'a str>,
|
||||
)
|
||||
-> TokenResult<'a, &'s VariableChange>,
|
||||
>
|
||||
})
|
||||
.collect::<Vec<
|
||||
Box<
|
||||
dyn Fn(LocatedSpan<&'a str>) -> TokenResult<'a, &'s VariableChange>,
|
||||
>,
|
||||
>>()
|
||||
.as_mut_slice(),
|
||||
)
|
||||
.and(token_parser(parser)),
|
||||
char('}'),
|
||||
)
|
||||
.map(|(i, v)| Self(i, v))
|
||||
.parse(input)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Will return the longest valid fasteval expression
|
||||
fn expression_parser<C: Into<char> + Ord + Display>(
|
||||
variables: &[C],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue