flat atom tests & fixes

This commit is contained in:
Breval Ferrari 2024-10-13 12:38:27 -04:00
parent 0465fb2e4c
commit 892914256d
No known key found for this signature in database
GPG key ID: 6FED68D87C479A59
3 changed files with 232 additions and 43 deletions

View file

@ -20,7 +20,7 @@ pub(super) enum Atom {
#[cfg_attr(test, derive(Debug, PartialEq))] #[cfg_attr(test, derive(Debug, PartialEq))]
pub(super) enum FlatAtom { pub(super) enum FlatAtom {
Note(char), Note(u8),
Rest, Rest,
StartHere, StartHere,
Modifier(Modifier), Modifier(Modifier),
@ -38,6 +38,12 @@ impl Clone for FlatAtom {
fn clone(&self) -> Self { fn clone(&self) -> Self {
match self { match self {
Self::Rest => Self::Rest, Self::Rest => Self::Rest,
Self::Comment => Self::Comment,
Self::LoopEnds => Self::LoopEnds,
Self::SlopeEnds => Self::SlopeEnds,
Self::StartHere => Self::StartHere,
Self::TupleEnds => Self::TupleEnds,
Self::TupleStarts => Self::TupleStarts,
_ => unimplemented!("variant can't be cloned"), _ => unimplemented!("variant can't be cloned"),
} }
} }

View file

@ -7,11 +7,11 @@ use clap::builder::TypedValueParser;
use fasteval::{Compiler, Instruction}; use fasteval::{Compiler, Instruction};
use nom::{ use nom::{
branch::alt, branch::alt,
bytes::complete::take_till1, bytes::complete::{take_till, take_till1},
character::complete::{anychar, char, one_of, u16, u8}, character::complete::{anychar, char, one_of, u16, u8},
combinator::{map_opt, map_res, value}, combinator::{map_opt, map_res, opt, value},
multi::many0, multi::many0,
sequence::{delimited, pair, preceded, separated_pair}, sequence::{delimited, pair, preceded, separated_pair, terminated},
Err, IResult, Parser, Err, IResult, Parser,
}; };
@ -35,17 +35,28 @@ impl Parse for Modifier {
} }
} }
fn atom_parser(notes: &str) -> impl Parser<&str, FlatAtom, nom::error::Error<&str>> { fn flat_atom_parser(notes: &str) -> impl Parser<&str, FlatAtom, nom::error::Error<&str>> {
alt(( alt((
one_of(notes).map(FlatAtom::Note), map_res(map_opt(one_of(notes), |c| notes.find(c)), u8::try_from).map(FlatAtom::Note),
value(FlatAtom::Rest, char(Atom::REST)), value(FlatAtom::Rest, char(Atom::REST)),
value(FlatAtom::StartHere, char(Atom::START_HERE)), value(FlatAtom::StartHere, char(Atom::START_HERE)),
preceded(char(Atom::MODIFIER), Modifier::parse).map(FlatAtom::Modifier), preceded(char(Atom::MODIFIER), Modifier::parse).map(FlatAtom::Modifier),
QuickModifier::parse.map(FlatAtom::QuickModifier), QuickModifier::parse.map(FlatAtom::QuickModifier),
preceded(char(Atom::LOOP.0), map_opt(u8, NonZeroU8::new)).map(FlatAtom::LoopStarts), preceded(
char(Atom::LOOP.0),
map_opt(opt(u8), |n| {
if let Some(n) = n {
NonZeroU8::new(n)
} else {
unsafe { Some(NonZeroU8::new_unchecked(2)) }
}
}),
)
.map(FlatAtom::LoopStarts),
value(FlatAtom::LoopEnds, char(Atom::LOOP.1)), value(FlatAtom::LoopEnds, char(Atom::LOOP.1)),
value(FlatAtom::TupleStarts, char(Atom::TUPLE.0)), value(FlatAtom::TupleStarts, char(Atom::TUPLE.0)),
value(FlatAtom::TupleEnds, char(Atom::TUPLE.1)), value(FlatAtom::TupleEnds, char(Atom::TUPLE.1)),
terminated(
preceded( preceded(
char(Atom::SLOPE.0), char(Atom::SLOPE.0),
separated_pair( separated_pair(
@ -57,18 +68,26 @@ fn atom_parser(notes: &str) -> impl Parser<&str, FlatAtom, nom::error::Error<&st
Result::<Instruction, nom::error::Error<&str>>::Ok( Result::<Instruction, nom::error::Error<&str>>::Ok(
parser parser
.parse(s, &mut slab.ps) .parse(s, &mut slab.ps)
.map_err(|_| nom::error::Error::new(s, nom::error::ErrorKind::Verify))? .map_err(|_| {
nom::error::Error::new(s, nom::error::ErrorKind::Verify)
})?
.from(&slab.ps) .from(&slab.ps)
.compile(&slab.ps, &mut slab.cs), .compile(&slab.ps, &mut slab.cs),
) )
}), }),
), ),
),
char(','),
) )
.map(|(sm, i)| FlatAtom::SlopeStarts(sm, i)), .map(|(sm, i)| FlatAtom::SlopeStarts(sm, i)),
value(FlatAtom::SlopeEnds, char(Atom::SLOPE.1)), value(FlatAtom::SlopeEnds, char(Atom::SLOPE.1)),
value( value(
FlatAtom::Comment, FlatAtom::Comment,
delimited(char(Atom::COMMENT.0), anychar, char(Atom::COMMENT.1)), delimited(
char(Atom::COMMENT.0),
take_till(|c| c == Atom::COMMENT.1),
char(Atom::COMMENT.1),
),
), ),
)) ))
} }

