Compare commits
No commits in common. "f9841267ec9c55fd81dbb418277640f6c8d72e75" and "7a02a920db363da6916d3a1533e696c149b4d40c" have entirely different histories.
f9841267ec
...
7a02a920db
7 changed files with 4 additions and 133 deletions
|
@ -14,18 +14,9 @@ nom = "7.1.3"
|
||||||
serde = "1.0.209"
|
serde = "1.0.209"
|
||||||
serde_yml = "0.0.12"
|
serde_yml = "0.0.12"
|
||||||
splines = "4.3.1"
|
splines = "4.3.1"
|
||||||
strum = { version = "0.26", features = ["derive"] }
|
|
||||||
strum_macros = "0.26"
|
|
||||||
tinyaudio = { version = "0.1", optional = true }
|
tinyaudio = { version = "0.1", optional = true }
|
||||||
bng_macros = { path = "bng_macros" }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["play", "save"]
|
default = ["play", "save"]
|
||||||
play = ["dep:tinyaudio"]
|
play = ["dep:tinyaudio"]
|
||||||
save = []
|
save = []
|
||||||
|
|
||||||
[workspace]
|
|
||||||
members = ["bng_macros"]
|
|
||||||
|
|
||||||
[lints.rust]
|
|
||||||
unused = "allow"
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "bng_macros"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
proc-macro = true
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
proc-macro2 = "1.0"
|
|
||||||
quote = "1.0"
|
|
||||||
syn = { version = "2.0", features = ["full"] }
|
|
|
@ -1,79 +0,0 @@
|
||||||
extern crate proc_macro;
|
|
||||||
use proc_macro::TokenStream;
|
|
||||||
use quote::quote;
|
|
||||||
use syn::{parse_macro_input, Data, DataEnum, DeriveInput, Fields};
|
|
||||||
|
|
||||||
#[proc_macro_derive(ModifierParser)]
|
|
||||||
pub fn modifier_parser(input: TokenStream) -> TokenStream {
|
|
||||||
let ast = parse_macro_input!(input as DeriveInput);
|
|
||||||
impl_modifier_parser(ast)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[proc_macro_derive(SlopeModifierParser)]
|
|
||||||
pub fn slope_modifier_parser(input: TokenStream) -> TokenStream {
|
|
||||||
let ast = parse_macro_input!(input as DeriveInput);
|
|
||||||
impl_slope_modifier_parser(ast)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn impl_modifier_parser(ast: DeriveInput) -> TokenStream {
|
|
||||||
let name = &ast.ident;
|
|
||||||
if let Data::Enum(DataEnum { variants, .. }) = ast.data {
|
|
||||||
let match_arms = variants.iter().map(|variant| {
|
|
||||||
let variant_name = &variant.ident;
|
|
||||||
let variant_type = if let Fields::Unnamed(ref fields) = variant.fields {
|
|
||||||
&fields.unnamed[0].ty
|
|
||||||
} else {
|
|
||||||
panic!("Expected unnamed fields in enum variants");
|
|
||||||
};
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
nom::combinator::map(
|
|
||||||
nom::sequence::preceded(
|
|
||||||
nom::character::complete::char(#name::#variant_name(Default::default()).token()),
|
|
||||||
nom::character::complete::#variant_type
|
|
||||||
),
|
|
||||||
#name::#variant_name
|
|
||||||
)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
impl lex::lexer::Parse for #name {
|
|
||||||
fn parse(input: &str) -> nom::IResult<&str, #name> {
|
|
||||||
nom::branch::alt((
|
|
||||||
#(#match_arms),*
|
|
||||||
))(input)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
} else {
|
|
||||||
panic!("this macro only works on enums")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn impl_slope_modifier_parser(ast: DeriveInput) -> TokenStream {
|
|
||||||
let name = &ast.ident;
|
|
||||||
if let Data::Enum(DataEnum { variants, .. }) = ast.data {
|
|
||||||
let match_arms = variants.iter().map(|variant| {
|
|
||||||
let variant_name = &variant.ident;
|
|
||||||
quote! {
|
|
||||||
tag(#name::#variant_name)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
impl lex::lexer::Parse for #name {
|
|
||||||
fn parse(input: &str) -> nom::IResult<&str, #name> {
|
|
||||||
let tag = |sm: SlopeModifier| nom::combinator::value(sm, nom::character::complete::char(sm.token()));
|
|
||||||
nom::branch::alt((
|
|
||||||
#(#match_arms),*
|
|
||||||
))(input)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
} else {
|
|
||||||
panic!("this macro only works on enums")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,7 +24,7 @@ channels:
|
||||||
(3deff)
|
(3deff)
|
||||||
(deff)
|
(deff)
|
||||||
[ffe]
|
[ffe]
|
||||||
{l 1-cos((PI*x)/2),acced}
|
{1-cos((PI*x)/2),acced}
|
||||||
abbc!o5cc!v15feed!l4fedd!t60hdd
|
abbc!o5cc!v15feed!l4fedd!t60hdd
|
||||||
# rest: .
|
# rest: .
|
||||||
# pizz.: '°
|
# pizz.: '°
|
||||||
|
@ -33,12 +33,7 @@ channels:
|
||||||
# octave: ><
|
# octave: ><
|
||||||
# comment?: ;,
|
# comment?: ;,
|
||||||
# start here: ':'
|
# start here: ':'
|
||||||
# slope: {MODIFIER EXPR, score}
|
# glissando: {EXPR, score}
|
||||||
# note modifier prefix: n
|
|
||||||
# volume modifier prefix: v
|
|
||||||
# octave modifier prefix: o
|
|
||||||
# length modifier prefix: l
|
|
||||||
# tempo modifier prefix: t
|
|
||||||
# loop: ()
|
# loop: ()
|
||||||
# loop with count: (COUNT, score)
|
# loop with count: (COUNT, score)
|
||||||
# tuple: []
|
# tuple: []
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use bng_macros::{ModifierParser, SlopeModifierParser};
|
|
||||||
use fasteval::Instruction;
|
use fasteval::Instruction;
|
||||||
|
|
||||||
mod lex;
|
mod lex;
|
||||||
use lex::Token;
|
|
||||||
|
|
||||||
pub(super) enum Atom {
|
pub(super) enum Atom {
|
||||||
Note(u8),
|
Note(u8),
|
||||||
|
@ -14,7 +12,6 @@ pub(super) enum Atom {
|
||||||
EmptyWrapper(WrapperKind),
|
EmptyWrapper(WrapperKind),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(ModifierParser)]
|
|
||||||
pub(super) enum Modifier {
|
pub(super) enum Modifier {
|
||||||
Volume(u8),
|
Volume(u8),
|
||||||
Octave(u8),
|
Octave(u8),
|
||||||
|
@ -36,7 +33,6 @@ pub(super) enum WrapperKind {
|
||||||
Comment,
|
Comment,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, SlopeModifierParser)]
|
|
||||||
pub(super) enum SlopeModifier {
|
pub(super) enum SlopeModifier {
|
||||||
Note,
|
Note,
|
||||||
Volume,
|
Volume,
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
use super::{Atom, Modifier, SlopeModifier, WrapperKind};
|
use super::{Atom, Modifier, WrapperKind};
|
||||||
|
|
||||||
pub(super) mod lexer;
|
|
||||||
|
|
||||||
const MORE: bool = true;
|
const MORE: bool = true;
|
||||||
const LESS: bool = false;
|
const LESS: bool = false;
|
||||||
const ON: bool = true;
|
const ON: bool = true;
|
||||||
|
@ -15,7 +12,7 @@ impl WrappingTokens {
|
||||||
const SEMICOLON_COMMA: (char, char) = (';', ',');
|
const SEMICOLON_COMMA: (char, char) = (';', ',');
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) trait Token<T> {
|
trait Token<T> {
|
||||||
fn token(self) -> T;
|
fn token(self) -> T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,18 +38,6 @@ impl Token<char> for Modifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Token<char> for SlopeModifier {
|
|
||||||
fn token(self) -> char {
|
|
||||||
match self {
|
|
||||||
Self::Note => 'n',
|
|
||||||
Self::Volume => 'v',
|
|
||||||
Self::Octave => 'o',
|
|
||||||
Self::Length => 'l',
|
|
||||||
Self::Tempo => 't',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Token<char> for Atom {
|
impl Token<char> for Atom {
|
||||||
fn token(self) -> char {
|
fn token(self) -> char {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
use nom::IResult;
|
|
||||||
|
|
||||||
pub(crate) trait Parse: Sized {
|
|
||||||
fn parse(input: &str) -> IResult<&str, Self>;
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue