83 lines
2.1 KiB
Rust
83 lines
2.1 KiB
Rust
use quote::{quote, ToTokens};
|
|
use syn::{parenthesized, parse::ParseStream, punctuated::Punctuated, Ident, Token};
|
|
|
|
use super::{common::Attributes, document::DocumentItemAttributes};
|
|
|
|
pub struct SyscallDefinition {
|
|
pub attributes: Attributes,
|
|
pub name: Ident,
|
|
pub arguments: Punctuated<SyscallArgument, Token![,]>,
|
|
pub return_type: Option<syn::Type>,
|
|
}
|
|
|
|
pub struct SyscallArgument {
|
|
pub name: syn::Ident,
|
|
pub ty: syn::Type,
|
|
}
|
|
|
|
impl DocumentItemAttributes for SyscallDefinition {
|
|
fn extend_attributes<I: IntoIterator<Item = syn::Attribute>>(&mut self, attrs: I) {
|
|
self.attributes.extend(attrs);
|
|
}
|
|
}
|
|
|
|
impl syn::parse::Parse for SyscallDefinition {
|
|
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
|
|
let arguments;
|
|
|
|
let name = input.parse()?;
|
|
parenthesized!(arguments in input);
|
|
let arguments = arguments.parse_terminated(SyscallArgument::parse, Token![,])?;
|
|
|
|
let return_type = if input.peek(Token![->]) {
|
|
input.parse::<Token![->]>()?;
|
|
let ty = input.parse()?;
|
|
Some(ty)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
input.parse::<Token![;]>()?;
|
|
|
|
Ok(Self {
|
|
attributes: Attributes::new(),
|
|
name,
|
|
arguments,
|
|
return_type,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl syn::parse::Parse for SyscallArgument {
|
|
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
|
|
let name = input.parse()?;
|
|
input.parse::<Token![:]>()?;
|
|
let ty = input.parse()?;
|
|
|
|
Ok(Self { name, ty })
|
|
}
|
|
}
|
|
|
|
impl ToTokens for SyscallArgument {
|
|
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
|
|
let Self { name, ty } = self;
|
|
tokens.extend(quote!(#name: #ty))
|
|
}
|
|
}
|
|
|
|
impl ToTokens for SyscallDefinition {
|
|
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
|
|
let Self {
|
|
attributes,
|
|
name,
|
|
arguments,
|
|
return_type,
|
|
} = self;
|
|
let return_type = return_type.as_ref().map(|ty| quote!(-> #ty));
|
|
tokens.extend(quote! {
|
|
#attributes
|
|
syscall #name (#arguments) #return_type;
|
|
});
|
|
}
|
|
}
|