diff options
| author | Gustav Sörnäs <gustav@sornas.net> | 2021-02-20 20:30:58 +0100 |
|---|---|---|
| committer | Gustav Sörnäs <gustav@sornas.net> | 2021-02-20 20:30:58 +0100 |
| commit | 6e97e9667967f90c66ff71f2c5468d5700887f24 (patch) | |
| tree | ab8cb0ad26597891f421a8c6f8883479af8ad37f | |
| parent | 2245aa052c4b4e3db841a68afc986838f4330f4e (diff) | |
| download | sylt-6e97e9667967f90c66ff71f2c5468d5700887f24.tar.gz | |
store linked functions in proc macro runtime and return them
| -rw-r--r-- | src/linked.rs | 18 | ||||
| -rw-r--r-- | src/main.rs | 44 | ||||
| -rw-r--r-- | sylt_macro/src/lib.rs | 26 |
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) } |
