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}