fix tests, weird nested comment bug

This commit is contained in:
Ponj 2024-11-09 23:41:46 -05:00
parent f0be539c69
commit 4bb38e0f3e
Signed by: p6nj
GPG key ID: 6FED68D87C479A59
4 changed files with 130 additions and 94 deletions

View file

@ -37,17 +37,17 @@ channels:
octave: ><
comment?: ;,
start here: ':'
slope: {MODIFIER EXPR, score}
slope: {MODIFIER EXPR score}
note modifier prefix: n
volume modifier prefix: v
octave modifier prefix: o
length modifier prefix: l
tempo modifier prefix: t
loop: ()
loop with count: (COUNT, score)
loop with count: (COUNT score)
tuple: []
modifier: !
volume modifier prefix: v
octave modifier prefix: o
length modifier prefix: l
tempo modifier prefix: t,
tempo modifier prefix: t

View file

@ -30,7 +30,7 @@ pub use de::*;
use super::Expression as Instruction;
#[derive(Deref, From, Default)]
#[derive(Deref, From, Default, Clone)]
#[cfg_attr(debug_assertions, derive(Serialize, Debug, PartialEq))]
pub struct Atoms(Vec<Atom>);
@ -50,7 +50,12 @@ pub enum Atom {
impl Clone for Atom {
fn clone(&self) -> Self {
match self {
Self::Note(n) => Self::Note(*n),
Self::Rest => Self::Rest,
Self::StartHere => Self::StartHere,
Self::Modifier(m) => Self::Modifier(m.clone()),
Self::QuickModifier(q) => Self::QuickModifier(q.clone()),
Self::Comment => Self::Comment,
_ => unimplemented!("variant can't be cloned right now"),
}
}

View file

@ -5,13 +5,14 @@ use std::{
};
use clap::builder::TypedValueParser;
use const_format::concatcp;
use fasteval::Compiler;
use lazy_static::lazy_static;
use nom::{
branch::alt,
bytes::complete::{take_till, take_till1},
bytes::complete::{is_not, tag, take_till, take_till1},
character::complete::{anychar, char, one_of, space1, u16, u8},
combinator::{all_consuming, map_opt, map_res, opt, value, verify},
combinator::{all_consuming, map_opt, map_res, not, opt, value, verify},
error::{context, ContextError, ErrorKind, FromExternalError, ParseError},
multi::{many0, many1},
sequence::{delimited, pair, preceded, separated_pair, terminated},
@ -24,8 +25,8 @@ use super::{
super::super::Expression as Instruction, Atom, Modifier, QuickModifier, SlopeModifier,
};
// #[cfg(test)]
// mod tests;
#[cfg(test)]
mod tests;
lazy_static! {
static ref NOTES: Mutex<Option<String>> = Mutex::new(None);
@ -37,11 +38,11 @@ pub fn set_notes(
Ok(NOTES.lock()?.replace(notes.to_string()))
}
fn maybe_yml_str_space<'a, E>() -> impl Parser<&'a str, Vec<char>, E>
fn maybe_yml_str_space<'a, E>(i: &'a str) -> IResult<&'a str, Vec<char>, E>
where
E: nom::error::ParseError<&'a str> + ContextError<&'a str>,
{
context("yml white space", many0(one_of(" \t\r\n")))
context("yml white space", many0(one_of(" \t\r\n"))).parse(i)
}
pub fn root<'a, E>(i: &'a str) -> IResult<&'a str, Atoms, E>
@ -52,8 +53,8 @@ where
+ FromExternalError<&'a str, E>,
{
terminated(
many1(preceded(maybe_yml_str_space(), atom)),
maybe_yml_str_space(),
many1(preceded(maybe_yml_str_space, atom)),
maybe_yml_str_space,
)
.map(Atoms)
.parse(i)
@ -166,9 +167,9 @@ where
use super::super::slope_modifier;
context(
"slope_starts",
separated_pair(
preceded(
char(Atom::SLOPE.0),
delimited(
char(Atom::SLOPE.0),
separated_pair(
separated_pair(
slope_modifier,
char(' '),
@ -177,9 +178,10 @@ where
.map_err(|_| E::from_error_kind(s, ErrorKind::Verify))
}),
),
char(','),
root,
),
char(','),
root,
char(Atom::SLOPE.1),
),
)
.map(|((sm, i), v)| Atom::Slope(sm, i, v))
@ -196,7 +198,10 @@ where
Atom::Comment,
delimited(
char(Atom::COMMENT.0),
take_till(|c| c == Atom::COMMENT.1),
many0(alt((
value((), comment),
value((), is_not(concatcp!(Atom::COMMENT.0, Atom::COMMENT.1))),
))),
char(Atom::COMMENT.1),
),
),

View file

@ -1,6 +1,6 @@
use const_format::concatcp;
use nom::{
error::{Error, ErrorKind},
error::{Error, ErrorKind, VerboseError},
Err,
};
@ -8,12 +8,21 @@ use flat_atom::{
FASTEVAL_INSTRUCTION as FLATATOM_FASTEVAL_INSTRUCTION, SAMPLE_STR as FLATATOM_SAMPLE_STRING,
};
fn set_notes() {
super::set_notes("abcdefg").unwrap();
}
type NomError<'a> = VerboseError<&'a str>;
mod flat_atom {
use std::num::NonZeroU8;
use fasteval::Compiler;
use lazy_static::lazy_static;
use nom::Parser;
use crate::bng::score::Atoms;
use super::super::{
super::super::super::Expression as Instruction, super::UP, atom, Atom, Modifier,
QuickModifier, SlopeModifier,
@ -26,16 +35,27 @@ mod flat_atom {
Atom::TUPLE.1,
"ed",
Atom::COMMENT.0,
"hello"
"hello",
Atom::COMMENT.1
);
pub(super) fn sample_str_expr() -> Atoms {
Atoms(vec![
Atom::Tuple(Atoms(vec![Atom::Note(0), Atom::Note(2), Atom::Note(2)])),
Atom::Note(4),
Atom::Note(3),
Atom::Comment,
])
}
pub(super) const FASTEVAL_INSTRUCTION: &str = "1-cos((PI*x)/2)";
#[test]
fn note() {
set_notes();
assert_eq!(
Ok((SAMPLE_STR, Atom::Note(2))),
atom::<Error<&str>>("abcdefg").parse(concatcp!('c', SAMPLE_STR))
atom::<NomError>.parse(concatcp!('c', SAMPLE_STR))
)
}
@ -43,7 +63,7 @@ mod flat_atom {
fn rest() {
assert_eq!(
Ok((SAMPLE_STR, Atom::Rest)),
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::REST, SAMPLE_STR))
atom::<NomError>.parse(concatcp!(Atom::REST, SAMPLE_STR))
)
}
@ -51,7 +71,7 @@ mod flat_atom {
fn start_here() {
assert_eq!(
Ok((SAMPLE_STR, Atom::StartHere)),
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::START_HERE, SAMPLE_STR))
atom::<NomError>.parse(concatcp!(Atom::START_HERE, SAMPLE_STR))
)
}
@ -62,12 +82,7 @@ mod flat_atom {
SAMPLE_STR,
Atom::Modifier(Modifier::Length(unsafe { NonZeroU8::new_unchecked(2) }))
)),
atom::<Error<&str>>("abcdefg").parse(concatcp!(
Atom::MODIFIER,
Modifier::LENGTH,
2u8,
SAMPLE_STR
))
atom::<NomError>.parse(concatcp!(Atom::MODIFIER, Modifier::LENGTH, 2u8, SAMPLE_STR))
)
}
@ -75,90 +90,92 @@ mod flat_atom {
fn quick_modifier() {
assert_eq!(
Ok((SAMPLE_STR, Atom::QuickModifier(QuickModifier::Length(UP)))),
atom::<Error<&str>>("abcdefg").parse(concatcp!(QuickModifier::LENGTH.0, SAMPLE_STR))
atom::<NomError>.parse(concatcp!(QuickModifier::LENGTH.0, SAMPLE_STR))
)
}
#[test]
fn loop_starts() {
fn r#loop() {
set_notes();
assert_eq!(
Ok((
SAMPLE_STR,
Atom::LoopStarts(unsafe { NonZeroU8::new_unchecked(3) })
Atom::Loop(unsafe { NonZeroU8::new_unchecked(3) }, sample_str_expr())
)),
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::LOOP.0, 3u8, SAMPLE_STR))
atom::<NomError>.parse(concatcp!(
Atom::LOOP.0,
3u8,
SAMPLE_STR,
Atom::LOOP.1,
SAMPLE_STR
))
);
assert_eq!(
Ok((
SAMPLE_STR,
Atom::LoopStarts(unsafe { NonZeroU8::new_unchecked(2) })
Atom::Loop(unsafe { NonZeroU8::new_unchecked(2) }, sample_str_expr())
)),
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::LOOP.0, SAMPLE_STR))
atom::<NomError>.parse(concatcp!(
Atom::LOOP.0,
SAMPLE_STR,
Atom::LOOP.1,
SAMPLE_STR
))
);
assert_eq!(
Err(nom::Err::Error(Error::new(
concatcp!(Atom::LOOP.0, 0u8, SAMPLE_STR),
ErrorKind::Char
))),
atom("abcdefg").parse(concatcp!(Atom::LOOP.0, 0u8, SAMPLE_STR))
atom.parse(concatcp!(Atom::LOOP.0, 0u8, SAMPLE_STR))
)
}
#[test]
fn loop_ends() {
fn tuple() {
set_notes();
assert_eq!(
Ok((SAMPLE_STR, Atom::LoopEnds)),
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::LOOP.1, SAMPLE_STR))
)
}
#[test]
fn tuple_starts() {
assert_eq!(
Ok((SAMPLE_STR, Atom::TupleStarts)),
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::TUPLE.0, SAMPLE_STR))
)
}
#[test]
fn tuple_ends() {
assert_eq!(
Ok((SAMPLE_STR, Atom::TupleEnds)),
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::TUPLE.1, SAMPLE_STR))
)
}
#[test]
fn slope_starts() {
assert_eq!(
Ok((
Ok((SAMPLE_STR, Atom::Tuple(sample_str_expr()))),
atom::<NomError>.parse(concatcp!(
Atom::TUPLE.0,
SAMPLE_STR,
Atom::SlopeStarts(SlopeModifier::Note, FASTEVAL_INSTRUCTION.parse().unwrap())
)),
atom::<Error<&str>>("abcdefg").parse(concatcp!(
Atom::SLOPE.0,
SlopeModifier::NOTE,
' ',
FASTEVAL_INSTRUCTION,
',',
Atom::TUPLE.1,
SAMPLE_STR
))
)
}
#[test]
fn slope_ends() {
fn slope() {
set_notes();
assert_eq!(
Ok((SAMPLE_STR, Atom::SlopeEnds)),
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::SLOPE.1, SAMPLE_STR))
Ok((
SAMPLE_STR,
Atom::Slope(
SlopeModifier::Note,
FASTEVAL_INSTRUCTION.parse().unwrap(),
sample_str_expr()
)
)),
atom::<NomError>.parse(concatcp!(
Atom::SLOPE.0,
SlopeModifier::NOTE,
' ',
FASTEVAL_INSTRUCTION,
',',
SAMPLE_STR,
Atom::SLOPE.1,
SAMPLE_STR
))
)
}
#[test]
fn comment() {
set_notes();
assert_eq!(
Ok((SAMPLE_STR, Atom::Comment)),
atom::<Error<&str>>("abcdefg").parse(concatcp!(
atom::<NomError>.parse(concatcp!(
Atom::COMMENT.0,
"hi I'm a little pony",
SAMPLE_STR,
@ -167,6 +184,15 @@ mod flat_atom {
))
)
}
#[test]
fn nested_comments() {
set_notes();
assert_eq!(
Ok(("", Atom::Comment)),
atom::<NomError>.parse(";d;;dd,ef,,")
)
}
}
mod modifier {
@ -175,14 +201,14 @@ mod modifier {
use const_format::concatcp;
use nom::error::{Error, ErrorKind, VerboseError};
use super::FLATATOM_SAMPLE_STRING as SAMPLE_STR;
use super::{NomError, FLATATOM_SAMPLE_STRING as SAMPLE_STR};
use crate::bng::score::{modifier, Modifier};
#[test]
fn volume() {
assert_eq!(
Ok((SAMPLE_STR, Modifier::Volume(2))),
modifier::<VerboseError<&str>>(concatcp!(Modifier::VOLUME, 2u8, SAMPLE_STR))
modifier::<NomError>(concatcp!(Modifier::VOLUME, 2u8, SAMPLE_STR))
);
assert_eq!(
Err(nom::Err::Error(Error::new(
@ -197,7 +223,7 @@ mod modifier {
fn octave() {
assert_eq!(
Ok((SAMPLE_STR, Modifier::Octave(2))),
modifier::<VerboseError<&str>>(concatcp!(Modifier::OCTAVE, 2u8, SAMPLE_STR))
modifier::<NomError>(concatcp!(Modifier::OCTAVE, 2u8, SAMPLE_STR))
);
assert_eq!(
Err(nom::Err::Error(Error::new(
@ -215,7 +241,7 @@ mod modifier {
SAMPLE_STR,
Modifier::Length(unsafe { NonZeroU8::new_unchecked(2) })
)),
modifier::<VerboseError<&str>>(concatcp!(Modifier::LENGTH, 2u8, SAMPLE_STR))
modifier::<NomError>(concatcp!(Modifier::LENGTH, 2u8, SAMPLE_STR))
);
assert_eq!(
Err(nom::Err::Error(Error::new(
@ -240,7 +266,7 @@ mod modifier {
SAMPLE_STR,
Modifier::Tempo(unsafe { NonZeroU16::new_unchecked(2) })
)),
modifier::<VerboseError<&str>>(concatcp!(Modifier::TEMPO, 2u8, SAMPLE_STR))
modifier::<NomError>(concatcp!(Modifier::TEMPO, 2u8, SAMPLE_STR))
);
assert_eq!(
Err(nom::Err::Error(Error::new(
@ -256,7 +282,7 @@ mod quick_modifier {
use const_format::concatcp;
use nom::error::VerboseError;
use super::FLATATOM_SAMPLE_STRING as SAMPLE_STR;
use super::{NomError, FLATATOM_SAMPLE_STRING as SAMPLE_STR};
use crate::bng::score::{
lex::{DOWN, OFF, ON, UP},
quick_modifier, QuickModifier,
@ -266,11 +292,11 @@ mod quick_modifier {
fn volume() {
assert_eq!(
Ok((SAMPLE_STR, QuickModifier::Volume(UP))),
quick_modifier::<VerboseError<&str>>(concatcp!(QuickModifier::VOLUME.0, SAMPLE_STR))
quick_modifier::<NomError>(concatcp!(QuickModifier::VOLUME.0, SAMPLE_STR))
);
assert_eq!(
Ok((SAMPLE_STR, QuickModifier::Volume(DOWN))),
quick_modifier::<VerboseError<&str>>(concatcp!(QuickModifier::VOLUME.1, SAMPLE_STR))
quick_modifier::<NomError>(concatcp!(QuickModifier::VOLUME.1, SAMPLE_STR))
);
}
@ -278,11 +304,11 @@ mod quick_modifier {
fn octave() {
assert_eq!(
Ok((SAMPLE_STR, QuickModifier::Octave(UP))),
quick_modifier::<VerboseError<&str>>(concatcp!(QuickModifier::OCTAVE.0, SAMPLE_STR))
quick_modifier::<NomError>(concatcp!(QuickModifier::OCTAVE.0, SAMPLE_STR))
);
assert_eq!(
Ok((SAMPLE_STR, QuickModifier::Octave(DOWN))),
quick_modifier::<VerboseError<&str>>(concatcp!(QuickModifier::OCTAVE.1, SAMPLE_STR))
quick_modifier::<NomError>(concatcp!(QuickModifier::OCTAVE.1, SAMPLE_STR))
);
}
@ -290,11 +316,11 @@ mod quick_modifier {
fn length() {
assert_eq!(
Ok((SAMPLE_STR, QuickModifier::Length(UP))),
quick_modifier::<VerboseError<&str>>(concatcp!(QuickModifier::LENGTH.0, SAMPLE_STR))
quick_modifier::<NomError>(concatcp!(QuickModifier::LENGTH.0, SAMPLE_STR))
);
assert_eq!(
Ok((SAMPLE_STR, QuickModifier::Length(DOWN))),
quick_modifier::<VerboseError<&str>>(concatcp!(QuickModifier::LENGTH.1, SAMPLE_STR))
quick_modifier::<NomError>(concatcp!(QuickModifier::LENGTH.1, SAMPLE_STR))
);
}
@ -302,11 +328,11 @@ mod quick_modifier {
fn pizz() {
assert_eq!(
Ok((SAMPLE_STR, QuickModifier::Pizz(ON))),
quick_modifier::<VerboseError<&str>>(concatcp!(QuickModifier::PIZZ.0, SAMPLE_STR))
quick_modifier::<NomError>(concatcp!(QuickModifier::PIZZ.0, SAMPLE_STR))
);
assert_eq!(
Ok((SAMPLE_STR, QuickModifier::Pizz(OFF))),
quick_modifier::<VerboseError<&str>>(concatcp!(QuickModifier::PIZZ.1, SAMPLE_STR))
quick_modifier::<NomError>(concatcp!(QuickModifier::PIZZ.1, SAMPLE_STR))
);
}
}
@ -316,7 +342,7 @@ mod slope_modifier {
use const_format::concatcp;
use nom::error::VerboseError;
use super::FLATATOM_FASTEVAL_INSTRUCTION as INSTRUCTION;
use super::{NomError, FLATATOM_FASTEVAL_INSTRUCTION as INSTRUCTION};
use crate::bng::score::{slope_modifier, Atom, SlopeModifier};
const SAMPLE_STR: &str = concatcp!(' ', INSTRUCTION, Atom::SLOPE.1);
@ -325,7 +351,7 @@ mod slope_modifier {
fn note() {
assert_eq!(
Ok((SAMPLE_STR, SlopeModifier::Note)),
slope_modifier::<VerboseError<&str>>(concatcp!(SlopeModifier::NOTE, SAMPLE_STR))
slope_modifier::<NomError>(concatcp!(SlopeModifier::NOTE, SAMPLE_STR))
)
}
@ -333,7 +359,7 @@ mod slope_modifier {
fn volume() {
assert_eq!(
Ok((SAMPLE_STR, SlopeModifier::Volume)),
slope_modifier::<VerboseError<&str>>(concatcp!(SlopeModifier::VOLUME, SAMPLE_STR))
slope_modifier::<NomError>(concatcp!(SlopeModifier::VOLUME, SAMPLE_STR))
)
}
@ -341,7 +367,7 @@ mod slope_modifier {
fn octave() {
assert_eq!(
Ok((SAMPLE_STR, SlopeModifier::Octave)),
slope_modifier::<VerboseError<&str>>(concatcp!(SlopeModifier::OCTAVE, SAMPLE_STR))
slope_modifier::<NomError>(concatcp!(SlopeModifier::OCTAVE, SAMPLE_STR))
)
}
@ -349,7 +375,7 @@ mod slope_modifier {
fn length() {
assert_eq!(
Ok((SAMPLE_STR, SlopeModifier::Length)),
slope_modifier::<VerboseError<&str>>(concatcp!(SlopeModifier::LENGTH, SAMPLE_STR))
slope_modifier::<NomError>(concatcp!(SlopeModifier::LENGTH, SAMPLE_STR))
)
}
@ -357,7 +383,7 @@ mod slope_modifier {
fn tempo() {
assert_eq!(
Ok((SAMPLE_STR, SlopeModifier::Tempo)),
slope_modifier::<VerboseError<&str>>(concatcp!(SlopeModifier::TEMPO, SAMPLE_STR))
slope_modifier::<NomError>(concatcp!(SlopeModifier::TEMPO, SAMPLE_STR))
)
}
}