Skip to content

Commit

Permalink
Derive macro modifications
Browse files Browse the repository at this point in the history
- Remove unstable proc_macro_span feature
- Add quick documentation pointing to the main trait
- Return a Result<u16, syn::Error> from analyze_bitsize and convert to a compile_error
  • Loading branch information
johngigantic committed Oct 27, 2023
1 parent bce8e8f commit b69680f
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 59 deletions.
1 change: 0 additions & 1 deletion derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ proc-macro = true
proc-macro2 = "1.0.69"
quote = "1.0.33"
syn = "2.0.38"
# allegro-motor-drivers = { version = "0.1.0", path = "../drivers" }

[dev-dependencies]
bilge = "0.2.0"
42 changes: 0 additions & 42 deletions derive/src/chips.rs

This file was deleted.

60 changes: 48 additions & 12 deletions derive/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,48 @@
//! Derive macros to implement allegro_motor_drivers::io traits.

#![feature(proc_macro_span)]

extern crate proc_macro;

use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};

mod chips;

/// Derive macro to implement the allegro_motor_drivers::regs::AllegroRegister trait.
///
/// See the [AllegroRegister trait][trait] for examples and complete documentation.
///
/// [trait]: ../allegro_motor_drivers/regs/trait.AllegroRegister.html
///
/// Please note that a compile failure will occur if derive macros are defined in the wrong order,
/// or if the bitsize derive macro is not used at all. This occurs because derive macros are parsed
/// from the outside in, and each macro depends on implementations defined by other macros.
///
/// ```compile_fail
/// # #[macro_use] extern crate allegro_motor_derive;
/// # use bilge::prelude::*;
/// #[derive(AllegroRegister)]
/// struct StructWithoutBitsize {
/// field_1: bool,
/// }
/// ```
///
/// ```compile_fail
/// # #[macro_use] extern crate allegro_motor_derive;
/// # use bilge::prelude::*;
/// #[bitsize(1)]
/// #[derive(AllegroRegister)]
/// struct WrongMacroOrder {
/// field_1: bool,
/// }
/// ```
///
#[proc_macro_derive(AllegroRegister)]
pub fn allegro_derive(item: TokenStream) -> TokenStream {
let DeriveInput { ident, .. } = parse_macro_input!(item as DeriveInput);
let DeriveInput { ident, attrs, .. } = parse_macro_input!(item as DeriveInput);

let source_file = proc_macro::Span::call_site().source_file().clone().path();
let chip_name = source_file.iter().nth(2).unwrap().to_str().unwrap();
let chip = chips::CHIPS
.into_iter()
.find(|chip| chip.name == chip_name)
.unwrap();
let bitsize = proc_macro2::Literal::u16_unsuffixed(chip.register_size);
let bitsize = match analyze_bitsize(&attrs) {
Ok(bitsize) => proc_macro2::Literal::u16_unsuffixed(bitsize),
Err(error_msg) => return error_msg.into_compile_error().into(),
};

quote! {
impl crate::regs::AllegroRegister<bilge::prelude::UInt<u16, #bitsize>> for #ident {
Expand All @@ -37,3 +57,19 @@ pub fn allegro_derive(item: TokenStream) -> TokenStream {
}
.into()
}

fn analyze_bitsize(attrs: &Vec<syn::Attribute>) -> Result<u16, syn::Error> {
let mut bitsizes = attrs.iter().filter_map(|attr| {
if attr.path().is_ident("bitsize") {
let a: syn::LitInt = attr.parse_args().unwrap();
Some(a.base10_parse::<u16>().unwrap())
} else {
None
}
});

match bitsizes.next() {
Some(bitsize) => Ok(bitsize),
None => Err(syn::Error::new_spanned(attrs.iter().next(), "'bitsize' not found in object attributes.")),
}
}
6 changes: 4 additions & 2 deletions drivers/src/a4910/regs/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ impl Default for VdsThreshold {
}
}

#[derive(AllegroRegister)]
#[bitsize(13)]
#[derive(PartialEq, Clone, Copy, DebugBits, DefaultBits, FromBits, AllegroRegister)]
#[derive(PartialEq, Clone, Copy, DebugBits, DefaultBits, FromBits)]
pub struct Config0 {
pub dt: DeadTime,
pub bt: FaultBlankingTime,
Expand All @@ -89,8 +90,9 @@ impl ConstantAddress<A4910Reg> for Config0 {
const ADDRESS: A4910Reg = A4910Reg::Config0;
}

#[derive(AllegroRegister)]
#[bitsize(13)]
#[derive(PartialEq, Clone, Copy, DebugBits, DefaultBits, FromBits, AllegroRegister)]
#[derive(PartialEq, Clone, Copy, DebugBits, DefaultBits, FromBits)]
pub struct Config1 {
pub vt: VdsThreshold,
reserved: u1,
Expand Down
3 changes: 2 additions & 1 deletion drivers/src/a4910/regs/mask.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ use bilge::prelude::*;
use super::A4910Reg;
use crate::regs::ConstantAddress;

#[derive(AllegroRegister)]
#[bitsize(13)]
#[derive(PartialEq, Clone, Copy, DebugBits, Default, FromBits, AllegroRegister)]
#[derive(PartialEq, Clone, Copy, DebugBits, Default, FromBits)]
pub struct Mask {
pub cl: bool,
pub ch: bool,
Expand Down
3 changes: 2 additions & 1 deletion drivers/src/a4910/regs/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ use bilge::prelude::*;
use super::A4910Reg;
use crate::regs::ConstantAddress;

#[derive(AllegroRegister)]
#[bitsize(13)]
#[derive(PartialEq, Clone, Copy, DebugBits, Default, FromBits, AllegroRegister)]
#[derive(PartialEq, Clone, Copy, DebugBits, Default, FromBits)]
pub struct Run {
pub cl: bool,
pub ch: bool,
Expand Down

0 comments on commit b69680f

Please sign in to comment.