macros/
lib.rs

1use syn::parse_macro_input;
2
3mod logging;
4mod syscall;
5mod tree;
6
7#[proc_macro_derive(TaggedLinks, attributes(rbtree, list))]
8pub fn derive_tagged_links(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
9    let input = syn::parse_macro_input!(input as syn::DeriveInput);
10
11    match tree::derive_tagged_links(&input) {
12        Ok(tokens) => tokens,
13        Err(e) => e.to_compile_error(),
14    }
15    .into()
16}
17
18#[proc_macro_attribute]
19pub fn fmt(
20    _args: proc_macro::TokenStream,
21    input: proc_macro::TokenStream,
22) -> proc_macro::TokenStream {
23    let input = syn::parse_macro_input!(input as syn::DeriveInput);
24
25    match logging::derive_fmt(&input) {
26        Ok(tokens) => tokens,
27        Err(e) => e.to_compile_error(),
28    }
29    .into()
30}
31
32#[proc_macro_attribute]
33pub fn app_main(
34    _attr: proc_macro::TokenStream,
35    item: proc_macro::TokenStream,
36) -> proc_macro::TokenStream {
37    let item = syn::parse_macro_input!(item as syn::ItemFn);
38    let block = &item.block;
39
40    let expanded = quote::quote! {
41        #[unsafe(no_mangle)]
42        #[unsafe(naked)]
43        extern "C" fn main() {
44            osiris::hal::asm::startup_trampoline!();
45        }
46
47        #[cfg(freestanding)]
48        #[panic_handler]
49        fn panic(info: &core::panic::PanicInfo) -> ! {
50            osiris::panic(info);
51        }
52
53        #[unsafe(no_mangle)]
54        pub extern "C" fn app_main() -> () {
55            #block
56        }
57    };
58
59    expanded.into()
60}
61
62#[proc_macro_attribute]
63pub fn syscall_handler(
64    attr: proc_macro::TokenStream,
65    item: proc_macro::TokenStream,
66) -> proc_macro::TokenStream {
67    let mut num = 0;
68
69    let parser = syn::meta::parser(|meta| {
70        if meta.path.is_ident("num") {
71            num = meta.value()?.parse::<syn::LitInt>()?.base10_parse()?;
72            Ok(())
73        } else {
74            Err(meta.error("unknown attribute"))
75        }
76    });
77
78    parse_macro_input!(attr with parser);
79
80    let item = syn::parse_macro_input!(item as syn::ItemFn);
81    syscall::syscall_handler_fn(&item).into()
82}