diff options
| author | Gustav Sörnäs <gustav@sornas.net> | 2021-02-22 11:39:42 +0100 |
|---|---|---|
| committer | Gustav Sörnäs <gustav@sornas.net> | 2021-02-22 11:39:42 +0100 |
| commit | 5449818b0975341e03720a450eec877453dee7c4 (patch) | |
| tree | b6df2df8fee78972f9a1fd3578a4f8a643bc614e | |
| parent | 3715433024e2df742a6ad16488ab2a580e397b86 (diff) | |
| download | sylt-5449818b0975341e03720a450eec877453dee7c4.tar.gz | |
Squash-merge remote tracking branch 'origin/automatic-link'
| -rw-r--r-- | progs/tests/simple.sy | 4 | ||||
| -rw-r--r-- | src/main.rs | 2 | ||||
| -rw-r--r-- | sylt_macro/src/lib.rs | 78 |
3 files changed, 79 insertions, 5 deletions
diff --git a/progs/tests/simple.sy b/progs/tests/simple.sy index 12a43c0..48394d7 100644 --- a/progs/tests/simple.sy +++ b/progs/tests/simple.sy @@ -1,2 +1,2 @@ -print extern_test(3.0) -print extern_test(3.0, 4.0, 5.0) +print test(3.0) +print test(3.0, 4.0) diff --git a/src/main.rs b/src/main.rs index bc68d40..28e4e79 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ struct Args { fn main() { let args = parse_args(); let file = args.file.unwrap_or_else(|| Path::new("progs/tests/simple.sy").to_owned()); - let errs = match run_file(&file, args.print, vec![(String::from("extern_test"), extern_test)]) { + let errs = match run_file(&file, args.print, sylt_macro::link!(extern_test as test)) { Err(it) => it, _ => return, }; 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) +} |
