tuplet and slope parser (lifetime issue)

This commit is contained in:
Breval Ferrari 2025-05-20 22:42:00 +02:00
parent cfdcc50973
commit 8387aa61bd
2 changed files with 62 additions and 15 deletions

View file

@ -11,30 +11,25 @@ pub trait Token {
} }
} }
#[cfg_attr(debug_assertions, derive(Default))]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Silence; pub struct Silence;
impl Token for Silence {} impl Token for Silence {}
#[cfg_attr(debug_assertions, derive(Default))]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Marker; pub struct Marker;
impl Token for Marker {} impl Token for Marker {}
#[cfg_attr(debug_assertions, derive(Default))]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Note(pub u8); pub struct Note(pub u8);
impl Token for Note {} impl Token for Note {}
#[cfg_attr(debug_assertions, derive(Default))]
pub struct VariableChange(pub char, pub Expression); pub struct VariableChange(pub char, pub Expression);
impl Token for VariableChange {} impl Token for VariableChange {}
#[cfg_attr(debug_assertions, derive(Default))]
pub struct Loop(pub LoopCount, pub TokenVec); pub struct Loop(pub LoopCount, pub TokenVec);
pub enum LoopCount { pub enum LoopCount {
@ -50,18 +45,16 @@ impl Default for LoopCount {
impl Token for Loop {} impl Token for Loop {}
#[cfg_attr(debug_assertions, derive(Default))]
pub struct Tuplet(pub TokenVec); pub struct Tuplet(pub TokenVec);
impl Token for Tuplet {} impl Token for Tuplet {}
#[cfg_attr(debug_assertions, derive(Default))] pub struct Slope<'a>(pub &'a VariableChange, pub TokenVec);
pub struct Slope(pub VariableChange, pub TokenVec);
impl Token for Slope {} impl Token for Slope<'_> {}
#[derive(new)] #[derive(new)]
#[cfg_attr(debug_assertions, derive(Debug, Default))] #[cfg_attr(debug_assertions, derive(Debug))]
pub struct Expression { pub struct Expression {
pub(crate) instruction: Instruction, pub(crate) instruction: Instruction,
pub(crate) slab: Slab, pub(crate) slab: Slab,

View file

@ -20,7 +20,9 @@ use nom::{
}; };
use nom_locate::LocatedSpan; 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)] #[derive(Builder)]
pub struct Parser<'i, 'n, 's, 'v> { pub struct Parser<'i, 'n, 's, 'v> {
@ -30,7 +32,7 @@ pub struct Parser<'i, 'n, 's, 'v> {
variables: &'v [char], variables: &'v [char],
} }
impl<'i, 'n, 's, 'v> Parser<'i, 'n, 's, 'v> { impl<'i> Parser<'i, '_, '_, '_> {
pub fn parse_all( pub fn parse_all(
&self, &self,
) -> Result<Vec<Box<dyn Token>>, Error<nom_locate::LocatedSpan<&'i str>>> { ) -> 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, parser: &Parser,
) -> impl NomParser< ) -> impl NomParser<
LocatedSpan<&'a str>, LocatedSpan<&'a str>,
@ -62,6 +64,8 @@ fn token_parser<'a, 'i, 'n, 's, 'v>(
Note::parser(parser.notes).map(into_box), Note::parser(parser.notes).map(into_box),
VariableChange::parser(parser.variables).map(into_box), VariableChange::parser(parser.variables).map(into_box),
Loop::parser(parser).map(into_box), Loop::parser(parser).map(into_box),
Tuplet::parser(parser).map(into_box),
Slope::parser(parser).map(into_box),
)), )),
space_or_comment(), space_or_comment(),
)) ))
@ -132,9 +136,9 @@ impl VariableChange {
} }
impl Loop { impl Loop {
fn parser<'a, 'i, 'n, 's, 'v>( fn parser<'i, 'n, 's, 'v>(
parser: &Parser<'i, 'n, 's, 'v>, parser: &Parser<'i, 'n, 's, 'v>,
) -> impl Fn(LocatedSpan<&str>) -> TokenResult<Loop> { ) -> impl Fn(LocatedSpan<&str>) -> TokenResult<Self> {
|input| { |input| {
delimited( delimited(
char('('), 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 /// Will return the longest valid fasteval expression
fn expression_parser<C: Into<char> + Ord + Display>( fn expression_parser<C: Into<char> + Ord + Display>(
variables: &[C], variables: &[C],