diff options
| author | Gustav Sörnäs <gustav@sornas.net> | 2021-02-26 17:50:53 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-26 17:50:53 +0100 |
| commit | 21b70835bfbc6b8a9c1099bb4a618f1cd457aac0 (patch) | |
| tree | 58d3a61762c85e4165af1dbd2dbafa6efdec6e9c /sylt_macro/src | |
| parent | 701c38433454d5afd833bb94723ab2e1f4bbe9bd (diff) | |
| parent | cab32da3a8f4b4e25e1d1f287315fe75256ecc89 (diff) | |
| download | sylt-21b70835bfbc6b8a9c1099bb4a618f1cd457aac0.tar.gz | |
Merge branch 'compiler-rewrite' into breaking-into-sections
Diffstat (limited to 'sylt_macro/src')
| -rw-r--r-- | sylt_macro/src/lib.rs | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/sylt_macro/src/lib.rs b/sylt_macro/src/lib.rs index fc43b5c..3b8b37c 100644 --- a/sylt_macro/src/lib.rs +++ b/sylt_macro/src/lib.rs @@ -73,15 +73,89 @@ pub fn extern_function(tokens: TokenStream) -> TokenStream { #[allow(unused_variables)] match __values { #(#typecheck_blocks),* - _ => Err(sylt::error::ErrorKind::ExternTypeMismatch(stringify!(#function).to_string(), __values.iter().map(|v| sylt::Type::from(v)).collect())) + _ => Err(sylt::error::ErrorKind::ExternTypeMismatch( + stringify!(#function).to_string(), + __values.iter().map(|v| sylt::Type::from(v)).collect() + )) } } else { match __values { #(#eval_blocks),* - _ => Err(sylt::error::ErrorKind::ExternTypeMismatch(stringify!(#function).to_string(), __values.iter().map(|v| sylt::Type::from(v)).collect())) + _ => Err(sylt::error::ErrorKind::ExternTypeMismatch( + stringify!(#function).to_string(), + __values.iter().map(|v| sylt::Type::from(v)).collect() + )) } } } }; TokenStream::from(tokens) } + +struct LinkRename { + _as: Token![as], + name: syn::Ident, +} + +impl Parse for LinkRename { + fn parse(input: ParseStream) -> Result<Self> { + Ok(Self { + _as: input.parse()?, + name: input.parse()?, + }) + } +} + +struct Link { + path: syn::Path, + rename: Option<LinkRename>, +} + +impl Parse for Link { + fn parse(input: ParseStream) -> Result<Self> { + Ok(Self { + path: input.parse()?, + rename: input.parse().ok(), + }) + } +} + +struct Links { + links: Vec<Link>, +} + +impl Parse for Links { + fn parse(input: ParseStream) -> Result<Self> { + let mut res = Self { + links: Vec::new(), + }; + while !input.is_empty() { + res.links.push(input.parse()?); + let _comma: Option<Token![,]> = input.parse().ok(); + } + Ok(res) + } +} + + +#[proc_macro] +pub fn link(tokens: TokenStream) -> TokenStream { + let links: Links = parse_macro_input!(tokens); + + let links: Vec<_> = links.links.iter().map(|link| { + let name = if let Some(rename) = &link.rename { + &rename.name + } else { + &link.path.segments.last().unwrap().ident + }; + let path = &link.path; + quote! { + (stringify!(#name).to_string(), #path) + } + }).collect(); + + let tokens = quote! { + vec![ #(#links),* ] + }; + TokenStream::from(tokens) +} |
