From e7bc2f3d36909f1e9ad99032382e8ad13f4e1bc3 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 27 Jul 2023 18:53:46 +0200 Subject: [PATCH] Macro for complex filters works --- Cargo.lock | 57 ++++----- firls-rs-macros/Cargo.toml | 1 + .../examples/filter_complex_macro.rs | 20 +++ firls-rs-macros/src/lib.rs | 114 ++++++++++++++---- 4 files changed, 139 insertions(+), 53 deletions(-) create mode 100644 firls-rs-macros/examples/filter_complex_macro.rs diff --git a/Cargo.lock b/Cargo.lock index 4e10c2d..874f6d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,10 @@ name = "firls-rs-macros" version = "0.1.0" dependencies = [ "firls_rs", + "num", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -54,9 +55,9 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.32.2" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68d47bba83f9e2006d117a9a33af1524e655516b8919caac694427a6fb1e511" +checksum = "307ed9b18cc2423f29e83f84fd23a8e73628727990181f18641a8b5dc2ab1caa" dependencies = [ "approx", "matrixmultiply", @@ -70,9 +71,9 @@ dependencies = [ [[package]] name = "nalgebra-macros" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d232c68884c0c99810a5a4d333ef7e47689cfd0edc85efc9e54e1e6bf5212766" +checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998" dependencies = [ "proc-macro2", "quote", @@ -81,9 +82,9 @@ dependencies = [ [[package]] name = "num" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" +checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" dependencies = [ "num-bigint", "num-complex", @@ -148,33 +149,33 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] [[package]] name = "paste" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "proc-macro2" -version = "1.0.64" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.29" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -187,9 +188,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "safe_arch" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62a7484307bd40f8f7ccbacccac730108f2cae119a3b11c74485b48aa9ea650f" +checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354" dependencies = [ "bytemuck", ] @@ -220,9 +221,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.23" +version = "2.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" dependencies = [ "proc-macro2", "quote", @@ -231,22 +232,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -257,15 +258,15 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "wide" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40018623e2dba2602a9790faba8d33f2ebdebf4b86561b83928db735f8784728" +checksum = "aa469ffa65ef7e0ba0f164183697b89b854253fd31aeb92358b7b6155177d62f" dependencies = [ "bytemuck", "safe_arch", diff --git a/firls-rs-macros/Cargo.toml b/firls-rs-macros/Cargo.toml index 50a6739..a1fd003 100644 --- a/firls-rs-macros/Cargo.toml +++ b/firls-rs-macros/Cargo.toml @@ -8,6 +8,7 @@ proc-macro = true [dependencies] firls_rs = { path = "../firls-rs" } +num = "0.4.1" proc-macro2 = "1.0.64" quote = "1.0.29" syn = {version="2.0.23", features=["full"]} diff --git a/firls-rs-macros/examples/filter_complex_macro.rs b/firls-rs-macros/examples/filter_complex_macro.rs new file mode 100644 index 0000000..ecb60eb --- /dev/null +++ b/firls-rs-macros/examples/filter_complex_macro.rs @@ -0,0 +1,20 @@ +use firls_rs_macros::firls_complex; + +use num::Complex; + +const COEFFS: [Complex; 23] = firls_complex!( + 23, + 8000.0, + [(0.0, 1.0), (1200.0, 1.0), (1500.0, 0.0), (4000.0, 0.0)], + 1500.0 +); + +fn main() { + println!("["); + for coeff in COEFFS.iter() { + println!("{},", coeff) + } + println!("]"); + + println!("Lenght: {}", COEFFS.len()); +} diff --git a/firls-rs-macros/src/lib.rs b/firls-rs-macros/src/lib.rs index 4bfd27f..10b13f6 100644 --- a/firls-rs-macros/src/lib.rs +++ b/firls-rs-macros/src/lib.rs @@ -1,15 +1,39 @@ +extern crate num; extern crate proc_macro; extern crate quote; -use firls_rs::firls; +use firls_rs::{firls, frequency_shift_coeffs}; use proc_macro::TokenStream; use proc_macro2::Span; use quote::quote; use syn::parse::{Parse, ParseStream}; +use syn::parse_macro_input; use syn::spanned::Spanned; -use syn::{parse_macro_input}; use syn::{punctuated::Punctuated, Expr, Lit, Token}; +#[proc_macro] +pub fn firls_real(input: TokenStream) -> TokenStream { + let FirlsRealInput { + filter_len, + sampling_frequency, + bands, + span, + } = parse_macro_input!(input as FirlsRealInput); + + let output = match firls(filter_len, sampling_frequency, &bands) { + Ok(coeffs) => { + quote! { + [ + #(#coeffs),* + ] + } + } + Err(msg) => syn::Error::new(span, msg).to_compile_error(), + }; + + proc_macro::TokenStream::from(output) +} + struct FirlsRealInput { filter_len: usize, sampling_frequency: f32, @@ -37,6 +61,69 @@ impl Parse for FirlsRealInput { } } +#[proc_macro] +pub fn firls_complex(input: TokenStream) -> TokenStream { + let FirlsComplexInput { + filter_len, + sampling_frequency, + bands, + frequency_shift, + span, + } = parse_macro_input!(input as FirlsComplexInput); + + let output = match firls(filter_len, sampling_frequency, &bands) { + Ok(coeffs) => { + let coeffs = frequency_shift_coeffs(&coeffs, sampling_frequency, frequency_shift); + let constructors: Vec = coeffs + .iter() + .map(|num::Complex:: { re, im }| { + quote! { + num::Complex:: {re: #re, im: #im} + } + }) + .collect(); + + quote! { + [ + #(#constructors),* + ] + } + } + Err(msg) => syn::Error::new(span, msg).to_compile_error(), + }; + + proc_macro::TokenStream::from(output) +} + +struct FirlsComplexInput { + filter_len: usize, + sampling_frequency: f32, + bands: Vec<(f32, f32)>, + frequency_shift: f32, + span: Span, +} + +impl Parse for FirlsComplexInput { + fn parse(input: ParseStream) -> Result { + let arg_list = Punctuated::::parse_separated_nonempty(input)?; + + if arg_list.len() != 4 { + return Err(syn::Error::new( + arg_list.span(), + "firls_complex takes 4 parameters", + )); + } + + Ok(FirlsComplexInput { + filter_len: parse_filter_len(&arg_list[0])?, + sampling_frequency: parse_frequency(&arg_list[1])?, + bands: parse_band_list(&arg_list[2])?, + frequency_shift: parse_frequency(&arg_list[3])?, + span: arg_list.span(), + }) + } +} + fn parse_filter_len(len: &Expr) -> Result { match len { Expr::Lit(expr) => match &expr.lit { @@ -122,26 +209,3 @@ fn parse_band_tuple(tuple: &Expr) -> Result<(f32, f32), syn::Error> { )), } } - -#[proc_macro] -pub fn firls_real(input: TokenStream) -> TokenStream { - let FirlsRealInput { - filter_len, - sampling_frequency, - bands, - span, - } = parse_macro_input!(input as FirlsRealInput); - - let output = match firls(filter_len, sampling_frequency, &bands) { - Ok(coeffs) => { - quote! { - [ - #(#coeffs),* - ] - } - } - Err(msg) => syn::Error::new(span, msg).to_compile_error(), - }; - - proc_macro::TokenStream::from(output) -}