1mod assembler;
2use proc_macro::TokenStream;
3use syn::parse_macro_input;
4
5#[proc_macro]
6pub fn assembler(input: TokenStream) -> TokenStream {
7 let input = parse_macro_input!(input with syn::punctuated::Punctuated::<syn::Expr, syn::Token![,]>::parse_terminated)
9 .into_iter()
10 .collect::<Vec<_>>();
11
12 if input.len() != 2 {
13 panic!("Expected two arguments: architecture name and definition file path");
14 }
15
16 let architecture = if let syn::Expr::Path(path) = &input[0] {
18 if let Some(ident) = path.path.get_ident() {
19 ident.to_string()
20 } else {
21 panic!("Expected architecture identifier");
22 }
23 } else {
24 panic!("Expected architecture identifier");
25 };
26
27 let filename = if let syn::Expr::Lit(syn::ExprLit {
29 lit: syn::Lit::Str(s),
30 ..
31 }) = &input[1]
32 {
33 s.value()
34 } else {
35 panic!("Expected string literal for filename");
36 };
37
38 let raw_definition = monistode_binutils::definition::RawDefinition::from_str(
39 match std::fs::read_to_string(&filename) {
40 Ok(x) => x,
41 Err(e) => panic!("Error reading {}: {}", filename, e),
42 }
43 .as_str(),
44 )
45 .unwrap();
46 let definition = monistode_binutils::definition::Definition::try_from(raw_definition).unwrap();
47 assembler::generate_parser(&definition, &architecture).into()
48}