View file

@ -1,13 +1,24 @@
mod modifier { use const_format::concatcp;
use std::num::{NonZeroU16, NonZeroU8}; use nom::{
use const_format::concatcp;
use nom::{
error::{Error, ErrorKind}, error::{Error, ErrorKind},
Err, Err,
}; };
use crate::bng::score::{lex::lexer::Parse, Atom, Modifier}; use flat_atom::{
FASTEVAL_INSTRUCTION as FLATATOM_FASTEVAL_INSTRUCTION, SAMPLE_STR as FLATATOM_SAMPLE_STRING,
};
mod flat_atom {
use std::num::NonZeroU8;
use fasteval::Compiler;
use nom::Parser;
use super::*;
use crate::bng::score::{
lex::{lexer::flat_atom_parser, UP},
Atom, FlatAtom, Modifier, QuickModifier, SlopeModifier,
};
pub(super) const SAMPLE_STR: &str = concatcp!( pub(super) const SAMPLE_STR: &str = concatcp!(
Atom::TUPLE.0, Atom::TUPLE.0,
@ -18,6 +29,164 @@ mod modifier {
"hello" "hello"
); );
pub(super) const FASTEVAL_INSTRUCTION: &str = "1-cos((PI*x)/2)";
#[test]
fn note() {
assert_eq!(
Ok((SAMPLE_STR, FlatAtom::Note(2))),
flat_atom_parser("abcdefg").parse(concatcp!('c', SAMPLE_STR))
)
}
#[test]
fn rest() {
assert_eq!(
Ok((SAMPLE_STR, FlatAtom::Rest)),
flat_atom_parser("abcdefg").parse(concatcp!(Atom::REST, SAMPLE_STR))
)
}
#[test]
fn start_here() {
assert_eq!(
Ok((SAMPLE_STR, FlatAtom::StartHere)),
flat_atom_parser("abcdefg").parse(concatcp!(Atom::START_HERE, SAMPLE_STR))
)
}
#[test]
fn modifier() {
assert_eq!(
Ok((
SAMPLE_STR,
FlatAtom::Modifier(Modifier::Length(unsafe { NonZeroU8::new_unchecked(2) }))
)),
flat_atom_parser("abcdefg").parse(concatcp!(
Atom::MODIFIER,
Modifier::LENGTH,
2u8,
SAMPLE_STR
))
)
}
#[test]
fn quick_modifier() {
assert_eq!(
Ok((
SAMPLE_STR,
FlatAtom::QuickModifier(QuickModifier::Length(UP))
)),
flat_atom_parser("abcdefg").parse(concatcp!(QuickModifier::LENGTH.0, SAMPLE_STR))
)
}
#[test]
fn loop_starts() {
assert_eq!(
Ok((
SAMPLE_STR,
FlatAtom::LoopStarts(unsafe { NonZeroU8::new_unchecked(3) })
)),
flat_atom_parser("abcdefg").parse(concatcp!(Atom::LOOP.0, 3u8, SAMPLE_STR))
);
assert_eq!(
Ok((
SAMPLE_STR,
FlatAtom::LoopStarts(unsafe { NonZeroU8::new_unchecked(2) })
)),
flat_atom_parser("abcdefg").parse(concatcp!(Atom::LOOP.0, SAMPLE_STR))
);
assert_eq!(
Err(nom::Err::Error(Error::new(
concatcp!(Atom::LOOP.0, 0u8, SAMPLE_STR),
ErrorKind::Char
))),
flat_atom_parser("abcdefg").parse(concatcp!(Atom::LOOP.0, 0u8, SAMPLE_STR))
)
}
#[test]
fn loop_ends() {
assert_eq!(
Ok((SAMPLE_STR, FlatAtom::LoopEnds)),
flat_atom_parser("abcdefg").parse(concatcp!(Atom::LOOP.1, SAMPLE_STR))
)
}
#[test]
fn tuple_starts() {
assert_eq!(
Ok((SAMPLE_STR, FlatAtom::TupleStarts)),
flat_atom_parser("abcdefg").parse(concatcp!(Atom::TUPLE.0, SAMPLE_STR))
)
}
#[test]
fn tuple_ends() {
assert_eq!(
Ok((SAMPLE_STR, FlatAtom::TupleEnds)),
flat_atom_parser("abcdefg").parse(concatcp!(Atom::TUPLE.1, SAMPLE_STR))
)
}
#[test]
fn slope_starts() {
assert_eq!(
Ok((
SAMPLE_STR,
FlatAtom::SlopeStarts(SlopeModifier::Note, {
let parser = fasteval::Parser::new();
let mut slab = fasteval::Slab::new();
parser
.parse(FASTEVAL_INSTRUCTION, &mut slab.ps)
.unwrap()
.from(&slab.ps)
.compile(&slab.ps, &mut slab.cs)
})
)),
flat_atom_parser("abcdefg").parse(concatcp!(
Atom::SLOPE.0,
SlopeModifier::NOTE,
' ',
FASTEVAL_INSTRUCTION,
',',
SAMPLE_STR
))
)
}
#[test]
fn slope_ends() {
assert_eq!(
Ok((SAMPLE_STR, FlatAtom::SlopeEnds)),
flat_atom_parser("abcdefg").parse(concatcp!(Atom::SLOPE.1, SAMPLE_STR))
)
}
#[test]
fn comment() {
assert_eq!(
Ok((SAMPLE_STR, FlatAtom::Comment)),
flat_atom_parser("abcdefg").parse(concatcp!(
Atom::COMMENT.0,
"hi I'm a little pony",
SAMPLE_STR,
Atom::COMMENT.1,
SAMPLE_STR
))
)
}
}
mod modifier {
use std::num::{NonZeroU16, NonZeroU8};
use super::FLATATOM_SAMPLE_STRING as SAMPLE_STR;
use super::*;
use crate::bng::score::{lex::lexer::Parse, Modifier};
#[test] #[test]
fn volume() { fn volume() {
assert_eq!( assert_eq!(
@ -92,16 +261,12 @@ mod modifier {
} }
} }
use modifier::SAMPLE_STR as MODIFIER_SAMPLE_STRING;
mod quick_modifier { mod quick_modifier {
use const_format::concatcp; use super::FLATATOM_SAMPLE_STRING as SAMPLE_STR;
use nom::{error::Error, Err}; use super::*;
use super::MODIFIER_SAMPLE_STRING as SAMPLE_STR;
use crate::bng::score::{ use crate::bng::score::{
lex::{lexer::Parse, DOWN, OFF, ON, UP}, lex::{lexer::Parse, DOWN, OFF, ON, UP},
Atom, QuickModifier, QuickModifier,
}; };
#[test] #[test]
@ -155,12 +320,11 @@ mod quick_modifier {
#[cfg(test)] #[cfg(test)]
mod slope_modifier { mod slope_modifier {
use const_format::concatcp; use super::FLATATOM_FASTEVAL_INSTRUCTION as INSTRUCTION;
use nom::{error::Error, Err}; use super::*;
use crate::bng::score::{lex::lexer::Parse, Atom, SlopeModifier}; use crate::bng::score::{lex::lexer::Parse, Atom, SlopeModifier};
const SAMPLE_STR: &str = concatcp!(" 1-cos((PI*x)/2),acced", Atom::SLOPE.1); const SAMPLE_STR: &str = concatcp!(' ', INSTRUCTION, Atom::SLOPE.1);
#[test] #[test]
fn note() { fn note() {