aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--progs/tests/simple.sy4
-rw-r--r--src/linked.rs18
-rw-r--r--src/main.rs33
-rw-r--r--sylt_macro/Cargo.toml1
-rw-r--r--sylt_macro/src/lib.rs85
6 files changed, 67 insertions, 75 deletions
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<sylt::Value, sylt::error::ErrorKind> {
- Ok(x)
-}
-
-#[sylt_macro::extern_link(g)]
-pub fn f2(x: sylt::Value, _typecheck: bool) -> Result<sylt::Value, sylt::error::ErrorKind> {
- Ok(x)
-}
-
-mod m1 {
- mod m2 {
- #[sylt_macro::extern_link(h)]
- pub fn f2(x: sylt::Value, _typecheck: bool) -> Result<sylt::Value, sylt::error::ErrorKind> {
- 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<PathBuf>,
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<Vec<(String, String)>> = 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<Self> {
+ 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<LinkRename>,
+}
- 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<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 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)
}