aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-02-22 11:39:42 +0100
committerGustav Sörnäs <gustav@sornas.net>2021-02-22 11:39:42 +0100
commit5449818b0975341e03720a450eec877453dee7c4 (patch)
treeb6df2df8fee78972f9a1fd3578a4f8a643bc614e
parent3715433024e2df742a6ad16488ab2a580e397b86 (diff)
downloadsylt-5449818b0975341e03720a450eec877453dee7c4.tar.gz
Squash-merge remote tracking branch 'origin/automatic-link'
-rw-r--r--progs/tests/simple.sy4
-rw-r--r--src/main.rs2
-rw-r--r--sylt_macro/src/lib.rs78
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)
+}