diff options
Diffstat (limited to 'guests_macro')
| -rw-r--r-- | guests_macro/src/lib.rs | 12 | ||||
| -rw-r--r-- | guests_macro/src/parse_fn.rs | 114 |
2 files changed, 82 insertions, 44 deletions
diff --git a/guests_macro/src/lib.rs b/guests_macro/src/lib.rs index 30bfec7..2a35292 100644 --- a/guests_macro/src/lib.rs +++ b/guests_macro/src/lib.rs @@ -1,5 +1,5 @@ -use std::{ fs::File, io::Write }; use proc_macro::TokenStream; +use std::{fs::File, io::Write}; mod parse_fn; /// Create an `entrypoint_expr` macro inside the guest program. This will be @@ -45,11 +45,17 @@ pub fn proving_entrypoint(_: TokenStream, mut item: TokenStream) -> TokenStream writeln!(output, "{}", &format!("{args}").replace('\n', " ")); write!(output, "{}", &format!("{ret}").replace('\n', " ")); - item.extend(format!("#[macro_export] + item.extend( + format!( + "#[macro_export] macro_rules! entrypoint_expr {{ () => {{ make_wrapper!{{{}{} -> {}}} }}; - }}", name, args, ret).parse::<TokenStream>()); + }}", + name, args, ret + ) + .parse::<TokenStream>(), + ); item } diff --git a/guests_macro/src/parse_fn.rs b/guests_macro/src/parse_fn.rs index 87b0073..2db81fa 100644 --- a/guests_macro/src/parse_fn.rs +++ b/guests_macro/src/parse_fn.rs @@ -5,7 +5,7 @@ //! Therefore, it should be used in ZKVM wrapper_macro crates, via a [mod path //! attribute](https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute). -use proc_macro::{ TokenStream, TokenTree, Delimiter, Spacing, Group }; +use proc_macro::{Delimiter, Group, Spacing, TokenStream, TokenTree}; /// Split function definition into triplet of name, arguments and output types. /// @@ -16,7 +16,7 @@ pub fn split_fn(item: &TokenStream) -> (TokenStream, TokenStream, TokenStream) { let mut name = TokenStream::new(); let mut args = TokenStream::new(); - let mut ret = TokenStream::new(); + let mut ret = TokenStream::new(); let mut out: &mut TokenStream = &mut name; for tt in item { @@ -27,7 +27,7 @@ pub fn split_fn(item: &TokenStream) -> (TokenStream, TokenStream, TokenStream) { if ident.to_string() == "fn" || ident.to_string() == "pub" { continue; } - }, + } TokenTree::Punct(ref punct) => { if punct.as_char() == '-' { out = &mut ret; @@ -36,15 +36,15 @@ pub fn split_fn(item: &TokenStream) -> (TokenStream, TokenStream, TokenStream) { if punct.as_char() == '>' && out.is_empty() { continue; } - }, + } TokenTree::Group(ref group) => { if group.delimiter() == Delimiter::Brace { break; } - if ! out.is_empty() { + if !out.is_empty() { out = &mut args; } - }, + } TokenTree::Literal(_) => unreachable!("Cannot have literal inside def!"), } out.extend([tt].into_iter()); @@ -62,8 +62,7 @@ pub fn args_split(item: &TokenStream) -> Vec<TokenStream> { let contents; if let TokenTree::Group(group) = item.clone().into_iter().next().unwrap() { contents = group.stream().into_iter(); - } - else { + } else { unreachable!("Item passed to args_split is not a group: \"{item}\""); } @@ -74,25 +73,27 @@ pub fn args_split(item: &TokenStream) -> Vec<TokenStream> { for tt in contents { match tt { TokenTree::Punct(ref punct) => match punct.as_char() { - // < and > do **not** form TokenTree groups, however their - // usage is like that of a group. Hence, we need extra - // logic to skip them. - '<' => angle_level += 1, - '>' => angle_level -= 1, - ',' => if angle_level == 0 { + // < and > do **not** form TokenTree groups, however their + // usage is like that of a group. Hence, we need extra + // logic to skip them. + '<' => angle_level += 1, + '>' => angle_level -= 1, + ',' => { + if angle_level == 0 { args.push(ts); ts = TokenStream::new(); continue; - }, - _ => {}, - }, - _ => {}, + } + } + _ => {} + }, + _ => {} } ts.extend([tt].into_iter()); } - if ! ts.is_empty() { + if !ts.is_empty() { args.push(ts); } args @@ -105,7 +106,10 @@ pub fn args_split(item: &TokenStream) -> Vec<TokenStream> { /// /// **Input:** "(p1 : t1, p2: t2, ...)", vec!["p3", "p4", ...] /// **Output:** vec!["p1 : t1", "p2: t2", ...], vec!["p3 : t3", "p4: t4", ...] -pub fn args_split_public(item: &TokenStream, public: &Vec<&String>) -> (Vec<TokenStream>, Vec<TokenStream>) { +pub fn args_split_public( + item: &TokenStream, + public: &Vec<&String>, +) -> (Vec<TokenStream>, Vec<TokenStream>) { let all_args = args_split(item); let public_args: Vec<TokenStream> = all_args .clone() @@ -114,7 +118,11 @@ pub fn args_split_public(item: &TokenStream, public: &Vec<&String>) -> (Vec<Toke .collect(); let private_args: Vec<TokenStream> = all_args .into_iter() - .filter(|t| !public_args.iter().any(|pt| *t.to_string() == pt.to_string())) + .filter(|t| { + !public_args + .iter() + .any(|pt| *t.to_string() == pt.to_string()) + }) .collect(); (public_args, private_args) } @@ -128,8 +136,7 @@ pub fn args_divide(item: &TokenStream) -> (Vec<TokenStream>, Vec<TokenStream>) { let contents; if let TokenTree::Group(group) = item.clone().into_iter().next().unwrap() { contents = group.stream().into_iter(); - } - else { + } else { unreachable!("Item passed to args_divide is not a group: \"{item}\""); } @@ -145,8 +152,7 @@ pub fn args_divide(item: &TokenStream) -> (Vec<TokenStream>, Vec<TokenStream>) { // Ignore "::" if punct.spacing() == Spacing::Joint && punct.as_char() == ':' { ignore_next = true; - } - else if !ignore_next { + } else if !ignore_next { match punct.as_char() { // < and > do **not** form TokenTree groups, however their // usage is like that of a group. Hence, we need extra @@ -157,20 +163,21 @@ pub fn args_divide(item: &TokenStream) -> (Vec<TokenStream>, Vec<TokenStream>) { patterns.push(ts); ts = TokenStream::new(); continue; - }, - ',' => if angle_level == 0 { - types.push(ts); - ts = TokenStream::new(); - continue; - }, - _ => {}, + } + ',' => { + if angle_level == 0 { + types.push(ts); + ts = TokenStream::new(); + continue; + } + } + _ => {} } - } - else { + } else { ignore_next = false; } - }, - _ => {}, + } + _ => {} } ts.extend([tt].into_iter()); @@ -187,7 +194,13 @@ pub fn args_divide(item: &TokenStream) -> (Vec<TokenStream>, Vec<TokenStream>) { /// /// **Input:** "(p1 : t1, p2: t2, ...)", vec!["p3", "p4", ...] /// **Output:** (vec!["p1", "p2", ...], vec!["t1", "t2", ...]), (vec!["p3", "p4", ...], vec!["t3", "t4", ...]) -pub fn args_divide_public(item: &TokenStream, public: &Vec<&String>) -> ((Vec<TokenStream>, Vec<TokenStream>), (Vec<TokenStream>, Vec<TokenStream>)) { +pub fn args_divide_public( + item: &TokenStream, + public: &Vec<&String>, +) -> ( + (Vec<TokenStream>, Vec<TokenStream>), + (Vec<TokenStream>, Vec<TokenStream>), +) { let (patterns, types) = args_divide(item); let (public_patterns, public_types): (Vec<TokenStream>, Vec<TokenStream>) = patterns @@ -200,9 +213,16 @@ pub fn args_divide_public(item: &TokenStream, public: &Vec<&String>) -> ((Vec<To let (private_patterns, private_types): (Vec<TokenStream>, Vec<TokenStream>) = patterns .into_iter() .zip(types.into_iter()) - .filter(|(p, _)| !public_patterns.iter().any(|x| p.to_string() == x.to_string())) + .filter(|(p, _)| { + !public_patterns + .iter() + .any(|x| p.to_string() == x.to_string()) + }) .unzip(); - ((public_patterns, public_types), (private_patterns, private_types)) + ( + (public_patterns, public_types), + (private_patterns, private_types), + ) } /// Like `args_divide`, but group arguments and types (via `group_streams`). @@ -220,10 +240,22 @@ pub fn args_divide_grouped(item: &TokenStream) -> (TokenStream, TokenStream) { /// **Output:** "(p1, p2, ...)" pub fn group_streams(patterns: &Vec<TokenStream>) -> TokenStream { let mut inner_ts = TokenStream::new(); - inner_ts.extend(patterns.clone().into_iter().flat_map(|i| [",".parse().unwrap(), i]).skip(1)); + inner_ts.extend( + patterns + .clone() + .into_iter() + .flat_map(|i| [",".parse().unwrap(), i]) + .skip(1), + ); let mut out = TokenStream::new(); - out.extend([TokenTree::Group(Group::new(Delimiter::Parenthesis, inner_ts))].into_iter()); + out.extend( + [TokenTree::Group(Group::new( + Delimiter::Parenthesis, + inner_ts, + ))] + .into_iter(), + ); out } |
