From ef38892cb0c8245d65a07518e080849795016755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Sat, 20 Feb 2021 21:42:25 +0100 Subject: cool linky macro --- Cargo.lock | 1 - progs/tests/simple.sy | 4 +-- src/linked.rs | 18 ----------- src/main.rs | 33 +++++++------------- sylt_macro/Cargo.toml | 1 - sylt_macro/src/lib.rs | 85 ++++++++++++++++++++++++++++++++------------------- 6 files changed, 67 insertions(+), 75 deletions(-) delete mode 100644 src/linked.rs diff --git a/Cargo.lock b/Cargo.lock index 44e16d0..f7d2ec1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -531,7 +531,6 @@ dependencies = [ name = "sylt_macro" version = "0.1.0" dependencies = [ - "lazy_static", "quote", "syn", ] 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/linked.rs b/src/linked.rs deleted file mode 100644 index 6d6621c..0000000 --- a/src/linked.rs +++ /dev/null @@ -1,18 +0,0 @@ -#[sylt_macro::extern_link] -pub fn f(x: sylt::Value, _typecheck: bool) -> Result { - Ok(x) -} - -#[sylt_macro::extern_link(g)] -pub fn f2(x: sylt::Value, _typecheck: bool) -> Result { - Ok(x) -} - -mod m1 { - mod m2 { - #[sylt_macro::extern_link(h)] - pub fn f2(x: sylt::Value, _typecheck: bool) -> Result { - Ok(x) - } - } -} diff --git a/src/main.rs b/src/main.rs index 21785a2..28e4e79 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,36 +2,15 @@ use std::path::{Path, PathBuf}; use sylt::run_file; -mod linked; - struct Args { file: Option, print: bool, } -macro_rules! link { - ([ $( $ident:tt ),* ]) => { - vec![ - $( (stringify!($ident).to_string(), $ident), )* - ] - } -} - -sylt_macro::extern_function!( - extern_test - [sylt::Value::Float(x), sylt::Value::Float(y)] -> sylt::Type::Float => { - Ok(sylt::Value::Float(x + y)) - }, - [sylt::Value::Float(x)] -> sylt::Type::Float => { - Ok(sylt::Value::Float(*x)) - }, -); - fn main() { let args = parse_args(); let file = args.file.unwrap_or_else(|| Path::new("progs/tests/simple.sy").to_owned()); - println!("{:?}", sylt_macro::links!()); - let errs = match run_file(&file, args.print, vec![]) { + let errs = match run_file(&file, args.print, sylt_macro::link!(extern_test as test)) { Err(it) => it, _ => return, }; @@ -59,3 +38,13 @@ fn parse_args() -> Args { }; args } + +sylt_macro::extern_function!( + extern_test + [sylt::Value::Float(x), sylt::Value::Float(y)] -> sylt::Type::Float => { + Ok(sylt::Value::Float(x + y)) + }, + [sylt::Value::Float(x)] -> sylt::Type::Float => { + Ok(sylt::Value::Float(*x)) + }, +); diff --git a/sylt_macro/Cargo.toml b/sylt_macro/Cargo.toml index 04ae39d..9ac045e 100644 --- a/sylt_macro/Cargo.toml +++ b/sylt_macro/Cargo.toml @@ -12,4 +12,3 @@ proc-macro = true [dependencies] syn = { version = "1.0", features=["full"] } quote = "1.0" -lazy_static = "1.4" diff --git a/sylt_macro/src/lib.rs b/sylt_macro/src/lib.rs index 39a62bf..3b8b37c 100644 --- a/sylt_macro/src/lib.rs +++ b/sylt_macro/src/lib.rs @@ -1,7 +1,5 @@ -use lazy_static::lazy_static; use proc_macro::TokenStream; use quote::quote; -use std::{borrow::Cow, sync::Mutex}; use syn::{Expr, Pat, Token, parse::{Parse, ParseStream, Result}, parse_macro_input}; struct ExternBlock { @@ -66,7 +64,6 @@ pub fn extern_function(tokens: TokenStream) -> TokenStream { }).collect(); let tokens = quote! { - #[sylt_macro::extern_link] pub fn #function ( __values: &[sylt::Value], __typecheck: bool @@ -95,44 +92,70 @@ pub fn extern_function(tokens: TokenStream) -> TokenStream { TokenStream::from(tokens) } -lazy_static! { - static ref LINKED_FUNCTIONS: Mutex> = Mutex::new(Vec::new()); +struct LinkRename { + _as: Token![as], + name: syn::Ident, } -#[proc_macro_attribute] -pub fn extern_link(attr: TokenStream, tokens: TokenStream) -> TokenStream { - let parsed: syn::ItemFn = parse_macro_input!(tokens); +impl Parse for LinkRename { + fn parse(input: ParseStream) -> Result { + Ok(Self { + _as: input.parse()?, + name: input.parse()?, + }) + } +} - let name = if attr.is_empty() { - Cow::Borrowed(&parsed.sig.ident) - } else { - let attr: syn::Ident = parse_macro_input!(attr); - Cow::Owned(attr) - }; +struct Link { + path: syn::Path, + rename: Option, +} - let tokens = quote! { - #parsed - }; - LINKED_FUNCTIONS.lock().unwrap().push((name.to_string(), name.to_string())); - TokenStream::from(tokens) +impl Parse for Link { + fn parse(input: ParseStream) -> Result { + Ok(Self { + path: input.parse()?, + rename: input.parse().ok(), + }) + } +} + +struct Links { + links: Vec, } +impl Parse for Links { + fn parse(input: ParseStream) -> Result { + let mut res = Self { + links: Vec::new(), + }; + while !input.is_empty() { + res.links.push(input.parse()?); + let _comma: Option = input.parse().ok(); + } + Ok(res) + } +} + + #[proc_macro] -pub fn links(tokens: TokenStream) -> TokenStream { - assert!(tokens.is_empty()); +pub fn link(tokens: TokenStream) -> TokenStream { + let links: Links = parse_macro_input!(tokens); - let linked_functions: Vec<_> = LINKED_FUNCTIONS - .lock() - .unwrap() - .iter() - .map(|(name, path)| format!("({}, {})", name, path)) - .collect(); + 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! { - (|| { - let ret: Vec<&str> = vec![ #(#linked_functions),* ]; - ret - })() + vec![ #(#links),* ] }; TokenStream::from(tokens) } -- cgit v1.2.1