mirror of
https://github.com/dredozubov/polyrhythmix.git
synced 2024-11-22 11:57:43 +00:00
WIP delimited groups parsing
This commit is contained in:
parent
2251a09bc2
commit
8c65e8a0b0
2 changed files with 60 additions and 12 deletions
|
@ -1,4 +1,4 @@
|
|||
use dsl;
|
||||
use poly::dsl;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
|
|
|
@ -2,13 +2,13 @@ use std::str;
|
|||
use std::vec::Vec;
|
||||
|
||||
pub use nom::character::complete::{char, digit1};
|
||||
use nom::sequence::{separated_pair, tuple};
|
||||
use nom::multi::many1;
|
||||
use nom::sequence::{separated_pair, tuple, delimited};
|
||||
use nom::{Err, IResult};
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::combinator::{map, map_res};
|
||||
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum BasicLength {
|
||||
Whole,
|
||||
|
@ -40,13 +40,45 @@ pub enum Note {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Group { notes: Vec<Note>, length: Length }
|
||||
pub struct Times(u16);
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum GroupOrNote {
|
||||
RepeatGroup(Group, Times),
|
||||
SingleNote(Note)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Group { notes: Vec<GroupOrNote>, length: Length }
|
||||
|
||||
static WHOLE : Length = Length::Simple(ModdedLength::Plain(BasicLength::Whole));
|
||||
static HALF : Length = Length::Simple(ModdedLength::Plain(BasicLength::Half));
|
||||
static FOURTH : Length = Length::Simple(ModdedLength::Plain(BasicLength::Fourth));
|
||||
static EIGHTH : Length = Length::Simple(ModdedLength::Plain(BasicLength::Eighth));
|
||||
static SIXTEENTH : Length = Length::Simple(ModdedLength::Plain(BasicLength::Sixteenth));
|
||||
static THIRTY_SECOND : Length = Length::Simple(ModdedLength::Plain(BasicLength::ThirtySecond));
|
||||
static SIXTY_FOURTH : Length = Length::Simple(ModdedLength::Plain(BasicLength::SixtyFourth));
|
||||
|
||||
static WHOLE_DOTTED_TRIPLET : Length = Length::Triplet(ModdedLength::Dotted(BasicLength::Whole));
|
||||
static HALF_DOTTED_TRIPLET : Length = Length::Triplet(ModdedLength::Dotted(BasicLength::Half));
|
||||
static FOURTH_DOTTED_TRIPLET : Length = Length::Triplet(ModdedLength::Dotted(BasicLength::Fourth));
|
||||
static EIGHTH_DOTTED_TRIPLET : Length = Length::Triplet(ModdedLength::Dotted(BasicLength::Eighth));
|
||||
static SIXTEENTH_DOTTED_TRIPLET : Length = Length::Triplet(ModdedLength::Dotted(BasicLength::Sixteenth));
|
||||
static THIRTY_SECOND_DOTTED_TRIPLET : Length = Length::Triplet(ModdedLength::Dotted(BasicLength::ThirtySecond));
|
||||
static SIXTY_FOURTH_DOTTED_TRIPLET : Length = Length::Triplet(ModdedLength::Dotted(BasicLength::SixtyFourth));
|
||||
|
||||
static WHOLE_TRIPLET : Length = Length::Triplet(ModdedLength::Plain(BasicLength::Whole));
|
||||
static HALF_TRIPLET : Length = Length::Triplet(ModdedLength::Plain(BasicLength::Half));
|
||||
static FOURTH_TRIPLET : Length = Length::Triplet(ModdedLength::Plain(BasicLength::Fourth));
|
||||
static EIGHTH_TRIPLET : Length = Length::Triplet(ModdedLength::Plain(BasicLength::Eighth));
|
||||
static SIXTEENTH_TRIPLET : Length = Length::Triplet(ModdedLength::Plain(BasicLength::Sixteenth));
|
||||
static THIRTY_SECOND_TRIPLET : Length = Length::Triplet(ModdedLength::Plain(BasicLength::ThirtySecond));
|
||||
static SIXTY_FOURTH_TRIPLET : Length = Length::Triplet(ModdedLength::Plain(BasicLength::SixtyFourth));
|
||||
|
||||
static HIT : GroupOrNote = GroupOrNote::SingleNote(Note::Hit);
|
||||
static REST : GroupOrNote = GroupOrNote::SingleNote(Note::Rest);
|
||||
|
||||
fn hit(input: &str) -> IResult<&str, Note> {
|
||||
// note that this is really creating a function, the parser for abc
|
||||
// vvvvv
|
||||
// which is then called here, returning an IResult<&str, &str>
|
||||
// vvvvv
|
||||
map(char('x'), |_| { Note::Hit })(input)
|
||||
}
|
||||
|
||||
|
@ -94,12 +126,28 @@ fn length(input: &str) -> IResult<&str, Length> {
|
|||
alt((triplet_length, tied_length, map(modded_length, |x| { Length::Simple(x) })))(input)
|
||||
}
|
||||
|
||||
fn group(input: &str) -> IResult<&str, Group> {
|
||||
let (rem, (l, n)) = tuple((length, many1(note)))(input)?;
|
||||
Ok((rem, Group{ notes: n.iter().map(|x| GroupOrNote::SingleNote(x.clone())).collect(), length: l}))
|
||||
}
|
||||
|
||||
fn delimited_group(input: &str) -> IResult<&str, Group> {
|
||||
delimited(char('('), group, char(')'))(input)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_basic_length() {
|
||||
assert_eq!(length("16"), Ok(("", Length::Simple(ModdedLength::Plain(BasicLength::Sixteenth)))));
|
||||
fn parse_length() {
|
||||
assert_eq!(length("16"), Ok(("", SIXTEENTH.clone())));
|
||||
assert_eq!(length("8+16"), Ok(("", Length::Tied(ModdedLength::Plain(BasicLength::Eighth), ModdedLength::Plain(BasicLength::Sixteenth)))));
|
||||
assert_eq!(length("8t"), Ok(("", Length::Triplet(ModdedLength::Plain(BasicLength::Eighth)))));
|
||||
assert_eq!(length("4.t"), Ok(("", Length::Triplet(ModdedLength::Dotted(BasicLength::Fourth)))));
|
||||
assert_eq!(length("8t"), Ok(("", EIGHTH_TRIPLET.clone())));
|
||||
assert_eq!(length("4.t"), Ok(("", FOURTH_DOTTED_TRIPLET.clone())));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_group() {
|
||||
assert_eq!(group("16x--x-"), Ok(("", Group{notes: vec![HIT.clone(), REST.clone(), REST.clone(), HIT.clone(), REST.clone()], length: SIXTEENTH.clone()})));
|
||||
assert_eq!(group("8txxx"), Ok(("", Group { notes: vec![HIT.clone(), HIT.clone(), HIT.clone()], length: EIGHTH_TRIPLET.clone()})));
|
||||
assert_eq!(group("16+32x-xx"), Ok(("", Group {notes: vec![HIT.clone(), REST.clone(), HIT.clone(), HIT.clone()], length: Length::Tied(ModdedLength::Plain(BasicLength::Sixteenth), ModdedLength::Plain(BasicLength::ThirtySecond))})))
|
||||
}
|
||||
|
||||
// “x” hit
|
||||
|
|
Loading…
Reference in a new issue