Initial commit of syndicate-macros crate, still incomplete
This commit is contained in:
parent
4f30faa1ba
commit
f0205f06ca
|
@ -1302,6 +1302,16 @@ dependencies = [
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syndicate-macros"
|
||||||
|
version = "0.2.0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"syndicate",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syndicate-server"
|
name = "syndicate-server"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -1309,6 +1319,7 @@ dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"structopt",
|
"structopt",
|
||||||
"syndicate",
|
"syndicate",
|
||||||
|
"syndicate-macros",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-tungstenite",
|
"tokio-tungstenite",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"syndicate",
|
"syndicate",
|
||||||
|
"syndicate-macros",
|
||||||
"syndicate-server",
|
"syndicate-server",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
[package]
|
||||||
|
name = "syndicate-macros"
|
||||||
|
version = "0.2.0"
|
||||||
|
authors = ["Tony Garnock-Jones <tonyg@leastfixedpoint.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
syndicate = { path = "../syndicate", version = "^0.2.0" }
|
||||||
|
|
||||||
|
proc-macro2 = "^1.0"
|
||||||
|
quote = "^1.0"
|
||||||
|
syn = "^1.0"
|
|
@ -0,0 +1,112 @@
|
||||||
|
use syndicate::value::IOValue;
|
||||||
|
use syndicate::value::NestedValue;
|
||||||
|
use syndicate::value::Value;
|
||||||
|
use syndicate::value::text::iovalue_from_str;
|
||||||
|
|
||||||
|
extern crate proc_macro;
|
||||||
|
use proc_macro::Span;
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
|
||||||
|
use quote::ToTokens;
|
||||||
|
use quote::quote;
|
||||||
|
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
use syn::parse_macro_input;
|
||||||
|
use syn::ExprLit;
|
||||||
|
use syn::Ident;
|
||||||
|
use syn::Lit;
|
||||||
|
use syn::LitByteStr;
|
||||||
|
|
||||||
|
fn lit<T: ToTokens>(e: T) -> TokenStream {
|
||||||
|
quote!(
|
||||||
|
syndicate::schemas::dataspace_patterns::Pattern::DLit(Box::new(
|
||||||
|
syndicate::schemas::dataspace_patterns::DLit { value: #e }))).into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compile_pattern(v: &IOValue) -> TokenStream {
|
||||||
|
match v.value() {
|
||||||
|
Value::Boolean(b) => lit(quote!(syndicate::value::Value::from(#b).wrap())),
|
||||||
|
Value::Float(f) => {
|
||||||
|
let f = f.0;
|
||||||
|
lit(quote!(syndicate::value::Value::from(#f).wrap()))
|
||||||
|
}
|
||||||
|
Value::Double(d) => {
|
||||||
|
let d = d.0;
|
||||||
|
lit(quote!(syndicate::value::Value::from(#d).wrap()))
|
||||||
|
}
|
||||||
|
Value::SignedInteger(i) => {
|
||||||
|
let i = i128::try_from(i).expect("Literal integer out-of-range");
|
||||||
|
lit(quote!(syndicate::value::Value::from(#i).wrap()))
|
||||||
|
}
|
||||||
|
Value::String(s) => lit(quote!(syndicate::value::Value::from(#s).wrap())),
|
||||||
|
Value::ByteString(bs) => {
|
||||||
|
let bs = LitByteStr::new(bs, Span::call_site().into());
|
||||||
|
lit(quote!(syndicate::value::Value::from(#bs).wrap()))
|
||||||
|
}
|
||||||
|
Value::Symbol(s) => match s.as_str() {
|
||||||
|
"$" => quote!(
|
||||||
|
syndicate::schemas::dataspace_patterns::Pattern::DBind(Box::new(
|
||||||
|
syndicate::schemas::dataspace_patterns::DBind {
|
||||||
|
pattern: syndicate::schemas::dataspace_patterns::Pattern::DDiscard(Box::new(
|
||||||
|
syndicate::schemas::dataspace_patterns::DDiscard))
|
||||||
|
}))).into(),
|
||||||
|
"_" => quote!(
|
||||||
|
syndicate::schemas::dataspace_patterns::Pattern::DDiscard(Box::new(
|
||||||
|
syndicate::schemas::dataspace_patterns::DDiscard))).into(),
|
||||||
|
_ => if s.starts_with("=") {
|
||||||
|
let id = Ident::new(&s[1..], Span::call_site().into());
|
||||||
|
lit(quote!(#id))
|
||||||
|
} else {
|
||||||
|
// let s = LitStr::new(s, Span::call_site().into());
|
||||||
|
lit(quote!(syndicate::value::Value::symbol(#s).wrap()))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Value::Record(r) => {
|
||||||
|
let arity = r.arity() as u128;
|
||||||
|
match r.label().value().as_symbol() {
|
||||||
|
None => panic!("Record labels in patterns must be symbols"),
|
||||||
|
Some(label) => {
|
||||||
|
let mut i = 0;
|
||||||
|
let members = r.fields().iter().map(
|
||||||
|
|f| {
|
||||||
|
let p: proc_macro2::TokenStream = compile_pattern(f).into();
|
||||||
|
let result = quote!((#i .into(), #p));
|
||||||
|
i += 1;
|
||||||
|
result
|
||||||
|
}).collect::<Vec<_>>();
|
||||||
|
quote!(
|
||||||
|
syndicate::schemas::dataspace_patterns::Pattern::DCompound(Box::new(
|
||||||
|
syndicate::schemas::dataspace_patterns::DCompound::Rec {
|
||||||
|
ctor: Box::new(syndicate::schemas::dataspace_patterns::CRec {
|
||||||
|
label: syndicate::value::Value::symbol(#label).wrap(),
|
||||||
|
arity: #arity .into(),
|
||||||
|
}),
|
||||||
|
members: syndicate::value::Map::from_iter(vec![#(#members),*])
|
||||||
|
}))).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Value::Sequence(vs) => ,
|
||||||
|
// Value::Set(_) => panic!("Cannot match sets in patterns"),
|
||||||
|
// Value::Dictionary(d) => ,
|
||||||
|
// Value::Embedded(e) => panic!("aiee"),
|
||||||
|
_ => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn pattern(src: TokenStream) -> TokenStream {
|
||||||
|
if let Lit::Str(s) = parse_macro_input!(src as ExprLit).lit {
|
||||||
|
match iovalue_from_str(&s.value()) {
|
||||||
|
Ok(v) => {
|
||||||
|
let e = compile_pattern(&v);
|
||||||
|
// println!("{:#}", &e);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
Err(_) => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("Expected literal string containing the pattern and no more");
|
||||||
|
}
|
Loading…
Reference in New Issue