use proc_macro2::{Ident, Span, TokenStream};
use proc_macro_crate::FoundCrate;
use quote::quote;
use syn::{parse_macro_input, ItemMod};
use crate::extractor::extract_defs;
use crate::generator::generate_microcode_type;
use crate::validation::validate_defs;
mod defs;
mod extractor;
mod generator;
mod parsing;
mod validation;
#[proc_macro_attribute]
pub fn define_microcode(
attr: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
let name = parse_macro_input!(attr as Ident);
let module = parse_macro_input!(item as ItemMod);
let defs = match extract_defs(name, module) {
Ok(defs) => defs,
Err(e) => return e.into_compile_error().into(),
};
if let Err(e) = validate_defs(&defs) {
return e.into_compile_error().into();
}
generate_microcode_type(&defs).into()
}
fn get_crate(name: &str) -> TokenStream {
match proc_macro_crate::crate_name(name) {
Ok(FoundCrate::Itself) => quote! { crate },
Ok(FoundCrate::Name(name)) => {
let name = Ident::new(&name, Span::call_site());
quote! { ::#name }
}
Err(e) => panic!(
"Unable to find the {} crate: {}, required by this macro.",
name, e
),
}
}