ruda_kernel_macros/ir/
entrypoints.rs1use core::panic;
2
3use ir::error::error_into_token_stream;
4use ir::generate::autotune::generate_autotune_key;
5use ir::parse::{
6 ruda_impl::RudaImpl,
7 ruda_trait::{RudaTrait, RudaTraitImpl},
8 helpers::{RemoveHelpers, ReplaceIndices},
9 kernel::{Launch, from_tokens},
10};
11use syn::visit_mut::VisitMut;
12
13use crate::ir::{
14 generate::{assign::generate_ruda_type_mut, into_runtime::generate_into_runtime},
15 parse::{
16 ruda_type::generate_ruda_type, derive_expand::generate_derive_expand,
17 helpers::ReplaceDefines,
18 },
19};
20
21
22#[proc_macro_attribute]
47pub fn ruda(args: TokenStream, input: TokenStream) -> TokenStream {
48 match ruda_impl(args, input.clone()) {
49 Ok(tokens) => tokens,
50 Err(e) => error_into_token_stream(e, input.into()).into(),
51 }
52}
53
54fn ruda_impl(args: TokenStream, input: TokenStream) -> syn::Result<TokenStream> {
55 let mut item: Item = syn::parse(input)?;
56 let args = from_tokens(args.into())?;
57
58 let tokens = match item.clone() {
59 Item::Fn(kernel) => {
60 let kernel = Launch::from_item_fn(kernel, args)?;
61 RemoveHelpers.visit_item_mut(&mut item);
62 ReplaceIndices.visit_item_mut(&mut item);
63 ReplaceDefines.visit_item_mut(&mut item);
64
65 return Ok(TokenStream::from(quote! {
66 #[allow(dead_code, clippy::too_many_arguments)]
67 #item
68 #kernel
69 }));
70 }
71 Item::Trait(kernel_trait) => {
72 let is_debug = args.debug.is_present();
73 let expand_trait = RudaTrait::from_item_trait(kernel_trait, args)?;
74
75 let tokens = TokenStream::from(quote! {
76 #expand_trait
77 });
78 if is_debug {
79 panic!("{tokens}");
80 }
81 return Ok(tokens);
82 }
83 Item::Impl(item_impl) => {
84 if item_impl.trait_.is_some() {
85 let mut expand_impl = RudaTraitImpl::from_item_impl(item_impl, &args)?;
86 let expand_impl = expand_impl.to_tokens_mut();
87
88 Ok(TokenStream::from(quote! {
89 #expand_impl
90 }))
91 } else {
92 let mut expand_impl = RudaImpl::from_item_impl(item_impl, &args)?;
93 let expand_impl = expand_impl.to_tokens_mut();
94
95 Ok(TokenStream::from(quote! {
96 #expand_impl
97 }))
98 }
99 }
100 item => Err(syn::Error::new_spanned(
101 item,
102 "`#[ruda]` is only supported on traits and functions",
103 ))?,
104 };
105
106 if args.debug.is_present() {
107 match tokens {
108 Ok(tokens) => panic!("{tokens}"),
109 Err(err) => panic!("{err}"),
110 };
111 }
112
113 tokens
114}
115
116#[proc_macro_derive(RudaLaunch, attributes(ruda, launch))]
118pub fn module_derive_ruda_launch(input: TokenStream) -> TokenStream {
119 gen_ruda_type(input, true)
120}
121
122#[proc_macro_derive(RudaType, attributes(ruda))]
124pub fn module_derive_ruda_type(input: TokenStream) -> TokenStream {
125 gen_ruda_type(input, false)
126}
127
128fn gen_ruda_type(input: TokenStream, with_launch: bool) -> TokenStream {
129 let parsed = syn::parse(input);
130
131 let input = match &parsed {
132 Ok(val) => val,
133 Err(err) => return err.to_compile_error().into(),
134 };
135
136 match generate_ruda_type(input, with_launch) {
137 Ok(val) => val.into(),
138 Err(err) => err.to_compile_error().into(),
139 }
140}
141
142#[proc_macro_attribute]
145pub fn derive_ruda_comptime(_metadata: TokenStream, input: TokenStream) -> TokenStream {
146 let input: proc_macro2::TokenStream = input.into();
147 quote! {
148 #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
149 #input
150 }
151 .into()
152}
153
154#[proc_macro_attribute]
156pub fn derive_expand(metadata: TokenStream, input: TokenStream) -> TokenStream {
157 match generate_derive_expand(input.into(), metadata.into()) {
158 Ok(val) => val.into(),
159 Err(err) => err.to_compile_error().into(),
160 }
161}
162
163#[proc_macro]
177pub fn comptime(input: TokenStream) -> TokenStream {
178 let tokens: proc_macro2::TokenStream = input.into();
179 quote![{ #tokens }].into()
180}
181
182#[proc_macro]
195pub fn intrinsic(_input: TokenStream) -> TokenStream {
196 let core = ir::paths::core_path();
197 quote![{ #core::unexpanded!() }].into()
198}
199
200#[proc_macro]
215pub fn comptime_type(input: TokenStream) -> TokenStream {
216 let tokens: proc_macro2::TokenStream = input.into();
217 quote![ #tokens ].into()
218}
219
220#[proc_macro]
232pub fn comment(input: TokenStream) -> TokenStream {
233 let tokens: proc_macro2::TokenStream = input.into();
234 quote![{ #tokens }].into()
235}
236
237#[proc_macro]
253pub fn terminate(input: TokenStream) -> TokenStream {
254 let tokens: proc_macro2::TokenStream = input.into();
255 quote![{ #tokens }].into()
256}
257
258#[proc_macro_derive(AutotuneKey, attributes(autotune))]
283pub fn derive_autotune_key(input: TokenStream) -> TokenStream {
284 let input = syn::parse(input).unwrap();
285 match generate_autotune_key(input) {
286 Ok(tokens) => tokens.into(),
287 Err(e) => e.into_compile_error().into(),
288 }
289}
290
291#[proc_macro_derive(IntoRuntime, attributes(ruda))]
293pub fn derive_into_runtime(input: TokenStream) -> TokenStream {
294 let input = syn::parse(input).unwrap();
295 match generate_into_runtime(&input) {
296 Ok(tokens) => tokens.into(),
297 Err(e) => e.into_compile_error().into(),
298 }
299}
300
301#[proc_macro_derive(RudaTypeMut, attributes(ruda))]
303pub fn derive_assign(input: TokenStream) -> TokenStream {
304 let input = syn::parse(input).unwrap();
305 match generate_ruda_type_mut(&input) {
306 Ok(tokens) => tokens.into(),
307 Err(e) => e.into_compile_error().into(),
308 }
309}