diff --git a/src/bng/score.rs b/src/bng/score.rs index 57a47d1..127cf2d 100644 --- a/src/bng/score.rs +++ b/src/bng/score.rs @@ -1,16 +1,13 @@ use std::num::{NonZeroU16, NonZeroU8}; -use anyhow::Context; use bng_macros::{QuickModifierParser, SlopeModifierParser}; use fasteval::Instruction; -use strum::EnumDiscriminants; mod lex; -mod utils; -#[cfg_attr(debug_assertions, derive(Debug, PartialEq))] +#[cfg_attr(test, derive(Debug, PartialEq))] pub(super) enum Atom { - Note(u8), + Note(char), Rest, StartHere, Modifier(Modifier), @@ -21,7 +18,7 @@ pub(super) enum Atom { Comment, } -#[cfg_attr(debug_assertions, derive(Debug, PartialEq))] +#[cfg_attr(test, derive(Debug, PartialEq))] pub(super) enum FlatAtom { Note(u8), Rest, @@ -52,8 +49,7 @@ impl Clone for FlatAtom { } } -#[derive(Clone)] -#[cfg_attr(debug_assertions, derive(Debug, PartialEq))] +#[cfg_attr(test, derive(Debug, PartialEq))] pub(super) enum Modifier { Volume(u8), Octave(u8), @@ -67,8 +63,8 @@ impl Default for Modifier { } } -#[derive(QuickModifierParser, Clone)] -#[cfg_attr(debug_assertions, derive(Debug, PartialEq))] +#[derive(QuickModifierParser)] +#[cfg_attr(test, derive(Debug, PartialEq))] pub(super) enum QuickModifier { Volume(bool), Octave(bool), @@ -77,7 +73,7 @@ pub(super) enum QuickModifier { } #[derive(Clone, Copy, SlopeModifierParser)] -#[cfg_attr(debug_assertions, derive(Debug, PartialEq))] +#[cfg_attr(test, derive(Debug, PartialEq))] pub(super) enum SlopeModifier { Note, Volume, diff --git a/src/bng/score/lex/lexer.rs b/src/bng/score/lex/lexer.rs index 5846f75..41bfe95 100644 --- a/src/bng/score/lex/lexer.rs +++ b/src/bng/score/lex/lexer.rs @@ -9,7 +9,7 @@ use nom::{ branch::alt, bytes::complete::{take_till, take_till1}, character::complete::{anychar, char, one_of, u16, u8}, - combinator::{map_opt, map_res, opt, value, verify}, + combinator::{map_opt, map_res, opt, value}, multi::many0, sequence::{delimited, pair, preceded, separated_pair, terminated}, Err, IResult, Parser, diff --git a/src/bng/score/utils.rs b/src/bng/score/utils.rs deleted file mode 100644 index 4229a60..0000000 --- a/src/bng/score/utils.rs +++ /dev/null @@ -1,204 +0,0 @@ -use super::*; - -#[cfg(test)] -mod tests; - -// TODO: replace panics with custom error type -fn inflate(mut flat_atoms: Vec) -> Vec { - #[derive(EnumDiscriminants)] - #[cfg_attr(debug_assertions, derive(Debug))] - enum CurrentStack { - Loop(NonZeroU8), - Tuple, - Slope(SlopeModifier, Instruction), - } - let mut result = Vec::with_capacity(flat_atoms.len()); - let mut loop_stack: Vec> = Vec::new(); - let mut tuple_stack: Vec> = Vec::new(); - let mut slope_stack: Vec> = Vec::new(); - let mut stack_history: Vec = 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); - // } - if let Some(stack) = stack_history.last() { - match CurrentStackDiscriminants::from(stack) { - CurrentStackDiscriminants::Loop => match atom { - FlatAtom::Note(n) => loop_stack.last_mut().unwrap().push(Atom::Note(n)), - FlatAtom::Rest => loop_stack.last_mut().unwrap().push(Atom::Rest), - FlatAtom::StartHere => loop_stack.last_mut().unwrap().push(Atom::StartHere), - FlatAtom::Modifier(m) => loop_stack.last_mut().unwrap().push(Atom::Modifier(m)), - FlatAtom::QuickModifier(q) => { - loop_stack.last_mut().unwrap().push(Atom::QuickModifier(q)) - } - FlatAtom::LoopStarts(n) => { - loop_stack.push(Vec::new()); - stack_history.push(CurrentStack::Loop(n)); - } - FlatAtom::LoopEnds => { - let popped = loop_stack.pop().unwrap(); - if stack_history.len() > 1 { - match CurrentStackDiscriminants::from( - stack_history.get(stack_history.len() - 2).unwrap(), - ) { - CurrentStackDiscriminants::Loop => &mut loop_stack, - CurrentStackDiscriminants::Tuple => &mut tuple_stack, - CurrentStackDiscriminants::Slope => &mut slope_stack, - } - .last_mut() - .unwrap() - .push(Atom::Loop( - match stack_history.pop().unwrap() { - CurrentStack::Loop(n) => n, - _ => unreachable!("this one is proven to be a loop"), - }, - popped, - )) - } else { - result.push(Atom::Loop( - match stack_history.pop().unwrap() { - CurrentStack::Loop(n) => n, - _ => unreachable!("this one is proven to be a loop"), - }, - popped, - )) - } - } - FlatAtom::TupleStarts => { - tuple_stack.push(Vec::new()); - stack_history.push(CurrentStack::Tuple); - } - FlatAtom::TupleEnds => panic!("unmatched end tuple in a loop"), - FlatAtom::SlopeStarts(s, i) => { - slope_stack.push(Vec::new()); - stack_history.push(CurrentStack::Slope(s, i)); - } - FlatAtom::SlopeEnds => panic!("unmatched end slope in a loop"), - FlatAtom::Comment => loop_stack.last_mut().unwrap().push(Atom::Comment), - }, - CurrentStackDiscriminants::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) => { - tuple_stack.push(Vec::new()); - stack_history.push(CurrentStack::Loop(n)); - } - FlatAtom::LoopEnds => panic!("unmatched end loop in a tuple"), - FlatAtom::TupleStarts => { - tuple_stack.push(Vec::new()); - stack_history.push(CurrentStack::Tuple); - } - FlatAtom::TupleEnds => { - let popped = tuple_stack.pop().unwrap(); - if stack_history.len() > 1 { - match CurrentStackDiscriminants::from( - stack_history.get(stack_history.len() - 2).unwrap(), - ) { - CurrentStackDiscriminants::Loop => &mut loop_stack, - CurrentStackDiscriminants::Tuple => &mut tuple_stack, - CurrentStackDiscriminants::Slope => &mut slope_stack, - } - .last_mut() - .unwrap() - .push(Atom::Tuple(popped)) - } else { - result.push(Atom::Tuple(popped)) - } - } - FlatAtom::SlopeStarts(s, i) => { - slope_stack.push(Vec::new()); - stack_history.push(CurrentStack::Slope(s, i)); - } - FlatAtom::SlopeEnds => panic!("unmatched end slope in a tuple"), - FlatAtom::Comment => tuple_stack.last_mut().unwrap().push(Atom::Comment), - }, - CurrentStackDiscriminants::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) => { - slope_stack.push(Vec::new()); - stack_history.push(CurrentStack::Loop(n)); - } - FlatAtom::LoopEnds => panic!("unmatched end loop"), - FlatAtom::TupleStarts => { - tuple_stack.push(Vec::new()); - stack_history.push(CurrentStack::Tuple); - } - FlatAtom::TupleEnds => panic!("unmatched end tuple"), - FlatAtom::SlopeStarts(s, i) => { - slope_stack.push(Vec::new()); - stack_history.push(CurrentStack::Slope(s, i)); - } - FlatAtom::SlopeEnds => { - let popped = slope_stack.pop().unwrap(); - if stack_history.len() > 1 { - match CurrentStackDiscriminants::from( - stack_history.get(stack_history.len() - 2).unwrap(), - ) { - CurrentStackDiscriminants::Loop => &mut loop_stack, - CurrentStackDiscriminants::Tuple => &mut tuple_stack, - CurrentStackDiscriminants::Slope => &mut slope_stack, - } - .last_mut() - .unwrap() - .push(match stack_history.pop().unwrap() { - CurrentStack::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() { - CurrentStack::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), - }, - } - } else { - 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(CurrentStack::Loop(n)); - } - FlatAtom::LoopEnds => panic!("unmatched end loop"), - FlatAtom::TupleStarts => { - tuple_stack.push(Vec::new()); - stack_history.push(CurrentStack::Tuple); - } - FlatAtom::TupleEnds => panic!("unmatched end tuple"), - FlatAtom::SlopeStarts(s, i) => { - slope_stack.push(Vec::new()); - stack_history.push(CurrentStack::Slope(s, i)); - } - FlatAtom::SlopeEnds => panic!("unmatched end slope"), - FlatAtom::Comment => result.push(Atom::Comment), - } - } - } - result -} diff --git a/src/bng/score/utils/tests.rs b/src/bng/score/utils/tests.rs deleted file mode 100644 index 88739d1..0000000 --- a/src/bng/score/utils/tests.rs +++ /dev/null @@ -1,86 +0,0 @@ -#[cfg(test)] -mod inflate { - use fasteval::Compiler; - use lex::UP; - - use super::{super::*, inflate}; - - const FASTEVAL_INSTRUCTION: &str = "1-cos((PI*x)/2)"; - - #[test] - fn inflate_flat() { - assert_eq!( - 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!( - 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!( - 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() { - let instruction = || { - 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) - }; - assert_eq!( - 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 - ]) - ) - } -}