Function like macro with multiple arguments

Hello,

I'm trying to make a macro,

extern crate proc_macro;
use proc_macro::TokenStream;

#[proc_macro]
pub fn add(args: TokenStream) -> TokenStream {
    format!("{} + {}", args[0], args[1]).parse().unwrap()
}

It needs to be function-like, and I need to access the nth parameter, is there a way to do that?

1 Like

You'll have to decide what kind of syntax you're parsing between the commas in the input first.

syn is useful for parsing proc macro input without too much work.

1 Like

Sorry for getting back so late; what would be the appropriate syn call to make here?

Something like

use proc_macro::TokenStream;
use proc_macro2::Literal;
use quote::{quote, ToTokens};
use syn::{parse::Parse, parse_macro_input, punctuated::Punctuated, Expr, Token};

struct MacroInput {
    a: Expr,
    comma: Token![,],
    b: Expr,
}

impl Parse for MacroInput {
    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
        Ok(Self {
            a: input.parse()?,
            comma: input.parse()?,
            b: input.parse()?,
        })
    }
}

#[proc_macro]
pub fn add(tokens: TokenStream) -> TokenStream {
    let input = parse_macro_input!(tokens as MacroInput);

    let a = &input.a;
    let b = &input.b;

    quote! {
        #a + #b
    }
    .into()
}

for the case of two inputs. If you want variable number of inputs you could use Punctuated instead.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.