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))]
pub(super) enum FlatAtom {
Note(char),
Note(u8),
Rest,
StartHere,
Modifier(Modifier),
@ -38,6 +38,12 @@ impl Clone for FlatAtom {
fn clone(&self) -> Self {
match self {
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"),
}
}

View file

@ -7,11 +7,11 @@ use clap::builder::TypedValueParser;
use fasteval::{Compiler, Instruction};
use nom::{
branch::alt,
bytes::complete::take_till1,
bytes::complete::{take_till, take_till1},
character::complete::{anychar, char, one_of, u16, u8},
combinator::{map_opt, map_res, value},
combinator::{map_opt, map_res, opt, value},
multi::many0,
sequence::{delimited, pair, preceded, separated_pair},
sequence::{delimited, pair, preceded, separated_pair, terminated},
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((
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::StartHere, char(Atom::START_HERE)),
preceded(char(Atom::MODIFIER), Modifier::parse).map(FlatAtom::Modifier),
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::TupleStarts, char(Atom::TUPLE.0)),
value(FlatAtom::TupleEnds, char(Atom::TUPLE.1)),
terminated(
preceded(
char(Atom::SLOPE.0),
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(
parser
.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)
.compile(&slab.ps, &mut slab.cs),
)
}),
),
),
char(','),
)
.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)),
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 std::num::{NonZeroU16, NonZeroU8};
use const_format::concatcp;
use nom::{
error::{Error, ErrorKind},
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!(
Atom::TUPLE.0,
@ -18,6 +29,164 @@ mod modifier {
"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]
fn volume() {
assert_eq!(
@ -92,16 +261,12 @@ mod modifier {
}
}
use modifier::SAMPLE_STR as MODIFIER_SAMPLE_STRING;
mod quick_modifier {
use const_format::concatcp;
use nom::{error::Error, Err};
use super::MODIFIER_SAMPLE_STRING as SAMPLE_STR;
use super::FLATATOM_SAMPLE_STRING as SAMPLE_STR;
use super::*;
use crate::bng::score::{
lex::{lexer::Parse, DOWN, OFF, ON, UP},
Atom, QuickModifier,
QuickModifier,
};
#[test]
@ -155,12 +320,11 @@ mod quick_modifier {
#[cfg(test)]
mod slope_modifier {
use const_format::concatcp;
use nom::{error::Error, Err};
use super::FLATATOM_FASTEVAL_INSTRUCTION as INSTRUCTION;
use super::*;
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]
fn note() {