diff --git a/Cargo.toml b/Cargo.toml index 7aceef6..60ed4b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ const_format = "0.2.33" thiserror = "1.0.64" derive-new = "0.7.0" naan = "0.1.32" +lazy_static = "1.5.0" [features] default = ["play", "save"] diff --git a/check.txt b/check.txt new file mode 100644 index 0000000..e3c7726 --- /dev/null +++ b/check.txt @@ -0,0 +1,122 @@ + Checking bng v0.1.0 (/home/p6nj/bng) +error[E0720]: cannot resolve opaque type + --> src/bng/score/lex/lexer.rs:35:39 + | +35 | pub fn root<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atoms, E> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive opaque type +... +42 | / terminated( +43 | | many1(preceded(maybe_yml_str_space(), atom(notes))), +44 | | maybe_yml_str_space(), +45 | | ) +46 | | .map(Atoms) + | |_______________- returning here with type `nom::Map std::result::Result<(&str, std::vec::Vec), nom::Err>, fn(std::vec::Vec) -> Atoms {Atoms}, std::vec::Vec>` + | + ::: /home/p6nj/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nom-7.1.3/src/sequence/mod.rs:100:6 + | +100 | ) -> impl FnMut(I) -> IResult + | ---------------------------------- returning this type `nom::Map std::result::Result<(&str, std::vec::Vec), nom::Err>, fn(std::vec::Vec) -> Atoms {Atoms}, std::vec::Vec>` + +error[E0720]: cannot resolve opaque type + --> src/bng/score/lex/lexer.rs:98:37 + | +98 | fn r#loop<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive opaque type +... +105 | / context( +106 | | "loop", +107 | | delimited( +108 | | char(Atom::LOOP.0), +... | +121 | | ) +122 | | .map(|(n, v)| Atom::Loop(n, v)) + | |___________________________________- returning here with type `nom::Map std::result::Result<(&str, (NonZero, Atoms)), nom::Err>, {closure@src/bng/score/lex/lexer.rs:122:10: 122:18}, (NonZero, Atoms)>` + | + ::: /home/p6nj/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nom-7.1.3/src/error.rs:236:6 + | +236 | ) -> impl FnMut(I) -> IResult + | --------------------------------- returning this type `nom::Map std::result::Result<(&str, (NonZero, Atoms)), nom::Err>, {closure@src/bng/score/lex/lexer.rs:122:10: 122:18}, (NonZero, Atoms)>` + +error[E0720]: cannot resolve opaque type + --> src/bng/score/lex/lexer.rs:185:35 + | +185 | fn atom<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive opaque type +... +192 | / context( +193 | | "atom", +194 | | alt(( +195 | | note(notes), +... | +204 | | )), +205 | | ) + | |_____- returning here with type `impl FnMut(&str) -> std::result::Result<(&str, Atom), nom::Err>` + | + ::: /home/p6nj/.cargo/registry/src/index.crates.io-6f17d22bba15001f/nom-7.1.3/src/error.rs:236:6 + | +236 | ) -> impl FnMut(I) -> IResult + | --------------------------------- returning this opaque type `impl FnMut(&str) -> std::result::Result<(&str, Atom), nom::Err>` + +error[E0391]: cycle detected when computing type of opaque `bng::score::lex::lexer::root::{opaque#0}` + --> src/bng/score/lex/lexer.rs:35:39 + | +35 | pub fn root<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atoms, E> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `bng::score::lex::lexer::root`... + --> src/bng/score/lex/lexer.rs:46:6 + | +46 | .map(Atoms) + | ^^^ + = note: ...which requires evaluating trait selection obligation `nom::sequence::terminated::{opaque#0}: core::marker::Sync`... + = note: ...which again requires computing type of opaque `bng::score::lex::lexer::root::{opaque#0}`, completing the cycle +note: cycle used when computing type of `bng::score::lex::lexer::root::{opaque#0}` + --> src/bng/score/lex/lexer.rs:35:39 + | +35 | pub fn root<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atoms, E> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error[E0391]: cycle detected when computing type of opaque `bng::score::lex::lexer::tuple::{opaque#0}` + --> src/bng/score/lex/lexer.rs:125:36 + | +125 | fn tuple<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `bng::score::lex::lexer::tuple`... + --> src/bng/score/lex/lexer.rs:136:6 + | +136 | .map(Atom::Tuple) + | ^^^ + = note: ...which requires evaluating trait selection obligation `nom::error::context::{opaque#0}: core::marker::Sync`... + = note: ...which again requires computing type of opaque `bng::score::lex::lexer::tuple::{opaque#0}`, completing the cycle +note: cycle used when computing type of `bng::score::lex::lexer::tuple::{opaque#0}` + --> src/bng/score/lex/lexer.rs:125:36 + | +125 | fn tuple<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error[E0391]: cycle detected when computing type of opaque `bng::score::lex::lexer::slope::{opaque#0}` + --> src/bng/score/lex/lexer.rs:139:36 + | +139 | fn slope<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `bng::score::lex::lexer::slope`... + --> src/bng/score/lex/lexer.rs:165:6 + | +165 | .map(|((sm, i), v)| Atom::Slope(sm, i, v)) + | ^^^ + = note: ...which requires evaluating trait selection obligation `nom::error::context::{opaque#0}: core::marker::Sync`... + = note: ...which again requires computing type of opaque `bng::score::lex::lexer::slope::{opaque#0}`, completing the cycle +note: cycle used when computing type of `bng::score::lex::lexer::slope::{opaque#0}` + --> src/bng/score/lex/lexer.rs:139:36 + | +139 | fn slope<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +Some errors have detailed explanations: E0391, E0720. +For more information about an error, try `rustc --explain E0391`. +error: could not compile `bng` (bin "bng") due to 6 previous errors diff --git a/src/bng/score/de.rs b/src/bng/score/de.rs index 6659557..459e232 100644 --- a/src/bng/score/de.rs +++ b/src/bng/score/de.rs @@ -20,7 +20,7 @@ use serde::{ }; use thiserror::Error; -use crate::bng::score::lex::lexer::root; +use crate::bng::score::lex::lexer::{root, set_notes}; use super::{Atom, Atoms}; @@ -44,7 +44,8 @@ impl<'de> Deserialize<'de> for Atoms { if sheet.is_empty() { Ok(Default::default()) } else { - all_consuming(root(¬es))(&sheet) + set_notes(notes).unwrap(); + all_consuming(root)(&sheet) .map_err(|e| pretty_verbose_err.curry().call1(sheet.as_str()).call1(e)) .map_err(de::Error::custom) .map(|(i, r)| r) diff --git a/src/bng/score/lex/lexer.rs b/src/bng/score/lex/lexer.rs index b3fbd0e..aaba0da 100644 --- a/src/bng/score/lex/lexer.rs +++ b/src/bng/score/lex/lexer.rs @@ -1,10 +1,12 @@ use std::{ collections::BTreeMap, num::{NonZeroU16, NonZeroU8, TryFromIntError}, + sync::{Mutex, MutexGuard, PoisonError}, }; use clap::builder::TypedValueParser; use fasteval::Compiler; +use lazy_static::lazy_static; use nom::{ branch::alt, bytes::complete::{take_till, take_till1}, @@ -25,6 +27,16 @@ use super::{ // #[cfg(test)] // mod tests; +lazy_static! { + static ref NOTES: Mutex> = Mutex::new(None); +} + +pub fn set_notes( + notes: impl ToString, +) -> Result, PoisonError>>> { + Ok(NOTES.lock()?.replace(notes.to_string())) +} + fn maybe_yml_str_space<'a, E>() -> impl Parser<&'a str, Vec, E> where E: nom::error::ParseError<&'a str> + ContextError<&'a str>, @@ -32,7 +44,7 @@ where context("yml white space", many0(one_of(" \t\r\n"))) } -pub fn root<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atoms, E> +pub fn root<'a, E>(i: &'a str) -> IResult<&'a str, Atoms, E> where E: ParseError<&'a str> + ContextError<&'a str> @@ -40,21 +52,27 @@ where + FromExternalError<&'a str, E>, { terminated( - many1(preceded(maybe_yml_str_space(), atom(notes))), + many1(preceded(maybe_yml_str_space(), atom)), maybe_yml_str_space(), ) .map(Atoms) + .parse(i) } -fn note<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> +fn note<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E> where E: ParseError<&'a str> + ContextError<&'a str> + FromExternalError<&'a str, TryFromIntError>, { - context( - "note", - map_res(map_opt(one_of(notes), |c| notes.find(c)), u8::try_from), - ) - .map(Atom::Note) + if let Some(notes) = NOTES.lock().unwrap().as_deref() { + context( + "note", + map_res(map_opt(one_of(notes), |c| notes.find(c)), u8::try_from), + ) + .map(Atom::Note) + .parse(i) + } else { + panic!("trouble locking the note set!") + } } fn rest<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E> @@ -95,7 +113,7 @@ where .parse(i) } -fn r#loop<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> +fn r#loop<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E> where E: ParseError<&'a str> + ContextError<&'a str> @@ -114,15 +132,16 @@ where unsafe { Some(NonZeroU8::new_unchecked(2)) } } }), - root(notes), + root, ), char(Atom::LOOP.1), ), ) .map(|(n, v)| Atom::Loop(n, v)) + .parse(i) } -fn tuple<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> +fn tuple<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E> where E: ParseError<&'a str> + ContextError<&'a str> @@ -131,12 +150,13 @@ where { context( "tuple", - delimited(char(Atom::TUPLE.0), root(notes), char(Atom::TUPLE.1)), + delimited(char(Atom::TUPLE.0), root, char(Atom::TUPLE.1)), ) .map(Atom::Tuple) + .parse(i) } -fn slope<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> +fn slope<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E> where E: ParseError<&'a str> + ContextError<&'a str> @@ -159,10 +179,11 @@ where ), ), char(','), - root(notes), + root, ), ) .map(|((sm, i), v)| Atom::Slope(sm, i, v)) + .parse(i) } fn comment<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E> @@ -182,7 +203,7 @@ where )(i) } -fn atom<'a, E>(notes: &'a str) -> impl Parser<&'a str, Atom, E> +fn atom<'a, E>(i: &'a str) -> IResult<&'a str, Atom, E> where E: ParseError<&'a str> + ContextError<&'a str> @@ -192,15 +213,16 @@ where context( "atom", alt(( - note(notes), + note, rest, start_here, modifier, quick_modifier, - r#loop(¬es), - tuple(¬es), - slope(¬es), + r#loop, + tuple, + slope, comment, )), ) + .parse(i) }