Allow variable labels in patterns (see pingpong.rs)

This commit is contained in:
Tony Garnock-Jones 2021-08-13 06:43:34 -04:00
parent 2255a54f1a
commit bb519b625b
2 changed files with 32 additions and 40 deletions

View File

@ -25,41 +25,39 @@ fn lit<T: ToTokens>(e: T) -> TokenStream {
} }
fn compile_pattern(v: &IOValue) -> TokenStream { fn compile_pattern(v: &IOValue) -> TokenStream {
#[allow(non_snake_case)]
let P_ = quote!(syndicate::schemas::dataspace_patterns);
#[allow(non_snake_case)]
let V_ = quote!(syndicate::value);
match v.value() { match v.value() {
Value::Boolean(b) => lit(quote!(syndicate::value::Value::from(#b).wrap())), Value::Boolean(b) => lit(quote!(#V_::Value::from(#b).wrap())),
Value::Float(f) => { Value::Float(f) => {
let f = f.0; let f = f.0;
lit(quote!(syndicate::value::Value::from(#f).wrap())) lit(quote!(#V_::Value::from(#f).wrap()))
} }
Value::Double(d) => { Value::Double(d) => {
let d = d.0; let d = d.0;
lit(quote!(syndicate::value::Value::from(#d).wrap())) lit(quote!(#V_::Value::from(#d).wrap()))
} }
Value::SignedInteger(i) => { Value::SignedInteger(i) => {
let i = i128::try_from(i).expect("Literal integer out-of-range"); let i = i128::try_from(i).expect("Literal integer out-of-range");
lit(quote!(syndicate::value::Value::from(#i).wrap())) lit(quote!(#V_::Value::from(#i).wrap()))
} }
Value::String(s) => lit(quote!(syndicate::value::Value::from(#s).wrap())), Value::String(s) => lit(quote!(#V_::Value::from(#s).wrap())),
Value::ByteString(bs) => { Value::ByteString(bs) => {
let bs = LitByteStr::new(bs, Span::call_site().into()); let bs = LitByteStr::new(bs, Span::call_site().into());
lit(quote!(syndicate::value::Value::from(#bs).wrap())) lit(quote!(#V_::Value::from(#bs).wrap()))
} }
Value::Symbol(s) => match s.as_str() { Value::Symbol(s) => match s.as_str() {
"$" => quote!( "$" => quote!(#P_::Pattern::DBind(Box::new(#P_::DBind {
syndicate::schemas::dataspace_patterns::Pattern::DBind(Box::new( pattern: #P_::Pattern::DDiscard(Box::new(#P_::DDiscard))
syndicate::schemas::dataspace_patterns::DBind { }))).into(),
pattern: syndicate::schemas::dataspace_patterns::Pattern::DDiscard(Box::new( "_" => quote!(#P_::Pattern::DDiscard(Box::new(#P_::DDiscard))).into(),
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("=") { _ => if s.starts_with("=") {
let id = Ident::new(&s[1..], Span::call_site().into()); lit(Ident::new(&s[1..], Span::call_site().into()))
lit(quote!(#id))
} else { } else {
// let s = LitStr::new(s, Span::call_site().into()); lit(quote!(#V_::Value::symbol(#s).wrap()))
lit(quote!(syndicate::value::Value::symbol(#s).wrap()))
}, },
} }
Value::Record(r) => { Value::Record(r) => {
@ -67,6 +65,12 @@ fn compile_pattern(v: &IOValue) -> TokenStream {
match r.label().value().as_symbol() { match r.label().value().as_symbol() {
None => panic!("Record labels in patterns must be symbols"), None => panic!("Record labels in patterns must be symbols"),
Some(label) => { Some(label) => {
let label_stx = if label.starts_with("=") {
let id = Ident::new(&label[1..], Span::call_site().into());
quote!(#id)
} else {
quote!(#V_::Value::symbol(#label).wrap())
};
let mut i = 0; let mut i = 0;
let members = r.fields().iter().map( let members = r.fields().iter().map(
|f| { |f| {
@ -76,13 +80,13 @@ fn compile_pattern(v: &IOValue) -> TokenStream {
result result
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
quote!( quote!(
syndicate::schemas::dataspace_patterns::Pattern::DCompound(Box::new( #P_::Pattern::DCompound(Box::new(
syndicate::schemas::dataspace_patterns::DCompound::Rec { #P_::DCompound::Rec {
ctor: Box::new(syndicate::schemas::dataspace_patterns::CRec { ctor: Box::new(#P_::CRec {
label: syndicate::value::Value::symbol(#label).wrap(), label: #label_stx,
arity: #arity .into(), arity: #arity .into(),
}), }),
members: syndicate::value::Map::from_iter(vec![#(#members),*]) members: #V_::Map::from_iter(vec![#(#members),*])
}))).into() }))).into()
} }
} }

View File

@ -7,9 +7,7 @@ use structopt::StructOpt;
use syndicate::actor::*; use syndicate::actor::*;
use syndicate::relay; use syndicate::relay;
use syndicate::schemas::dataspace::Observe; use syndicate::schemas::dataspace::Observe;
use syndicate::schemas::dataspace_patterns as p;
use syndicate::sturdy; use syndicate::sturdy;
use syndicate::value::Map;
use syndicate::value::NestedValue; use syndicate::value::NestedValue;
use syndicate::value::Value; use syndicate::value::Value;
@ -172,20 +170,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}; };
ds.assert(t, &Observe { ds.assert(t, &Observe {
pattern: p::Pattern::DCompound(Box::new(p::DCompound::Rec { pattern: {
ctor: Box::new(p::CRec { let recv_label = Value::symbol(recv_label).wrap();
label: Value::symbol(recv_label).wrap(), syndicate_macros::pattern!("<=recv_label $ $>")
arity: 2.into(), },
}),
members: Map::from_iter(vec![
(0.into(), p::Pattern::DBind(Box::new(p::DBind {
pattern: p::Pattern::DDiscard(Box::new(p::DDiscard)),
}))),
(1.into(), p::Pattern::DBind(Box::new(p::DBind {
pattern: p::Pattern::DDiscard(Box::new(p::DDiscard)),
}))),
].into_iter()),
})),
observer: Arc::clone(&consumer), observer: Arc::clone(&consumer),
}); });