Skip to main content

zodiac_macro/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{ItemFn, ItemStatic, parse_macro_input};
4
5#[proc_macro_attribute]
6pub fn global_allocator(_attr: TokenStream, item: TokenStream) -> TokenStream {
7    let global_allocator_item = parse_macro_input!(item as ItemStatic);
8    let global_allocator_name = &global_allocator_item.ident;
9
10    quote!(
11        #[used]
12        #[unsafe(no_mangle)]
13        static __ZODIAC_GLOBAL_ALLOCATOR: &'static dyn ::zodiac::mem::Allocator = &#global_allocator_name;
14
15        #global_allocator_item
16    )
17    .into()
18}
19
20#[proc_macro_attribute]
21pub fn main(_attr: TokenStream, item: TokenStream) -> TokenStream {
22    let main_fn = parse_macro_input!(item as ItemFn);
23    let main_fn_name = &main_fn.sig.ident;
24
25    quote!(
26        #[unsafe(no_mangle)]
27        extern "Rust" fn __zodiac_main() -> ! {
28            let _: () = #main_fn_name();
29
30            loop {}
31        }
32
33        #[expect(unused)]
34        #main_fn
35    )
36    .into()
37}
38
39#[proc_macro_attribute]
40pub fn panic_handler(_attr: TokenStream, item: TokenStream) -> TokenStream {
41    let handler_fn = parse_macro_input!(item as ItemFn);
42    let handler_fn_name = &handler_fn.sig.ident;
43
44    quote!(
45        #[unsafe(no_mangle)]
46        extern "Rust" fn __zodiac_panic_handler(info: &core::panic::PanicInfo) -> ! {
47            #handler_fn_name(info);
48        }
49
50        #[expect(unused)]
51        #handler_fn
52    )
53    .into()
54}