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}