aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-02-20 20:30:58 +0100
committerGustav Sörnäs <gustav@sornas.net>2021-02-20 20:30:58 +0100
commit6e97e9667967f90c66ff71f2c5468d5700887f24 (patch)
treeab8cb0ad26597891f421a8c6f8883479af8ad37f
parent2245aa052c4b4e3db841a68afc986838f4330f4e (diff)
downloadsylt-6e97e9667967f90c66ff71f2c5468d5700887f24.tar.gz
store linked functions in proc macro runtime and return them
-rw-r--r--src/linked.rs18
-rw-r--r--src/main.rs44
-rw-r--r--sylt_macro/src/lib.rs26
3 files changed, 54 insertions, 34 deletions
diff --git a/src/linked.rs b/src/linked.rs
new file mode 100644
index 0000000..6d6621c
--- /dev/null
+++ b/src/linked.rs
@@ -0,0 +1,18 @@
+#[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 69af682..21785a2 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,6 +2,8 @@ use std::path::{Path, PathBuf};
use sylt::run_file;
+mod linked;
+
struct Args {
file: Option<PathBuf>,
print: bool,
@@ -15,10 +17,21 @@ macro_rules! link {
}
}
+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());
- let errs = match run_file(&file, args.print, link!([extern_test])) {
+ println!("{:?}", sylt_macro::links!());
+ let errs = match run_file(&file, args.print, vec![]) {
Err(it) => it,
_ => return,
};
@@ -46,32 +59,3 @@ fn parse_args() -> Args {
};
args
}
-
-#[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)
- }
- }
-}
-
-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/src/lib.rs b/sylt_macro/src/lib.rs
index e4b9d36..39a62bf 100644
--- a/sylt_macro/src/lib.rs
+++ b/sylt_macro/src/lib.rs
@@ -1,7 +1,7 @@
use lazy_static::lazy_static;
use proc_macro::TokenStream;
use quote::quote;
-use std::borrow::Cow;
+use std::{borrow::Cow, sync::Mutex};
use syn::{Expr, Pat, Token, parse::{Parse, ParseStream, Result}, parse_macro_input};
struct ExternBlock {
@@ -66,6 +66,7 @@ pub fn extern_function(tokens: TokenStream) -> TokenStream {
}).collect();
let tokens = quote! {
+ #[sylt_macro::extern_link]
pub fn #function (
__values: &[sylt::Value],
__typecheck: bool
@@ -94,10 +95,8 @@ pub fn extern_function(tokens: TokenStream) -> TokenStream {
TokenStream::from(tokens)
}
-type RustFunction = fn(&[Value], bool) -> Result<Value, ErrorKind>;
-
lazy_static! {
- static ref LINKED_FUNCTIONS: Mutex<Vec<(String, )>>
+ static ref LINKED_FUNCTIONS: Mutex<Vec<(String, String)>> = Mutex::new(Vec::new());
}
#[proc_macro_attribute]
@@ -113,8 +112,27 @@ pub fn extern_link(attr: TokenStream, tokens: TokenStream) -> TokenStream {
let tokens = quote! {
#parsed
+ };
+ LINKED_FUNCTIONS.lock().unwrap().push((name.to_string(), name.to_string()));
+ TokenStream::from(tokens)
+}
+#[proc_macro]
+pub fn links(tokens: TokenStream) -> TokenStream {
+ assert!(tokens.is_empty());
+
+ let linked_functions: Vec<_> = LINKED_FUNCTIONS
+ .lock()
+ .unwrap()
+ .iter()
+ .map(|(name, path)| format!("({}, {})", name, path))
+ .collect();
+ let tokens = quote! {
+ (|| {
+ let ret: Vec<&str> = vec![ #(#linked_functions),* ];
+ ret
+ })()
};
TokenStream::from(tokens)
}