mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 16:21:33 +11:00
Pass a Gba struct argument to the agb entry
This commit is contained in:
parent
40b87e6c6f
commit
0d623fc5b0
|
@ -2,9 +2,9 @@
|
|||
use proc_macro::TokenStream;
|
||||
|
||||
use proc_macro2::Span;
|
||||
use quote::quote;
|
||||
use quote::{quote, ToTokens};
|
||||
use rand::Rng;
|
||||
use syn::{Ident, ItemFn, ReturnType, Type, Visibility};
|
||||
use syn::{FnArg, Ident, ItemFn, Pat, ReturnType, Token, Type, Visibility};
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
|
@ -15,16 +15,43 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
|
|||
f.sig.constness.is_none()
|
||||
&& f.vis == Visibility::Inherited
|
||||
&& f.sig.abi.is_none()
|
||||
&& f.sig.inputs.is_empty()
|
||||
&& f.sig.generics.params.is_empty()
|
||||
&& f.sig.generics.where_clause.is_none()
|
||||
&& match f.sig.output {
|
||||
ReturnType::Type(_, ref ty) => matches!(**ty, Type::Never(_)),
|
||||
_ => false,
|
||||
},
|
||||
"#[agb::entry] must have signature [unsafe] fn () -> !"
|
||||
"#[agb::entry] must have signature [unsafe] fn (mut agb::Gba) -> !"
|
||||
);
|
||||
|
||||
// Check that the function signature takes 1 argument, agb::Gba
|
||||
let arguments: Vec<_> = f.sig.inputs.iter().collect();
|
||||
|
||||
assert_eq!(
|
||||
arguments.len(),
|
||||
1,
|
||||
"#[agb::entry] must have signature [unsafe] fn (mut agb::Gba) -> !, but got {} arguments",
|
||||
arguments.len(),
|
||||
);
|
||||
|
||||
let (argument_type, (argument_name, is_mutable)) = match arguments[0] {
|
||||
FnArg::Typed(pat_type) => (
|
||||
pat_type.ty.to_token_stream(),
|
||||
match &*pat_type.pat {
|
||||
Pat::Ident(ident) => {
|
||||
assert!(
|
||||
ident.attrs.is_empty() && ident.by_ref.is_none() && ident.subpat.is_none(),
|
||||
"#[agb::entry] must have signature [unsafe] fn (mut agb::Gba) -> !"
|
||||
);
|
||||
|
||||
(ident.ident.clone(), ident.mutability.is_some())
|
||||
}
|
||||
_ => panic!("Expected first argument to #[agb::entry] to be a basic identifier"),
|
||||
},
|
||||
),
|
||||
_ => panic!("Expected first argument to #[agb::entry] to not be self"),
|
||||
};
|
||||
|
||||
assert!(
|
||||
args.to_string() == "",
|
||||
"Must pass no args to #[agb::entry] macro"
|
||||
|
@ -35,10 +62,23 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
|
|||
let attrs = f.attrs;
|
||||
let stmts = f.block.stmts;
|
||||
|
||||
let mutable = if is_mutable {
|
||||
Some(Token![mut](Span::call_site()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
assert!(
|
||||
argument_type.to_string().ends_with("Gba"),
|
||||
"Expected first argument to have type 'Gba'"
|
||||
);
|
||||
|
||||
quote!(
|
||||
#[export_name = "main"]
|
||||
#(#attrs)*
|
||||
pub fn #fn_name() -> ! {
|
||||
let #mutable #argument_name = #argument_type ::new();
|
||||
|
||||
#(#stmts)*
|
||||
}
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue