From e7a933b83760d7ffefbcf1267390443bdd99ca80 Mon Sep 17 00:00:00 2001 From: Denis Redozubov Date: Tue, 2 May 2023 16:06:08 +0400 Subject: [PATCH] Trying to make nom compile --- .gitignore | 1 + Cargo.lock | 32 ++++++++++++++ Cargo.toml | 13 ++++++ src/bin/main.rs | 5 +++ src/dsl/dsl.rs | 109 ++++++++++++++++++++++++++++++++++++++++++++++++ src/dsl/mod.rs | 1 + src/lib.rs | 1 + 7 files changed, 162 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/bin/main.rs create mode 100644 src/dsl/dsl.rs create mode 100644 src/dsl/mod.rs create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..da42fa6 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,32 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "poly" +version = "0.1.0" +dependencies = [ + "nom", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ea9babf --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "poly" +version = "0.1.0" +edition = "2021" + +[[bin]] +name = "main" +path = "src/bin/main.rs" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +nom = "*" diff --git a/src/bin/main.rs b/src/bin/main.rs new file mode 100644 index 0000000..91ed075 --- /dev/null +++ b/src/bin/main.rs @@ -0,0 +1,5 @@ +use dsl; + +fn main() { + println!("Hello, world!"); +} diff --git a/src/dsl/dsl.rs b/src/dsl/dsl.rs new file mode 100644 index 0000000..1bf43da --- /dev/null +++ b/src/dsl/dsl.rs @@ -0,0 +1,109 @@ +use std::str; +use std::vec::Vec; + +pub use nom::character::complete::{char, digit1}; +use nom::{Err, IResult}; +use nom::branch::alt; +use nom::bytes::complete::tag; + + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum BasicLength { + Whole, + Half, + Fourth, + Eighth, + Sixteenth, + ThirtySecond, + SixtyFourth +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ModdedLength { + Plain(BasicLength), + Dotted(BasicLength), + Triplet(BasicLength) +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Length { + Simple(ModdedLength), + Tied(ModdedLength, ModdedLength) +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Note { + Hit(Length), + Rest(Length) +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Group { notes: Vec } + +fn hit(len: Length, 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 + let (rem, c) = char('x')(input)?; + Ok((rem, Note::Hit(len))) +} + +fn rest( len: Length, input: &str) -> IResult<&str, Note> { + let (rem, c) = char('-')(input)?; + Ok((rem, Note::Rest(len))) +} + +fn note(input: &str, len: Length) -> IResult<&str, Note> { + alt((hit(len), rest(len)))(input) +} + +fn length_basic(input: &str) -> IResult<&str, Length> { + match map_res(digit1, str::parse)(input) { + Ok(r,1) => Ok(r, Whole), + Ok(r,2) => Ok(r, Half), + Ok(r,4) => Ok(r, Fourth), + Ok(r,8) => Ok(r, Eighth), + Ok(r,16) => Ok(r, Sixteenth), + Ok(r,32) => Ok(r, ThirtySecond), + Ok(r, 64) => Ok(r, SixtyFourth), + e => e + } +} + +fn tie_length(input: &str) -> IResult<&str, Length> { + let (rem, (l1,l2)) = separated_pair(length_basic, char('+'), length_basic)?; + Ok(rem, Tie(l1, l2)) +} + +fn length(input: &str) -> IResult<&str, Length> { + let (rem, len) = alt(tie_length, length_basic)(input)?; + let (rem2, is_triplet) = char('t')(rem)?; + if is_triplet { + Triplet(len) + } else { + leṇ + } +} + +#[test] +fn parse_basic_length() { + assert_eq!( + length("16"), + Ok(( + "", + Sixteenth + )) + ); + assert_eq!( + length("8+16"), + Ok("", Tie(Eighth, Sixteenth)) + ); + assert_eq!(length("8t"), Triplet(Eighth)) +} + +// “x” hit +// “-“ rest +// 16x-- => 16th hit and 16th rests + +// - 16x-xx-x-8txxx(3,16+32x-xx)4x-x- => x-xx-x- of 16th, then three hits of 8th triplets, repeat a group of tied 16+32th x-xx three times, then 4th x-x \ No newline at end of file diff --git a/src/dsl/mod.rs b/src/dsl/mod.rs new file mode 100644 index 0000000..6366b56 --- /dev/null +++ b/src/dsl/mod.rs @@ -0,0 +1 @@ +pub mod dsl; \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..6366b56 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1 @@ +pub mod dsl; \ No newline at end of file