use proc_macro::{TokenStream, TokenTree}; use quote::{format_ident, quote}; mod instrs; use self::instrs::*; #[proc_macro] pub fn mnemonics(input: TokenStream) -> TokenStream { let instrs: [Instruction; 256] = input .into_iter() .map(|tt| { if let TokenTree::Ident(ident) = tt { return ident.to_string(); } panic!("Not an ident"); }) .map(|mnemonic| mnemonic.parse()) .collect::, InstructionParseError>>() .unwrap_or_else(|inner| { panic!("Invalid instruction: {inner}"); }) .try_into() .unwrap_or_else(|_| { panic!("Not 256"); }); let bodies = instrs.into_iter() .map(|instr| { let instr_fn_ident = format_ident!("{}", instr.name.to_lowercase()); let short_ident = if instr.is_short { quote!(Short) } else { quote!(Byte) }; let is_keep = instr.is_keep; let is_return = instr.is_return; let is_cross_stack = instr.is_cross_stack; quote! { |e| e.map::<#is_keep, #is_return, #is_cross_stack, _, _, _>(Self::#instr_fn_ident::<#short_ident>) } }) .collect::>(); quote! { [ #( #bodies, )* ] } .into() }