From a1015ba1d7c2228224847f1931118da473815de3 Mon Sep 17 00:00:00 2001 From: Griffin Smith Date: Sun, 6 Nov 2022 10:28:34 -0500 Subject: feat(tvix/eval): Give names to builtin arguments Refactor the arguments of a Builtin to be a vec of a new BuiltinArgument struct, which contains the old strictness boolean and also a static `name` str - this is automatically determined via the ident for the corresponding function argument in the proc-macro case, and passed in in the cases where we're still manually calling Builtin::new. Currently this name is unused, but in the future this can be used as part of a documentation system for builtins. Change-Id: Ib9dadb15b69bf8c9ea1983a4f4f197294a2394a6 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7204 Reviewed-by: tazjin Tested-by: BuildkiteCI --- tvix/eval/builtin-macros/src/lib.rs | 65 +++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 20 deletions(-) (limited to 'tvix/eval/builtin-macros') diff --git a/tvix/eval/builtin-macros/src/lib.rs b/tvix/eval/builtin-macros/src/lib.rs index 8e2c4b3f8776..8276e421c5d8 100644 --- a/tvix/eval/builtin-macros/src/lib.rs +++ b/tvix/eval/builtin-macros/src/lib.rs @@ -5,7 +5,9 @@ use proc_macro2::Span; use quote::{quote_spanned, ToTokens}; use syn::parse::Parse; use syn::spanned::Spanned; -use syn::{parse_macro_input, parse_quote, FnArg, Ident, Item, ItemMod, LitStr, PatType}; +use syn::{ + parse_macro_input, parse_quote, FnArg, Ident, Item, ItemMod, LitStr, Pat, PatIdent, PatType, +}; struct BuiltinArgs { name: LitStr, @@ -89,31 +91,54 @@ pub fn builtins(_args: TokenStream, item: TokenStream) -> TokenStream { .into(); } - let strictness = f + let builtin_arguments = f .sig .inputs .iter_mut() .skip(1) - .map(|input| { - let mut lazy = false; - if let FnArg::Typed(PatType { attrs, .. }) = input { - attrs.retain(|attr| { - attr.path.get_ident().into_iter().any(|id| { - if id == "lazy" { - lazy = true; - false - } else { - true - } - }) - }); - } - !lazy + .map(|arg| { + let mut strict = true; + let name = match arg { + FnArg::Receiver(_) => { + return Err(quote_spanned!(arg.span() => { + compile_error!("Unexpected receiver argument in builtin") + })) + } + FnArg::Typed(PatType { attrs, pat, .. }) => { + attrs.retain(|attr| { + attr.path.get_ident().into_iter().any(|id| { + if id == "lazy" { + strict = false; + false + } else { + true + } + }) + }); + match pat.as_ref() { + Pat::Ident(PatIdent { ident, .. }) => ident.to_string(), + _ => "unknown".to_string(), + } + } + }; + + Ok(quote_spanned!(arg.span() => { + crate::internal::BuiltinArgument { + strict: #strict, + name: #name, + } + })) }) - .collect::>(); + .collect::, _>>(); + + let builtin_arguments = match builtin_arguments { + Ok(args) => args, + Err(err) => return err.into(), + }; let fn_name = f.sig.ident.clone(); - let args = (0..(f.sig.inputs.len() - 1)) + let num_args = f.sig.inputs.len() - 1; + let args = (0..num_args) .map(|n| Ident::new(&format!("arg_{n}"), Span::call_site())) .collect::>(); let mut reversed_args = args.clone(); @@ -122,7 +147,7 @@ pub fn builtins(_args: TokenStream, item: TokenStream) -> TokenStream { builtins.push(quote_spanned! { builtin_attr.span() => { crate::internal::Builtin::new( #name, - &[#(#strictness),*], + &[#(#builtin_arguments),*], |mut args: Vec, vm: &mut crate::internal::VM| { #(let #reversed_args = args.pop().unwrap();)* #fn_name(vm, #(#args),*) -- cgit 1.4.1