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