no more FlatAtoms
This commit is contained in:
parent
9c910b8076
commit
1c91b113fb
7 changed files with 105 additions and 603 deletions
|
@ -23,17 +23,15 @@ use serde::{
|
||||||
};
|
};
|
||||||
use strum::EnumDiscriminants;
|
use strum::EnumDiscriminants;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use utils::{inflate, InflateError};
|
|
||||||
|
|
||||||
mod de;
|
mod de;
|
||||||
mod lex;
|
mod lex;
|
||||||
mod utils;
|
|
||||||
pub use de::*;
|
pub use de::*;
|
||||||
|
|
||||||
use super::Expression as Instruction;
|
use super::Expression as Instruction;
|
||||||
|
|
||||||
#[derive(Deref, From, Default)]
|
#[derive(Deref, From, Default)]
|
||||||
#[cfg_attr(debug_assertions, derive(Serialize, Debug))]
|
#[cfg_attr(debug_assertions, derive(Serialize, Debug, PartialEq))]
|
||||||
pub struct Atoms(Vec<Atom>);
|
pub struct Atoms(Vec<Atom>);
|
||||||
|
|
||||||
#[cfg_attr(debug_assertions, derive(Debug, PartialEq))]
|
#[cfg_attr(debug_assertions, derive(Debug, PartialEq))]
|
||||||
|
@ -43,12 +41,21 @@ pub enum Atom {
|
||||||
StartHere,
|
StartHere,
|
||||||
Modifier(Modifier),
|
Modifier(Modifier),
|
||||||
QuickModifier(QuickModifier),
|
QuickModifier(QuickModifier),
|
||||||
Loop(NonZeroU8, Vec<Atom>),
|
Loop(NonZeroU8, Atoms),
|
||||||
Tuple(Vec<Atom>),
|
Tuple(Atoms),
|
||||||
Slope(SlopeModifier, Instruction, Vec<Atom>),
|
Slope(SlopeModifier, Instruction, Atoms),
|
||||||
Comment,
|
Comment,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Clone for Atom {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
match self {
|
||||||
|
Self::Rest => Self::Rest,
|
||||||
|
_ => unimplemented!("variant can't be cloned right now"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
impl Serialize for Atom {
|
impl Serialize for Atom {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
@ -59,37 +66,6 @@ impl Serialize for Atom {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(debug_assertions, derive(Debug, PartialEq))]
|
|
||||||
pub(super) enum FlatAtom {
|
|
||||||
Note(u8),
|
|
||||||
Rest,
|
|
||||||
StartHere,
|
|
||||||
Modifier(Modifier),
|
|
||||||
QuickModifier(QuickModifier),
|
|
||||||
LoopStarts(NonZeroU8),
|
|
||||||
LoopEnds,
|
|
||||||
TupleStarts,
|
|
||||||
TupleEnds,
|
|
||||||
SlopeStarts(SlopeModifier, Instruction),
|
|
||||||
SlopeEnds,
|
|
||||||
Comment,
|
|
||||||
}
|
|
||||||
|
|
||||||
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"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, ModifierParser)]
|
#[derive(Clone, ModifierParser)]
|
||||||
#[cfg_attr(debug_assertions, derive(Debug, PartialEq))]
|
#[cfg_attr(debug_assertions, derive(Debug, PartialEq))]
|
||||||
pub enum Modifier {
|
pub enum Modifier {
|
||||||
|
|
|
@ -22,18 +22,7 @@ use thiserror::Error;
|
||||||
|
|
||||||
use crate::bng::score::lex::lexer::root;
|
use crate::bng::score::lex::lexer::root;
|
||||||
|
|
||||||
use super::{
|
use super::{Atom, Atoms};
|
||||||
utils::{inflate, InflateError},
|
|
||||||
Atoms, FlatAtom,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
enum AtomsSerializeError {
|
|
||||||
#[error("sheet parsing error:\n{0}")]
|
|
||||||
Parsing(String),
|
|
||||||
#[error("sheet semantics: {0}")]
|
|
||||||
Inflation(#[from] InflateError),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Atoms {
|
impl<'de> Deserialize<'de> for Atoms {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
@ -55,16 +44,10 @@ impl<'de> Deserialize<'de> for Atoms {
|
||||||
if sheet.is_empty() {
|
if sheet.is_empty() {
|
||||||
Ok(Default::default())
|
Ok(Default::default())
|
||||||
} else {
|
} else {
|
||||||
root(&sheet, ¬es)
|
all_consuming(root(¬es))(&sheet)
|
||||||
.map_err(|e| pretty_verbose_err.curry().call1(sheet.as_str()).call1(e))
|
.map_err(|e| pretty_verbose_err.curry().call1(sheet.as_str()).call1(e))
|
||||||
.map_err(AtomsSerializeError::Parsing)
|
|
||||||
.map_err(de::Error::custom)
|
.map_err(de::Error::custom)
|
||||||
.and_then(|(_, v)| {
|
.map(|(i, r)| r)
|
||||||
inflate(v)
|
|
||||||
.map_err(AtomsSerializeError::from)
|
|
||||||
.map_err(de::Error::custom)
|
|
||||||
})
|
|
||||||
.map(Atoms)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{Atom, FlatAtom, Modifier, QuickModifier, SlopeModifier};
|
use super::{Atom, Modifier, QuickModifier, SlopeModifier};
|
||||||
|
|
||||||
pub(super) mod lexer;
|
pub(super) mod lexer;
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,14 @@ use nom::{
|
||||||
Err, IResult, Parser,
|
Err, IResult, Parser,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::bng::score::Atoms;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
super::super::Expression as Instruction, Atom, FlatAtom, Modifier, QuickModifier, SlopeModifier,
|
super::super::Expression as Instruction, Atom, Modifier, QuickModifier, SlopeModifier,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(test)]
|
// #[cfg(test)]
|
||||||
mod tests;
|
// mod tests;
|
||||||
|
|
||||||
fn maybe_yml_str_space<'a, E>() -> impl Parser<&'a str, Vec<char>, E>
|
fn maybe_yml_str_space<'a, E>() -> impl Parser<&'a str, Vec<char>, E>
|
||||||
where
|
where
|
||||||
|
@ -30,76 +32,81 @@ where
|
||||||
context("yml white space", many0(one_of(" \t\r\n")))
|
context("yml white space", many0(one_of(" \t\r\n")))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root<'a, E>(i: &'a str, notes: &'a str) -> IResult<&'a str, Vec<FlatAtom>, E>
|
pub fn root<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atoms, E>
|
||||||
where
|
where
|
||||||
E: ParseError<&'a str>
|
E: ParseError<&'a str>
|
||||||
+ ContextError<&'a str>
|
+ ContextError<&'a str>
|
||||||
+ FromExternalError<&'a str, TryFromIntError>
|
+ FromExternalError<&'a str, TryFromIntError>
|
||||||
+ FromExternalError<&'a str, E>,
|
+ FromExternalError<&'a str, E>,
|
||||||
{
|
{
|
||||||
all_consuming(terminated(
|
terminated(
|
||||||
many1(preceded(maybe_yml_str_space(), atom(notes))),
|
many1(preceded(maybe_yml_str_space(), atom(notes))),
|
||||||
maybe_yml_str_space(),
|
maybe_yml_str_space(),
|
||||||
))(i)
|
)
|
||||||
|
.map(Atoms)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn note<'a, E>(notes: &'a str) -> impl Parser<&'a str, FlatAtom, E>
|
fn note<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E>
|
||||||
where
|
where
|
||||||
E: ParseError<&'a str> + ContextError<&'a str> + FromExternalError<&'a str, TryFromIntError>,
|
E: ParseError<&'a str> + ContextError<&'a str> + FromExternalError<&'a str, TryFromIntError>,
|
||||||
{
|
{
|
||||||
context(
|
context(
|
||||||
"note",
|
"note",
|
||||||
map_res(map_opt(one_of(notes), |c| notes.find(c)), u8::try_from).map(FlatAtom::Note),
|
map_res(map_opt(one_of(notes), |c| notes.find(c)), u8::try_from),
|
||||||
)
|
)
|
||||||
|
.map(Atom::Note)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rest<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
|
fn rest<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E>
|
||||||
where
|
where
|
||||||
E: ParseError<&'a str> + ContextError<&'a str>,
|
E: ParseError<&'a str> + ContextError<&'a str>,
|
||||||
{
|
{
|
||||||
context("rest", value(FlatAtom::Rest, char(Atom::REST)))(i)
|
value(Atom::Rest, context("rest", char(Atom::REST))).parse(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_here<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
|
fn start_here<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E>
|
||||||
where
|
where
|
||||||
E: ParseError<&'a str> + ContextError<&'a str>,
|
E: ParseError<&'a str> + ContextError<&'a str>,
|
||||||
{
|
{
|
||||||
context(
|
value(
|
||||||
"start_here",
|
Atom::StartHere,
|
||||||
value(FlatAtom::StartHere, char(Atom::START_HERE)),
|
context("start_here", char(Atom::START_HERE)),
|
||||||
)(i)
|
)
|
||||||
|
.parse(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modifier<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
|
fn modifier<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E>
|
||||||
where
|
where
|
||||||
E: ParseError<&'a str> + ContextError<&'a str>,
|
E: ParseError<&'a str> + ContextError<&'a str>,
|
||||||
{
|
{
|
||||||
use super::super::modifier;
|
use super::super::modifier;
|
||||||
context(
|
context("modifier", preceded(char(Atom::MODIFIER), modifier))
|
||||||
"modifier",
|
.map(Atom::Modifier)
|
||||||
preceded(char(Atom::MODIFIER), modifier).map(FlatAtom::Modifier),
|
.parse(i)
|
||||||
)(i)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn quick_modifier<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
|
fn quick_modifier<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E>
|
||||||
where
|
where
|
||||||
E: ParseError<&'a str> + ContextError<&'a str>,
|
E: ParseError<&'a str> + ContextError<&'a str>,
|
||||||
{
|
{
|
||||||
use super::super::quick_modifier;
|
use super::super::quick_modifier;
|
||||||
context(
|
context("quick_modifier", quick_modifier)
|
||||||
"quick_modifier",
|
.map(Atom::QuickModifier)
|
||||||
quick_modifier.map(FlatAtom::QuickModifier),
|
.parse(i)
|
||||||
)(i)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn loop_starts<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
|
fn r#loop<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E>
|
||||||
where
|
where
|
||||||
E: ParseError<&'a str> + ContextError<&'a str>,
|
E: ParseError<&'a str>
|
||||||
|
+ ContextError<&'a str>
|
||||||
|
+ FromExternalError<&'a str, TryFromIntError>
|
||||||
|
+ FromExternalError<&'a str, E>,
|
||||||
{
|
{
|
||||||
context(
|
context(
|
||||||
"loop_starts",
|
"loop",
|
||||||
preceded(
|
delimited(
|
||||||
char(Atom::LOOP.0),
|
char(Atom::LOOP.0),
|
||||||
|
pair(
|
||||||
map_opt(opt(u8), |n| {
|
map_opt(opt(u8), |n| {
|
||||||
if let Some(n) = n {
|
if let Some(n) = n {
|
||||||
NonZeroU8::new(n)
|
NonZeroU8::new(n)
|
||||||
|
@ -107,46 +114,39 @@ where
|
||||||
unsafe { Some(NonZeroU8::new_unchecked(2)) }
|
unsafe { Some(NonZeroU8::new_unchecked(2)) }
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
root(notes),
|
||||||
|
),
|
||||||
|
char(Atom::LOOP.1),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.map(FlatAtom::LoopStarts),
|
.map(|(n, v)| Atom::Loop(n, v))
|
||||||
)(i)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn loop_ends<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
|
fn tuple<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E>
|
||||||
where
|
where
|
||||||
E: ParseError<&'a str> + ContextError<&'a str>,
|
E: ParseError<&'a str>
|
||||||
{
|
+ ContextError<&'a str>
|
||||||
context("loop_ends", value(FlatAtom::LoopEnds, char(Atom::LOOP.1)))(i)
|
+ FromExternalError<&'a str, TryFromIntError>
|
||||||
}
|
+ FromExternalError<&'a str, E>,
|
||||||
|
|
||||||
fn tuple_starts<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
|
|
||||||
where
|
|
||||||
E: ParseError<&'a str> + ContextError<&'a str>,
|
|
||||||
{
|
{
|
||||||
context(
|
context(
|
||||||
"tuple_starts",
|
"tuple",
|
||||||
value(FlatAtom::TupleStarts, char(Atom::TUPLE.0)),
|
delimited(char(Atom::TUPLE.0), root(notes), char(Atom::TUPLE.1)),
|
||||||
)(i)
|
)
|
||||||
|
.map(Atom::Tuple)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tuple_ends<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
|
fn slope<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E>
|
||||||
where
|
where
|
||||||
E: ParseError<&'a str> + ContextError<&'a str>,
|
E: ParseError<&'a str>
|
||||||
{
|
+ ContextError<&'a str>
|
||||||
context(
|
+ FromExternalError<&'a str, TryFromIntError>
|
||||||
"tuple_ends",
|
+ FromExternalError<&'a str, E>,
|
||||||
value(FlatAtom::TupleEnds, char(Atom::TUPLE.1)),
|
|
||||||
)(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn slope_starts<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
|
|
||||||
where
|
|
||||||
E: ParseError<&'a str> + ContextError<&'a str> + FromExternalError<&'a str, E>,
|
|
||||||
{
|
{
|
||||||
use super::super::slope_modifier;
|
use super::super::slope_modifier;
|
||||||
context(
|
context(
|
||||||
"slope_starts",
|
"slope_starts",
|
||||||
terminated(
|
separated_pair(
|
||||||
preceded(
|
preceded(
|
||||||
char(Atom::SLOPE.0),
|
char(Atom::SLOPE.0),
|
||||||
separated_pair(
|
separated_pair(
|
||||||
|
@ -159,29 +159,20 @@ where
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
char(','),
|
char(','),
|
||||||
|
root(notes),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.map(|(sm, i)| FlatAtom::SlopeStarts(sm, i)),
|
.map(|((sm, i), v)| Atom::Slope(sm, i, v))
|
||||||
)(i)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn slope_ends<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
|
fn comment<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E>
|
||||||
where
|
|
||||||
E: ParseError<&'a str> + ContextError<&'a str>,
|
|
||||||
{
|
|
||||||
context(
|
|
||||||
"slope_ends",
|
|
||||||
value(FlatAtom::SlopeEnds, char(Atom::SLOPE.1)),
|
|
||||||
)(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn comment<'a, E>(i: &'a str) -> IResult<&'a str, FlatAtom, E>
|
|
||||||
where
|
where
|
||||||
E: ParseError<&'a str> + ContextError<&'a str>,
|
E: ParseError<&'a str> + ContextError<&'a str>,
|
||||||
{
|
{
|
||||||
context(
|
context(
|
||||||
"comment",
|
"comment",
|
||||||
value(
|
value(
|
||||||
FlatAtom::Comment,
|
Atom::Comment,
|
||||||
delimited(
|
delimited(
|
||||||
char(Atom::COMMENT.0),
|
char(Atom::COMMENT.0),
|
||||||
take_till(|c| c == Atom::COMMENT.1),
|
take_till(|c| c == Atom::COMMENT.1),
|
||||||
|
@ -191,7 +182,7 @@ where
|
||||||
)(i)
|
)(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn atom<'a, E>(notes: &'a str) -> impl Parser<&'a str, FlatAtom, E>
|
fn atom<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E>
|
||||||
where
|
where
|
||||||
E: ParseError<&'a str>
|
E: ParseError<&'a str>
|
||||||
+ ContextError<&'a str>
|
+ ContextError<&'a str>
|
||||||
|
@ -206,12 +197,9 @@ where
|
||||||
start_here,
|
start_here,
|
||||||
modifier,
|
modifier,
|
||||||
quick_modifier,
|
quick_modifier,
|
||||||
loop_starts,
|
r#loop(¬es),
|
||||||
loop_ends,
|
tuple(¬es),
|
||||||
tuple_starts,
|
slope(¬es),
|
||||||
tuple_ends,
|
|
||||||
slope_starts,
|
|
||||||
slope_ends,
|
|
||||||
comment,
|
comment,
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
|
|
|
@ -15,7 +15,7 @@ mod flat_atom {
|
||||||
use nom::Parser;
|
use nom::Parser;
|
||||||
|
|
||||||
use super::super::{
|
use super::super::{
|
||||||
super::super::super::Expression as Instruction, super::UP, atom, Atom, FlatAtom, Modifier,
|
super::super::super::Expression as Instruction, super::UP, atom, Atom, Modifier,
|
||||||
QuickModifier, SlopeModifier,
|
QuickModifier, SlopeModifier,
|
||||||
};
|
};
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -34,7 +34,7 @@ mod flat_atom {
|
||||||
#[test]
|
#[test]
|
||||||
fn note() {
|
fn note() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok((SAMPLE_STR, FlatAtom::Note(2))),
|
Ok((SAMPLE_STR, Atom::Note(2))),
|
||||||
atom::<Error<&str>>("abcdefg").parse(concatcp!('c', SAMPLE_STR))
|
atom::<Error<&str>>("abcdefg").parse(concatcp!('c', SAMPLE_STR))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ mod flat_atom {
|
||||||
#[test]
|
#[test]
|
||||||
fn rest() {
|
fn rest() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok((SAMPLE_STR, FlatAtom::Rest)),
|
Ok((SAMPLE_STR, Atom::Rest)),
|
||||||
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::REST, SAMPLE_STR))
|
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::REST, SAMPLE_STR))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ mod flat_atom {
|
||||||
#[test]
|
#[test]
|
||||||
fn start_here() {
|
fn start_here() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok((SAMPLE_STR, FlatAtom::StartHere)),
|
Ok((SAMPLE_STR, Atom::StartHere)),
|
||||||
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::START_HERE, SAMPLE_STR))
|
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::START_HERE, SAMPLE_STR))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ mod flat_atom {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok((
|
Ok((
|
||||||
SAMPLE_STR,
|
SAMPLE_STR,
|
||||||
FlatAtom::Modifier(Modifier::Length(unsafe { NonZeroU8::new_unchecked(2) }))
|
Atom::Modifier(Modifier::Length(unsafe { NonZeroU8::new_unchecked(2) }))
|
||||||
)),
|
)),
|
||||||
atom::<Error<&str>>("abcdefg").parse(concatcp!(
|
atom::<Error<&str>>("abcdefg").parse(concatcp!(
|
||||||
Atom::MODIFIER,
|
Atom::MODIFIER,
|
||||||
|
@ -74,10 +74,7 @@ mod flat_atom {
|
||||||
#[test]
|
#[test]
|
||||||
fn quick_modifier() {
|
fn quick_modifier() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok((
|
Ok((SAMPLE_STR, Atom::QuickModifier(QuickModifier::Length(UP)))),
|
||||||
SAMPLE_STR,
|
|
||||||
FlatAtom::QuickModifier(QuickModifier::Length(UP))
|
|
||||||
)),
|
|
||||||
atom::<Error<&str>>("abcdefg").parse(concatcp!(QuickModifier::LENGTH.0, SAMPLE_STR))
|
atom::<Error<&str>>("abcdefg").parse(concatcp!(QuickModifier::LENGTH.0, SAMPLE_STR))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -87,14 +84,14 @@ mod flat_atom {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok((
|
Ok((
|
||||||
SAMPLE_STR,
|
SAMPLE_STR,
|
||||||
FlatAtom::LoopStarts(unsafe { NonZeroU8::new_unchecked(3) })
|
Atom::LoopStarts(unsafe { NonZeroU8::new_unchecked(3) })
|
||||||
)),
|
)),
|
||||||
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::LOOP.0, 3u8, SAMPLE_STR))
|
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::LOOP.0, 3u8, SAMPLE_STR))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok((
|
Ok((
|
||||||
SAMPLE_STR,
|
SAMPLE_STR,
|
||||||
FlatAtom::LoopStarts(unsafe { NonZeroU8::new_unchecked(2) })
|
Atom::LoopStarts(unsafe { NonZeroU8::new_unchecked(2) })
|
||||||
)),
|
)),
|
||||||
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::LOOP.0, SAMPLE_STR))
|
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::LOOP.0, SAMPLE_STR))
|
||||||
);
|
);
|
||||||
|
@ -110,7 +107,7 @@ mod flat_atom {
|
||||||
#[test]
|
#[test]
|
||||||
fn loop_ends() {
|
fn loop_ends() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok((SAMPLE_STR, FlatAtom::LoopEnds)),
|
Ok((SAMPLE_STR, Atom::LoopEnds)),
|
||||||
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::LOOP.1, SAMPLE_STR))
|
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::LOOP.1, SAMPLE_STR))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -118,7 +115,7 @@ mod flat_atom {
|
||||||
#[test]
|
#[test]
|
||||||
fn tuple_starts() {
|
fn tuple_starts() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok((SAMPLE_STR, FlatAtom::TupleStarts)),
|
Ok((SAMPLE_STR, Atom::TupleStarts)),
|
||||||
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::TUPLE.0, SAMPLE_STR))
|
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::TUPLE.0, SAMPLE_STR))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -126,7 +123,7 @@ mod flat_atom {
|
||||||
#[test]
|
#[test]
|
||||||
fn tuple_ends() {
|
fn tuple_ends() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok((SAMPLE_STR, FlatAtom::TupleEnds)),
|
Ok((SAMPLE_STR, Atom::TupleEnds)),
|
||||||
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::TUPLE.1, SAMPLE_STR))
|
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::TUPLE.1, SAMPLE_STR))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -136,7 +133,7 @@ mod flat_atom {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok((
|
Ok((
|
||||||
SAMPLE_STR,
|
SAMPLE_STR,
|
||||||
FlatAtom::SlopeStarts(SlopeModifier::Note, FASTEVAL_INSTRUCTION.parse().unwrap())
|
Atom::SlopeStarts(SlopeModifier::Note, FASTEVAL_INSTRUCTION.parse().unwrap())
|
||||||
)),
|
)),
|
||||||
atom::<Error<&str>>("abcdefg").parse(concatcp!(
|
atom::<Error<&str>>("abcdefg").parse(concatcp!(
|
||||||
Atom::SLOPE.0,
|
Atom::SLOPE.0,
|
||||||
|
@ -152,7 +149,7 @@ mod flat_atom {
|
||||||
#[test]
|
#[test]
|
||||||
fn slope_ends() {
|
fn slope_ends() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok((SAMPLE_STR, FlatAtom::SlopeEnds)),
|
Ok((SAMPLE_STR, Atom::SlopeEnds)),
|
||||||
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::SLOPE.1, SAMPLE_STR))
|
atom::<Error<&str>>("abcdefg").parse(concatcp!(Atom::SLOPE.1, SAMPLE_STR))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -160,7 +157,7 @@ mod flat_atom {
|
||||||
#[test]
|
#[test]
|
||||||
fn comment() {
|
fn comment() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok((SAMPLE_STR, FlatAtom::Comment)),
|
Ok((SAMPLE_STR, Atom::Comment)),
|
||||||
atom::<Error<&str>>("abcdefg").parse(concatcp!(
|
atom::<Error<&str>>("abcdefg").parse(concatcp!(
|
||||||
Atom::COMMENT.0,
|
Atom::COMMENT.0,
|
||||||
"hi I'm a little pony",
|
"hi I'm a little pony",
|
||||||
|
|
|
@ -1,236 +0,0 @@
|
||||||
use super::*;
|
|
||||||
use strum::Display;
|
|
||||||
use thiserror::Error;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
#[derive(Debug, EnumDiscriminants)]
|
|
||||||
#[strum_discriminants(derive(Display))]
|
|
||||||
pub enum Wrapper {
|
|
||||||
Loop(NonZeroU8),
|
|
||||||
Tuple,
|
|
||||||
Slope(SlopeModifier, Instruction),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
#[cfg_attr(test, derive(PartialEq))]
|
|
||||||
pub enum InflateError {
|
|
||||||
#[error("misplaced {0} end symbol")]
|
|
||||||
MismatchedEnd(WrapperDiscriminants),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn inflate(mut flat_atoms: Vec<FlatAtom>) -> Result<Vec<Atom>, InflateError> {
|
|
||||||
type Error = InflateError;
|
|
||||||
let mut result = Vec::with_capacity(flat_atoms.len());
|
|
||||||
let mut loop_stack: Vec<Vec<Atom>> = Vec::new();
|
|
||||||
let mut tuple_stack: Vec<Vec<Atom>> = Vec::new();
|
|
||||||
let mut slope_stack: Vec<Vec<Atom>> = Vec::new();
|
|
||||||
let mut stack_history: Vec<Wrapper> = Vec::new();
|
|
||||||
for mut atom in flat_atoms.into_iter() {
|
|
||||||
#[cfg(test)]
|
|
||||||
{
|
|
||||||
dbg!(&atom);
|
|
||||||
dbg!(&loop_stack);
|
|
||||||
dbg!(&tuple_stack);
|
|
||||||
dbg!(&slope_stack);
|
|
||||||
dbg!(&stack_history);
|
|
||||||
}
|
|
||||||
match stack_history.last().map(WrapperDiscriminants::from) {
|
|
||||||
Some(WrapperDiscriminants::Loop) => match atom {
|
|
||||||
FlatAtom::Note(n) => {
|
|
||||||
unsafe { loop_stack.last_mut().unwrap_unchecked() }.push(Atom::Note(n))
|
|
||||||
}
|
|
||||||
FlatAtom::Rest => {
|
|
||||||
unsafe { loop_stack.last_mut().unwrap_unchecked() }.push(Atom::Rest)
|
|
||||||
}
|
|
||||||
FlatAtom::StartHere => {
|
|
||||||
unsafe { loop_stack.last_mut().unwrap_unchecked() }.push(Atom::StartHere)
|
|
||||||
}
|
|
||||||
FlatAtom::Modifier(m) => {
|
|
||||||
unsafe { loop_stack.last_mut().unwrap_unchecked() }.push(Atom::Modifier(m))
|
|
||||||
}
|
|
||||||
FlatAtom::QuickModifier(q) => {
|
|
||||||
unsafe { loop_stack.last_mut().unwrap_unchecked() }.push(Atom::QuickModifier(q))
|
|
||||||
}
|
|
||||||
FlatAtom::LoopStarts(n) => {
|
|
||||||
loop_stack.push(Vec::new());
|
|
||||||
stack_history.push(Wrapper::Loop(n));
|
|
||||||
}
|
|
||||||
FlatAtom::LoopEnds => {
|
|
||||||
let popped = unsafe { loop_stack.pop().unwrap_unchecked() };
|
|
||||||
if stack_history.len() > 1 {
|
|
||||||
match WrapperDiscriminants::from(
|
|
||||||
stack_history.get(stack_history.len() - 2).unwrap(),
|
|
||||||
) {
|
|
||||||
WrapperDiscriminants::Loop => &mut loop_stack,
|
|
||||||
WrapperDiscriminants::Tuple => &mut tuple_stack,
|
|
||||||
WrapperDiscriminants::Slope => &mut slope_stack,
|
|
||||||
}
|
|
||||||
.last_mut()
|
|
||||||
.unwrap()
|
|
||||||
.push(Atom::Loop(
|
|
||||||
match stack_history.pop().unwrap() {
|
|
||||||
Wrapper::Loop(n) => n,
|
|
||||||
_ => unreachable!("this one is proven to be a loop"),
|
|
||||||
},
|
|
||||||
popped,
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
result.push(Atom::Loop(
|
|
||||||
match stack_history.pop().unwrap() {
|
|
||||||
Wrapper::Loop(n) => n,
|
|
||||||
_ => unreachable!("this one is proven to be a loop"),
|
|
||||||
},
|
|
||||||
popped,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FlatAtom::TupleStarts => {
|
|
||||||
tuple_stack.push(Vec::new());
|
|
||||||
stack_history.push(Wrapper::Tuple);
|
|
||||||
}
|
|
||||||
FlatAtom::TupleEnds => {
|
|
||||||
return Err(Error::MismatchedEnd(WrapperDiscriminants::Tuple));
|
|
||||||
}
|
|
||||||
FlatAtom::SlopeStarts(s, i) => {
|
|
||||||
slope_stack.push(Vec::new());
|
|
||||||
stack_history.push(Wrapper::Slope(s, i));
|
|
||||||
}
|
|
||||||
FlatAtom::SlopeEnds => {
|
|
||||||
return Err(Error::MismatchedEnd(WrapperDiscriminants::Slope));
|
|
||||||
}
|
|
||||||
FlatAtom::Comment => loop_stack.last_mut().unwrap().push(Atom::Comment),
|
|
||||||
},
|
|
||||||
Some(WrapperDiscriminants::Tuple) => match atom {
|
|
||||||
FlatAtom::Note(n) => tuple_stack.last_mut().unwrap().push(Atom::Note(n)),
|
|
||||||
FlatAtom::Rest => tuple_stack.last_mut().unwrap().push(Atom::Rest),
|
|
||||||
FlatAtom::StartHere => tuple_stack.last_mut().unwrap().push(Atom::StartHere),
|
|
||||||
FlatAtom::Modifier(m) => tuple_stack.last_mut().unwrap().push(Atom::Modifier(m)),
|
|
||||||
FlatAtom::QuickModifier(q) => {
|
|
||||||
tuple_stack.last_mut().unwrap().push(Atom::QuickModifier(q))
|
|
||||||
}
|
|
||||||
FlatAtom::LoopStarts(n) => {
|
|
||||||
loop_stack.push(Vec::new());
|
|
||||||
stack_history.push(Wrapper::Loop(n));
|
|
||||||
}
|
|
||||||
FlatAtom::LoopEnds => {
|
|
||||||
return Err(Error::MismatchedEnd(WrapperDiscriminants::Loop));
|
|
||||||
}
|
|
||||||
FlatAtom::TupleStarts => {
|
|
||||||
tuple_stack.push(Vec::new());
|
|
||||||
stack_history.push(Wrapper::Tuple);
|
|
||||||
}
|
|
||||||
FlatAtom::TupleEnds => {
|
|
||||||
let popped = tuple_stack.pop().unwrap();
|
|
||||||
if stack_history.len() > 1 {
|
|
||||||
match WrapperDiscriminants::from(
|
|
||||||
stack_history.get(stack_history.len() - 2).unwrap(),
|
|
||||||
) {
|
|
||||||
WrapperDiscriminants::Loop => &mut loop_stack,
|
|
||||||
WrapperDiscriminants::Tuple => &mut tuple_stack,
|
|
||||||
WrapperDiscriminants::Slope => &mut slope_stack,
|
|
||||||
}
|
|
||||||
.last_mut()
|
|
||||||
.unwrap()
|
|
||||||
.push({
|
|
||||||
stack_history.pop();
|
|
||||||
Atom::Tuple(popped)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
result.push(Atom::Tuple(popped))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FlatAtom::SlopeStarts(s, i) => {
|
|
||||||
slope_stack.push(Vec::new());
|
|
||||||
stack_history.push(Wrapper::Slope(s, i));
|
|
||||||
}
|
|
||||||
FlatAtom::SlopeEnds => {
|
|
||||||
return Err(Error::MismatchedEnd(WrapperDiscriminants::Slope));
|
|
||||||
}
|
|
||||||
FlatAtom::Comment => tuple_stack.last_mut().unwrap().push(Atom::Comment),
|
|
||||||
},
|
|
||||||
Some(WrapperDiscriminants::Slope) => match atom {
|
|
||||||
FlatAtom::Note(n) => slope_stack.last_mut().unwrap().push(Atom::Note(n)),
|
|
||||||
FlatAtom::Rest => slope_stack.last_mut().unwrap().push(Atom::Rest),
|
|
||||||
FlatAtom::StartHere => slope_stack.last_mut().unwrap().push(Atom::StartHere),
|
|
||||||
FlatAtom::Modifier(m) => slope_stack.last_mut().unwrap().push(Atom::Modifier(m)),
|
|
||||||
FlatAtom::QuickModifier(q) => {
|
|
||||||
slope_stack.last_mut().unwrap().push(Atom::QuickModifier(q))
|
|
||||||
}
|
|
||||||
FlatAtom::LoopStarts(n) => {
|
|
||||||
loop_stack.push(Vec::new());
|
|
||||||
stack_history.push(Wrapper::Loop(n));
|
|
||||||
}
|
|
||||||
FlatAtom::LoopEnds => {
|
|
||||||
return Err(Error::MismatchedEnd(WrapperDiscriminants::Loop));
|
|
||||||
}
|
|
||||||
FlatAtom::TupleStarts => {
|
|
||||||
tuple_stack.push(Vec::new());
|
|
||||||
stack_history.push(Wrapper::Tuple);
|
|
||||||
}
|
|
||||||
FlatAtom::TupleEnds => {
|
|
||||||
return Err(Error::MismatchedEnd(WrapperDiscriminants::Tuple));
|
|
||||||
}
|
|
||||||
FlatAtom::SlopeStarts(s, i) => {
|
|
||||||
slope_stack.push(Vec::new());
|
|
||||||
stack_history.push(Wrapper::Slope(s, i));
|
|
||||||
}
|
|
||||||
FlatAtom::SlopeEnds => {
|
|
||||||
let popped = slope_stack.pop().unwrap();
|
|
||||||
if stack_history.len() > 1 {
|
|
||||||
match WrapperDiscriminants::from(
|
|
||||||
stack_history.get(stack_history.len() - 2).unwrap(),
|
|
||||||
) {
|
|
||||||
WrapperDiscriminants::Loop => &mut loop_stack,
|
|
||||||
WrapperDiscriminants::Tuple => &mut tuple_stack,
|
|
||||||
WrapperDiscriminants::Slope => &mut slope_stack,
|
|
||||||
}
|
|
||||||
.last_mut()
|
|
||||||
.unwrap()
|
|
||||||
.push(match stack_history.pop().unwrap() {
|
|
||||||
Wrapper::Slope(m, i) => Atom::Slope(m, i, popped),
|
|
||||||
_ => unreachable!("this one is proven to be a slope"),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
result.push(match stack_history.pop().unwrap() {
|
|
||||||
Wrapper::Slope(m, i) => Atom::Slope(m, i, popped),
|
|
||||||
_ => unreachable!("this one is proven to be a slope"),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FlatAtom::Comment => slope_stack.last_mut().unwrap().push(Atom::Comment),
|
|
||||||
},
|
|
||||||
None => match atom {
|
|
||||||
FlatAtom::Note(n) => result.push(Atom::Note(n)),
|
|
||||||
FlatAtom::Rest => result.push(Atom::Rest),
|
|
||||||
FlatAtom::StartHere => result.push(Atom::StartHere),
|
|
||||||
FlatAtom::Modifier(m) => result.push(Atom::Modifier(m)),
|
|
||||||
FlatAtom::QuickModifier(q) => result.push(Atom::QuickModifier(q)),
|
|
||||||
FlatAtom::LoopStarts(n) => {
|
|
||||||
loop_stack.push(Vec::new());
|
|
||||||
stack_history.push(Wrapper::Loop(n));
|
|
||||||
}
|
|
||||||
FlatAtom::LoopEnds => {
|
|
||||||
return Err(Error::MismatchedEnd(WrapperDiscriminants::Loop));
|
|
||||||
}
|
|
||||||
FlatAtom::TupleStarts => {
|
|
||||||
tuple_stack.push(Vec::new());
|
|
||||||
stack_history.push(Wrapper::Tuple);
|
|
||||||
}
|
|
||||||
FlatAtom::TupleEnds => {
|
|
||||||
return Err(Error::MismatchedEnd(WrapperDiscriminants::Tuple));
|
|
||||||
}
|
|
||||||
FlatAtom::SlopeStarts(s, i) => {
|
|
||||||
slope_stack.push(Vec::new());
|
|
||||||
stack_history.push(Wrapper::Slope(s, i));
|
|
||||||
}
|
|
||||||
FlatAtom::SlopeEnds => {
|
|
||||||
return Err(Error::MismatchedEnd(WrapperDiscriminants::Slope));
|
|
||||||
}
|
|
||||||
FlatAtom::Comment => result.push(Atom::Comment),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
|
@ -1,206 +0,0 @@
|
||||||
#[cfg(test)]
|
|
||||||
mod inflate {
|
|
||||||
use fasteval::Compiler;
|
|
||||||
use lex::{ON, UP};
|
|
||||||
|
|
||||||
use super::{super::*, inflate};
|
|
||||||
|
|
||||||
const FASTEVAL_INSTRUCTION: &str = "1-cos((PI*x)/2)";
|
|
||||||
|
|
||||||
fn instruction() -> Instruction {
|
|
||||||
FASTEVAL_INSTRUCTION.parse().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn inflate_flat() {
|
|
||||||
assert_eq!(
|
|
||||||
Ok(vec![
|
|
||||||
Atom::Note(2),
|
|
||||||
Atom::Rest,
|
|
||||||
Atom::StartHere,
|
|
||||||
Atom::Modifier(Modifier::Volume(2)),
|
|
||||||
Atom::QuickModifier(QuickModifier::Volume(UP)),
|
|
||||||
Atom::Comment
|
|
||||||
]),
|
|
||||||
inflate(vec![
|
|
||||||
FlatAtom::Note(2),
|
|
||||||
FlatAtom::Rest,
|
|
||||||
FlatAtom::StartHere,
|
|
||||||
FlatAtom::Modifier(Modifier::Volume(2)),
|
|
||||||
FlatAtom::QuickModifier(QuickModifier::Volume(UP)),
|
|
||||||
FlatAtom::Comment
|
|
||||||
])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn inflate_loop_l1() {
|
|
||||||
assert_eq!(
|
|
||||||
Ok(vec![Atom::Loop(
|
|
||||||
unsafe { NonZeroU8::new_unchecked(3) },
|
|
||||||
vec![Atom::Note(2), Atom::Note(3)]
|
|
||||||
)]),
|
|
||||||
inflate(vec![
|
|
||||||
FlatAtom::LoopStarts(unsafe { NonZeroU8::new_unchecked(3) }),
|
|
||||||
FlatAtom::Note(2),
|
|
||||||
FlatAtom::Note(3),
|
|
||||||
FlatAtom::LoopEnds
|
|
||||||
])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn inflate_tuple_l1() {
|
|
||||||
assert_eq!(
|
|
||||||
Ok(vec![Atom::Tuple(vec![Atom::Note(2), Atom::Note(3)])]),
|
|
||||||
inflate(vec![
|
|
||||||
FlatAtom::TupleStarts,
|
|
||||||
FlatAtom::Note(2),
|
|
||||||
FlatAtom::Note(3),
|
|
||||||
FlatAtom::TupleEnds
|
|
||||||
])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn inflate_slope_l1() {
|
|
||||||
assert_eq!(
|
|
||||||
Ok(vec![Atom::Slope(
|
|
||||||
SlopeModifier::Note,
|
|
||||||
instruction(),
|
|
||||||
vec![Atom::Note(2), Atom::Note(3)]
|
|
||||||
)]),
|
|
||||||
inflate(vec![
|
|
||||||
FlatAtom::SlopeStarts(SlopeModifier::Note, instruction()),
|
|
||||||
FlatAtom::Note(2),
|
|
||||||
FlatAtom::Note(3),
|
|
||||||
FlatAtom::SlopeEnds
|
|
||||||
])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn inflate_loop_l2() {
|
|
||||||
assert_eq!(
|
|
||||||
Ok(vec![Atom::Loop(
|
|
||||||
unsafe { NonZeroU8::new_unchecked(2) },
|
|
||||||
vec![Atom::Loop(
|
|
||||||
unsafe { NonZeroU8::new_unchecked(3) },
|
|
||||||
vec![Atom::Note(2), Atom::Note(3)]
|
|
||||||
)]
|
|
||||||
)]),
|
|
||||||
inflate(vec![
|
|
||||||
FlatAtom::LoopStarts(unsafe { NonZeroU8::new_unchecked(2) }),
|
|
||||||
FlatAtom::LoopStarts(unsafe { NonZeroU8::new_unchecked(3) }),
|
|
||||||
FlatAtom::Note(2),
|
|
||||||
FlatAtom::Note(3),
|
|
||||||
FlatAtom::LoopEnds,
|
|
||||||
FlatAtom::LoopEnds
|
|
||||||
])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn inflate_tuple_l2() {
|
|
||||||
assert_eq!(
|
|
||||||
Ok(vec![Atom::Tuple(vec![Atom::Tuple(vec![
|
|
||||||
Atom::Note(2),
|
|
||||||
Atom::Note(3)
|
|
||||||
])])]),
|
|
||||||
inflate(vec![
|
|
||||||
FlatAtom::TupleStarts,
|
|
||||||
FlatAtom::TupleStarts,
|
|
||||||
FlatAtom::Note(2),
|
|
||||||
FlatAtom::Note(3),
|
|
||||||
FlatAtom::TupleEnds,
|
|
||||||
FlatAtom::TupleEnds
|
|
||||||
])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn inflate_slope_l2() {
|
|
||||||
assert_eq!(
|
|
||||||
Ok(vec![Atom::Slope(
|
|
||||||
SlopeModifier::Note,
|
|
||||||
instruction(),
|
|
||||||
vec![Atom::Slope(
|
|
||||||
SlopeModifier::Length,
|
|
||||||
instruction(),
|
|
||||||
vec![Atom::Note(2), Atom::Note(3)]
|
|
||||||
)]
|
|
||||||
)]),
|
|
||||||
inflate(vec![
|
|
||||||
FlatAtom::SlopeStarts(SlopeModifier::Note, instruction()),
|
|
||||||
FlatAtom::SlopeStarts(SlopeModifier::Length, instruction()),
|
|
||||||
FlatAtom::Note(2),
|
|
||||||
FlatAtom::Note(3),
|
|
||||||
FlatAtom::SlopeEnds,
|
|
||||||
FlatAtom::SlopeEnds
|
|
||||||
])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn mixed() {
|
|
||||||
assert_eq!(
|
|
||||||
Ok(vec![Atom::Slope(
|
|
||||||
SlopeModifier::Note,
|
|
||||||
instruction(),
|
|
||||||
vec![Atom::Slope(
|
|
||||||
SlopeModifier::Length,
|
|
||||||
instruction(),
|
|
||||||
vec![
|
|
||||||
Atom::Note(2),
|
|
||||||
Atom::Tuple(vec![Atom::Rest, Atom::Note(6)]),
|
|
||||||
Atom::Note(3),
|
|
||||||
Atom::Loop(
|
|
||||||
unsafe { NonZeroU8::new_unchecked(9) },
|
|
||||||
vec![Atom::QuickModifier(QuickModifier::Pizz(ON)), Atom::Note(0)]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)]
|
|
||||||
)]),
|
|
||||||
inflate(vec![
|
|
||||||
FlatAtom::SlopeStarts(SlopeModifier::Note, instruction()),
|
|
||||||
FlatAtom::SlopeStarts(SlopeModifier::Length, instruction()),
|
|
||||||
FlatAtom::Note(2),
|
|
||||||
FlatAtom::TupleStarts,
|
|
||||||
FlatAtom::Rest,
|
|
||||||
FlatAtom::Note(6),
|
|
||||||
FlatAtom::TupleEnds,
|
|
||||||
FlatAtom::Note(3),
|
|
||||||
FlatAtom::LoopStarts(unsafe { NonZeroU8::new_unchecked(9) }),
|
|
||||||
FlatAtom::QuickModifier(QuickModifier::Pizz(ON)),
|
|
||||||
FlatAtom::Note(0),
|
|
||||||
FlatAtom::LoopEnds,
|
|
||||||
FlatAtom::SlopeEnds,
|
|
||||||
FlatAtom::SlopeEnds
|
|
||||||
])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn mixed_mismatched_end() {
|
|
||||||
assert_eq!(
|
|
||||||
Err(InflateError::MismatchedEnd(WrapperDiscriminants::Slope)),
|
|
||||||
inflate(vec![
|
|
||||||
FlatAtom::SlopeStarts(SlopeModifier::Note, instruction()),
|
|
||||||
FlatAtom::SlopeStarts(SlopeModifier::Length, instruction()),
|
|
||||||
FlatAtom::Note(2),
|
|
||||||
FlatAtom::TupleStarts,
|
|
||||||
FlatAtom::Rest,
|
|
||||||
FlatAtom::SlopeEnds, // mismatched slope end while in a tuple
|
|
||||||
FlatAtom::Note(6),
|
|
||||||
FlatAtom::TupleEnds,
|
|
||||||
FlatAtom::Note(3),
|
|
||||||
FlatAtom::LoopStarts(unsafe { NonZeroU8::new_unchecked(9) }),
|
|
||||||
FlatAtom::QuickModifier(QuickModifier::Pizz(ON)),
|
|
||||||
FlatAtom::Note(0),
|
|
||||||
FlatAtom::LoopEnds,
|
|
||||||
FlatAtom::SlopeEnds,
|
|
||||||
FlatAtom::SlopeEnds,
|
|
||||||
])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue