Accommodate changes to dataspacePatterns
This commit is contained in:
parent
ea9e48cf31
commit
a831b02ca5
|
@ -170,11 +170,10 @@ fn compile_pattern(v: &IOValue) -> TokenStream {
|
||||||
lit(ValueCompiler::for_patterns().compile(v)),
|
lit(ValueCompiler::for_patterns().compile(v)),
|
||||||
}
|
}
|
||||||
Value::Record(r) => {
|
Value::Record(r) => {
|
||||||
let arity = r.arity() as u128;
|
|
||||||
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) =>
|
||||||
if label.starts_with("$") && arity == 1 {
|
if label.starts_with("$") && r.arity() == 1 {
|
||||||
let nested = compile_pattern(&r.fields()[0]);
|
let nested = compile_pattern(&r.fields()[0]);
|
||||||
quote!(#P_::Pattern::DBind(Box::new(#P_::DBind {
|
quote!(#P_::Pattern::DBind(Box::new(#P_::DBind {
|
||||||
pattern: #nested
|
pattern: #nested
|
||||||
|
@ -188,23 +187,16 @@ fn compile_pattern(v: &IOValue) -> TokenStream {
|
||||||
};
|
};
|
||||||
let members = compile_sequence_members(r.fields());
|
let members = compile_sequence_members(r.fields());
|
||||||
quote!(#P_::Pattern::DCompound(Box::new(#P_::DCompound::Rec {
|
quote!(#P_::Pattern::DCompound(Box::new(#P_::DCompound::Rec {
|
||||||
ctor: Box::new(#P_::CRec {
|
label: #label_stx,
|
||||||
label: #label_stx,
|
fields: vec![#(#members),*],
|
||||||
arity: #arity .into(),
|
|
||||||
}),
|
|
||||||
members: #MapFromIterator_(vec![#(#members),*])
|
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::Sequence(vs) => {
|
Value::Sequence(vs) => {
|
||||||
let arity = vs.len() as u128;
|
|
||||||
let members = compile_sequence_members(vs);
|
let members = compile_sequence_members(vs);
|
||||||
quote!(#P_::Pattern::DCompound(Box::new(#P_::DCompound::Arr {
|
quote!(#P_::Pattern::DCompound(Box::new(#P_::DCompound::Arr {
|
||||||
ctor: Box::new(#P_::CArr {
|
items: vec![#(#members),*],
|
||||||
arity: #arity .into(),
|
|
||||||
}),
|
|
||||||
members: #MapFromIterator_(vec![#(#members),*])
|
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
Value::Set(_) =>
|
Value::Set(_) =>
|
||||||
|
@ -216,8 +208,7 @@ fn compile_pattern(v: &IOValue) -> TokenStream {
|
||||||
quote!((#k, #v))
|
quote!((#k, #v))
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
quote!(#P_::Pattern::DCompound(Box::new(#P_::DCompound::Dict {
|
quote!(#P_::Pattern::DCompound(Box::new(#P_::DCompound::Dict {
|
||||||
ctor: Box::new(#P_::CDict),
|
entries: #MapFromIterator_(vec![#(#members),*])
|
||||||
members: #MapFromIterator_(vec![#(#members),*])
|
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
_ => lit(ValueCompiler::for_patterns().compile(v)),
|
_ => lit(ValueCompiler::for_patterns().compile(v)),
|
||||||
|
|
|
@ -7,20 +7,18 @@ use quote::quote;
|
||||||
use syn::parse_macro_input;
|
use syn::parse_macro_input;
|
||||||
|
|
||||||
use crate::stx::Stx;
|
use crate::stx::Stx;
|
||||||
use crate::val::emit_set;
|
|
||||||
use crate::val::to_value_expr;
|
use crate::val::to_value_expr;
|
||||||
use crate::val::value_to_value_expr;
|
use crate::val::value_to_value_expr;
|
||||||
|
|
||||||
pub fn lit<T: ToTokens>(e: T) -> TokenStream2 {
|
pub fn lit<T: ToTokens>(e: T) -> TokenStream2 {
|
||||||
quote!(
|
quote!(syndicate::pattern::lift_literal(#e))
|
||||||
syndicate::schemas::dataspace_patterns::Pattern::DLit(Box::new(
|
|
||||||
syndicate::schemas::dataspace_patterns::DLit { value: #e })))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_sequence_members(stxs: &Vec<Stx>) -> Result<Vec<TokenStream2>, &'static str> {
|
fn compile_sequence_members(stxs: &Vec<Stx>) -> Result<Vec<TokenStream2>, &'static str> {
|
||||||
stxs.iter().enumerate().map(|(i, stx)| {
|
stxs.iter().map(|stx| {
|
||||||
let p = to_pattern_expr(stx)?;
|
// let p = to_pattern_expr(stx)?;
|
||||||
Ok(quote!((#i .into(), #p)))
|
// Ok(quote!(#p))
|
||||||
|
to_pattern_expr(stx)
|
||||||
}).collect()
|
}).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,24 +49,21 @@ pub fn to_pattern_expr(stx: &Stx) -> Result<TokenStream2, &'static str> {
|
||||||
Ok(quote!(#P_::Pattern::DDiscard(Box::new(#P_::DDiscard)))),
|
Ok(quote!(#P_::Pattern::DDiscard(Box::new(#P_::DDiscard)))),
|
||||||
|
|
||||||
Stx::Rec(l, fs) => {
|
Stx::Rec(l, fs) => {
|
||||||
let arity = fs.len() as u128;
|
|
||||||
let label = to_value_expr(&*l)?;
|
let label = to_value_expr(&*l)?;
|
||||||
let members = compile_sequence_members(fs)?;
|
let members = compile_sequence_members(fs)?;
|
||||||
Ok(quote!(#P_::Pattern::DCompound(Box::new(#P_::DCompound::Rec {
|
Ok(quote!(#P_::Pattern::DCompound(Box::new(#P_::DCompound::Rec {
|
||||||
ctor: Box::new(#P_::CRec { label: #label, arity: #arity .into() }),
|
label: #label,
|
||||||
members: #MapFromIterator_(vec![#(#members),*])
|
fields: vec![#(#members),*],
|
||||||
}))))
|
}))))
|
||||||
},
|
},
|
||||||
Stx::Seq(stxs) => {
|
Stx::Seq(stxs) => {
|
||||||
let arity = stxs.len() as u128;
|
|
||||||
let members = compile_sequence_members(stxs)?;
|
let members = compile_sequence_members(stxs)?;
|
||||||
Ok(quote!(#P_::Pattern::DCompound(Box::new(#P_::DCompound::Arr {
|
Ok(quote!(#P_::Pattern::DCompound(Box::new(#P_::DCompound::Arr {
|
||||||
ctor: Box::new(#P_::CArr { arity: #arity .into() }),
|
items: vec![#(#members),*],
|
||||||
members: #MapFromIterator_(vec![#(#members),*])
|
|
||||||
}))))
|
}))))
|
||||||
}
|
}
|
||||||
Stx::Set(stxs) =>
|
Stx::Set(_stxs) =>
|
||||||
Ok(lit(emit_set(&stxs.iter().map(to_value_expr).collect::<Result<Vec<_>,_>>()?))),
|
Err("Set literals not supported in patterns"),
|
||||||
Stx::Dict(d) => {
|
Stx::Dict(d) => {
|
||||||
let members = d.iter().map(|(k, v)| {
|
let members = d.iter().map(|(k, v)| {
|
||||||
let k = to_value_expr(k)?;
|
let k = to_value_expr(k)?;
|
||||||
|
@ -76,8 +71,7 @@ pub fn to_pattern_expr(stx: &Stx) -> Result<TokenStream2, &'static str> {
|
||||||
Ok(quote!((#k, #v)))
|
Ok(quote!((#k, #v)))
|
||||||
}).collect::<Result<Vec<_>, &'static str>>()?;
|
}).collect::<Result<Vec<_>, &'static str>>()?;
|
||||||
Ok(quote!(#P_::Pattern::DCompound(Box::new(#P_::DCompound::Dict {
|
Ok(quote!(#P_::Pattern::DCompound(Box::new(#P_::DCompound::Dict {
|
||||||
ctor: Box::new(#P_::CDict),
|
entries: #MapFromIterator_(vec![#(#members),*])
|
||||||
members: #MapFromIterator_(vec![#(#members),*])
|
|
||||||
}))))
|
}))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use proc_macro2::Delimiter;
|
use proc_macro2::Delimiter;
|
||||||
use proc_macro2::LineColumn;
|
use proc_macro2::LineColumn;
|
||||||
use proc_macro2::TokenTree;
|
use proc_macro2::TokenStream;
|
||||||
|
|
||||||
use syn::ExprLit;
|
use syn::ExprLit;
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
|
@ -24,7 +24,7 @@ pub enum Stx {
|
||||||
Atom(IOValue),
|
Atom(IOValue),
|
||||||
Binder(Option<Ident>, Option<Type>, Option<Box<Stx>>),
|
Binder(Option<Ident>, Option<Type>, Option<Box<Stx>>),
|
||||||
Discard,
|
Discard,
|
||||||
Subst(TokenTree),
|
Subst(TokenStream),
|
||||||
Rec(Box<Stx>, Vec<Stx>),
|
Rec(Box<Stx>, Vec<Stx>),
|
||||||
Seq(Vec<Stx>),
|
Seq(Vec<Stx>),
|
||||||
Set(Vec<Stx>),
|
Set(Vec<Stx>),
|
||||||
|
@ -230,8 +230,10 @@ fn parse1(c: Cursor) -> Result<(Stx, Cursor)> {
|
||||||
'#' => {
|
'#' => {
|
||||||
if let Some((inner, _, next)) = next.group(Delimiter::Brace) {
|
if let Some((inner, _, next)) = next.group(Delimiter::Brace) {
|
||||||
parse_group_inner(inner, parse1, next).map(|(q,c)| (Stx::Set(q),c))
|
parse_group_inner(inner, parse1, next).map(|(q,c)| (Stx::Set(q),c))
|
||||||
|
} else if let Some((inner, _, next)) = next.group(Delimiter::Parenthesis) {
|
||||||
|
Ok((Stx::Subst(inner.token_stream()), next))
|
||||||
} else if let Some((tt, next)) = next.token_tree() {
|
} else if let Some((tt, next)) = next.token_tree() {
|
||||||
Ok((Stx::Subst(tt), next))
|
Ok((Stx::Subst(vec![tt].into_iter().collect()), next))
|
||||||
} else {
|
} else {
|
||||||
Err(Error::new(c.span(), "Expected expression to substitute"))
|
Err(Error::new(c.span(), "Expected expression to substitute"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,11 @@ mod pattern_plugin {
|
||||||
|
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
|
use syndicate::pattern::lift_literal;
|
||||||
use syndicate::schemas::dataspace_patterns as P;
|
use syndicate::schemas::dataspace_patterns as P;
|
||||||
use syndicate::value::IOValue;
|
use syndicate::value::IOValue;
|
||||||
use syndicate::value::Map;
|
use syndicate::value::Map;
|
||||||
use syndicate::value::NestedValue;
|
use syndicate::value::NestedValue;
|
||||||
use syndicate::value::signed_integer::SignedInteger;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PatternPlugin;
|
pub struct PatternPlugin;
|
||||||
|
@ -88,20 +88,15 @@ mod pattern_plugin {
|
||||||
match self {
|
match self {
|
||||||
CompoundPattern::Tuple { patterns } =>
|
CompoundPattern::Tuple { patterns } =>
|
||||||
Some(P::Pattern::DCompound(Box::new(P::DCompound::Arr {
|
Some(P::Pattern::DCompound(Box::new(P::DCompound::Arr {
|
||||||
ctor: Box::new(P::CArr { arity: patterns.len().into() }),
|
items: patterns.iter()
|
||||||
members: Map::from_iter(
|
.map(|p| unname(p).wc(s))
|
||||||
patterns.iter().enumerate()
|
.collect::<Option<Vec<P::Pattern>>>()?,
|
||||||
.map(|(i, p)| Some((i.into(), unname(p).wc(s)?)))
|
|
||||||
.filter(|e| discard() != e.as_ref().unwrap().1)
|
|
||||||
.collect::<Option<Vec<(SignedInteger, P::Pattern)>>>()?
|
|
||||||
.into_iter()),
|
|
||||||
}))),
|
}))),
|
||||||
CompoundPattern::TuplePrefix { .. } =>
|
CompoundPattern::TuplePrefix { .. } =>
|
||||||
Some(discard()),
|
Some(discard()),
|
||||||
CompoundPattern::Dict { entries } =>
|
CompoundPattern::Dict { entries } =>
|
||||||
Some(P::Pattern::DCompound(Box::new(P::DCompound::Dict {
|
Some(P::Pattern::DCompound(Box::new(P::DCompound::Dict {
|
||||||
ctor: Box::new(P::CDict),
|
entries: Map::from_iter(
|
||||||
members: Map::from_iter(
|
|
||||||
entries.0.iter()
|
entries.0.iter()
|
||||||
.map(|(k, p)| Some((from_io(k)?, unname_simple(p).wc(s)?)))
|
.map(|(k, p)| Some((from_io(k)?, unname_simple(p).wc(s)?)))
|
||||||
.filter(|e| discard() != e.as_ref().unwrap().1)
|
.filter(|e| discard() != e.as_ref().unwrap().1)
|
||||||
|
@ -113,16 +108,10 @@ mod pattern_plugin {
|
||||||
match (*label, *fields) {
|
match (*label, *fields) {
|
||||||
(SimplePattern::Lit { value }, CompoundPattern::Tuple { patterns }) =>
|
(SimplePattern::Lit { value }, CompoundPattern::Tuple { patterns }) =>
|
||||||
Some(P::Pattern::DCompound(Box::new(P::DCompound::Rec {
|
Some(P::Pattern::DCompound(Box::new(P::DCompound::Rec {
|
||||||
ctor: Box::new(P::CRec {
|
label: from_io(&value)?,
|
||||||
label: from_io(&value)?,
|
fields: patterns.iter()
|
||||||
arity: patterns.len().into(),
|
.map(|p| unname(p).wc(s))
|
||||||
}),
|
.collect::<Option<Vec<P::Pattern>>>()?,
|
||||||
members: Map::from_iter(
|
|
||||||
patterns.iter().enumerate()
|
|
||||||
.map(|(i, p)| Some((i.into(), unname(p).wc(s)?)))
|
|
||||||
.filter(|e| discard() != e.as_ref().unwrap().1)
|
|
||||||
.collect::<Option<Vec<(SignedInteger, P::Pattern)>>>()?
|
|
||||||
.into_iter()),
|
|
||||||
}))),
|
}))),
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
|
@ -141,11 +130,7 @@ mod pattern_plugin {
|
||||||
SimplePattern::Seqof { .. } |
|
SimplePattern::Seqof { .. } |
|
||||||
SimplePattern::Setof { .. } |
|
SimplePattern::Setof { .. } |
|
||||||
SimplePattern::Dictof { .. } => Some(discard()),
|
SimplePattern::Dictof { .. } => Some(discard()),
|
||||||
|
SimplePattern::Lit { value } => Some(lift_literal(&from_io(value)?)),
|
||||||
SimplePattern::Lit { value } => Some(P::Pattern::DLit(Box::new(P::DLit {
|
|
||||||
value: from_io(&value)?,
|
|
||||||
}))),
|
|
||||||
|
|
||||||
SimplePattern::Ref(r) => s.cycle_check(
|
SimplePattern::Ref(r) => s.cycle_check(
|
||||||
r,
|
r,
|
||||||
|ctxt, r| ctxt.bundle.lookup_definition(r),
|
|ctxt, r| ctxt.bundle.lookup_definition(r),
|
||||||
|
|
|
@ -47,7 +47,7 @@ fn run(t: &mut Activation, ds: Arc<Cap>, service_name: AnyValue) -> ActorResult
|
||||||
}))
|
}))
|
||||||
.create_cap(t);
|
.create_cap(t);
|
||||||
ds.assert(t, language(), &Observe {
|
ds.assert(t, language(), &Observe {
|
||||||
pattern: syndicate_macros::pattern!{<core-service #(service_name.clone())>},
|
pattern: syndicate_macros::pattern!{<core-service #(&service_name)>},
|
||||||
observer: milestone_monitor,
|
observer: milestone_monitor,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ fn run(t: &mut Activation, ds: Arc<Cap>, service_name: AnyValue) -> ActorResult
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
enclose!((ds, obstacle_count) during!(
|
enclose!((ds, obstacle_count) during!(
|
||||||
t, ds, language(), <depends-on #(service_name.clone()) $dependee>,
|
t, ds, language(), <depends-on #(&service_name) $dependee>,
|
||||||
enclose!((ds, obstacle_count) move |t: &mut Activation| {
|
enclose!((ds, obstacle_count) move |t: &mut Activation| {
|
||||||
if let Ok(dependee) = language().parse::<service::ServiceState>(&dependee) {
|
if let Ok(dependee) = language().parse::<service::ServiceState>(&dependee) {
|
||||||
tracing::trace!(on = ?dependee, "new dependency");
|
tracing::trace!(on = ?dependee, "new dependency");
|
||||||
|
@ -87,8 +87,8 @@ fn run(t: &mut Activation, ds: Arc<Cap>, service_name: AnyValue) -> ActorResult
|
||||||
|
|
||||||
counter::adjust(t, &obstacle_count, 1);
|
counter::adjust(t, &obstacle_count, 1);
|
||||||
|
|
||||||
let d = dependee.clone();
|
let d = &dependee.clone();
|
||||||
during!(t, ds, language(), #(d), enclose!(
|
during!(t, ds, language(), #d, enclose!(
|
||||||
(obstacle_count, dependee) move |t: &mut Activation| {
|
(obstacle_count, dependee) move |t: &mut Activation| {
|
||||||
tracing::trace!(on = ?dependee, "dependency satisfied");
|
tracing::trace!(on = ?dependee, "dependency satisfied");
|
||||||
counter::adjust(t, &obstacle_count, -1);
|
counter::adjust(t, &obstacle_count, -1);
|
||||||
|
|
|
@ -56,7 +56,7 @@ pub fn handle_resolve(
|
||||||
.create_cap(t);
|
.create_cap(t);
|
||||||
if let Some(oh) = ds.assert(t, language(), &dataspace::Observe {
|
if let Some(oh) = ds.assert(t, language(), &dataspace::Observe {
|
||||||
// TODO: codegen plugin to generate pattern constructors
|
// TODO: codegen plugin to generate pattern constructors
|
||||||
pattern: syndicate_macros::pattern!{<bind #(queried_oid) $ $>},
|
pattern: syndicate_macros::pattern!{<bind #(&queried_oid) $ $>},
|
||||||
observer: handler,
|
observer: handler,
|
||||||
}) {
|
}) {
|
||||||
Ok(Some(Box::new(move |_ds, t| Ok(t.retract(oh)))))
|
Ok(Some(Box::new(move |_ds, t| Ok(t.retract(oh)))))
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use preserves_schema::Codec;
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -7,6 +9,7 @@ use syndicate::actor::*;
|
||||||
use syndicate::dataspace::Dataspace;
|
use syndicate::dataspace::Dataspace;
|
||||||
use syndicate::during;
|
use syndicate::during;
|
||||||
use syndicate::enclose;
|
use syndicate::enclose;
|
||||||
|
use syndicate::pattern::{lift_literal, drop_literal};
|
||||||
use syndicate::schemas::dataspace;
|
use syndicate::schemas::dataspace;
|
||||||
use syndicate::schemas::dataspace_patterns as P;
|
use syndicate::schemas::dataspace_patterns as P;
|
||||||
use syndicate::schemas::sturdy;
|
use syndicate::schemas::sturdy;
|
||||||
|
@ -15,7 +18,6 @@ use syndicate::value::NestedValue;
|
||||||
use syndicate::value::Record;
|
use syndicate::value::Record;
|
||||||
use syndicate::value::Set;
|
use syndicate::value::Set;
|
||||||
use syndicate::value::Value;
|
use syndicate::value::Value;
|
||||||
use syndicate::value::signed_integer::SignedInteger;
|
|
||||||
|
|
||||||
use crate::language::language;
|
use crate::language::language;
|
||||||
|
|
||||||
|
@ -154,7 +156,7 @@ fn discard() -> P::Pattern {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dlit(value: AnyValue) -> P::Pattern {
|
fn dlit(value: AnyValue) -> P::Pattern {
|
||||||
P::Pattern::DLit(Box::new(P::DLit { value }))
|
lift_literal(&value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tlit(value: AnyValue) -> sturdy::Template {
|
fn tlit(value: AnyValue) -> sturdy::Template {
|
||||||
|
@ -239,40 +241,28 @@ impl<'env> PatternInstantiator<'env> {
|
||||||
Value::Record(r) => match parse_attenuation(r)? {
|
Value::Record(r) => match parse_attenuation(r)? {
|
||||||
Some((base_name, alternatives)) =>
|
Some((base_name, alternatives)) =>
|
||||||
dlit(self.env.eval_attenuation(base_name, alternatives)?),
|
dlit(self.env.eval_attenuation(base_name, alternatives)?),
|
||||||
None => {
|
None => {
|
||||||
// TODO: properly consolidate constant patterns into literals.
|
let label = self.instantiate_pattern(r.label())?;
|
||||||
match self.instantiate_pattern(r.label())? {
|
let fields = r.fields().iter().map(|p| self.instantiate_pattern(p))
|
||||||
P::Pattern::DLit(b) =>
|
.collect::<io::Result<Vec<P::Pattern>>>()?;
|
||||||
P::Pattern::DCompound(Box::new(P::DCompound::Rec {
|
P::Pattern::DCompound(Box::new(P::DCompound::Rec {
|
||||||
ctor: Box::new(P::CRec {
|
label: drop_literal(&label)
|
||||||
label: b.value,
|
.ok_or(bad_instruction("Record pattern must have literal label"))?,
|
||||||
arity: r.fields().len().into(),
|
fields,
|
||||||
}),
|
}))
|
||||||
members: r.fields().iter().enumerate()
|
}
|
||||||
.map(|(i, p)| Ok((i.into(), self.instantiate_pattern(p)?)))
|
|
||||||
.filter(|e| discard() != e.as_ref().unwrap().1)
|
|
||||||
.collect::<io::Result<Map<SignedInteger, P::Pattern>>>()?,
|
|
||||||
})),
|
|
||||||
_ => Err(bad_instruction("Record pattern must have literal label"))?,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Value::Sequence(v) =>
|
Value::Sequence(v) =>
|
||||||
P::Pattern::DCompound(Box::new(P::DCompound::Arr {
|
P::Pattern::DCompound(Box::new(P::DCompound::Arr {
|
||||||
ctor: Box::new(P::CArr {
|
items: v.iter()
|
||||||
arity: v.len().into(),
|
.map(|p| self.instantiate_pattern(p))
|
||||||
}),
|
.collect::<io::Result<Vec<P::Pattern>>>()?,
|
||||||
members: v.iter().enumerate()
|
|
||||||
.map(|(i, p)| Ok((i.into(), self.instantiate_pattern(p)?)))
|
|
||||||
.filter(|e| discard() != e.as_ref().unwrap().1)
|
|
||||||
.collect::<io::Result<Map<SignedInteger, P::Pattern>>>()?,
|
|
||||||
})),
|
})),
|
||||||
Value::Set(_) =>
|
Value::Set(_) =>
|
||||||
Err(bad_instruction(&format!("Sets not permitted in patterns: {:?}", template)))?,
|
Err(bad_instruction(&format!("Sets not permitted in patterns: {:?}", template)))?,
|
||||||
Value::Dictionary(v) =>
|
Value::Dictionary(v) =>
|
||||||
P::Pattern::DCompound(Box::new(P::DCompound::Dict {
|
P::Pattern::DCompound(Box::new(P::DCompound::Dict {
|
||||||
ctor: Box::new(P::CDict),
|
entries: v.iter()
|
||||||
members: v.iter()
|
|
||||||
.map(|(a, b)| Ok((a.clone(), self.instantiate_pattern(b)?)))
|
.map(|(a, b)| Ok((a.clone(), self.instantiate_pattern(b)?)))
|
||||||
.collect::<io::Result<Map<AnyValue, P::Pattern>>>()?,
|
.collect::<io::Result<Map<AnyValue, P::Pattern>>>()?,
|
||||||
})),
|
})),
|
||||||
|
@ -618,31 +608,33 @@ fn embed_pattern(p: &P::Pattern) -> sturdy::Pattern {
|
||||||
pattern: embed_pattern(&b.pattern),
|
pattern: embed_pattern(&b.pattern),
|
||||||
})),
|
})),
|
||||||
P::Pattern::DLit(b) => sturdy::Pattern::Lit(Box::new(sturdy::Lit {
|
P::Pattern::DLit(b) => sturdy::Pattern::Lit(Box::new(sturdy::Lit {
|
||||||
value: b.value.clone(),
|
value: language().unparse(&b.value),
|
||||||
})),
|
})),
|
||||||
P::Pattern::DCompound(b) => sturdy::Pattern::PCompound(Box::new(match &**b {
|
P::Pattern::DCompound(b) => sturdy::Pattern::PCompound(Box::new(match &**b {
|
||||||
P::DCompound::Rec { ctor, members } =>
|
P::DCompound::Rec { label, fields } =>
|
||||||
sturdy::PCompound {
|
sturdy::PCompound {
|
||||||
ctor: sturdy::ConstructorSpec::CRec(Box::new(sturdy::CRec {
|
ctor: sturdy::ConstructorSpec::CRec(Box::new(sturdy::CRec {
|
||||||
label: ctor.label.clone(),
|
label: label.clone(),
|
||||||
arity: ctor.arity.clone(),
|
arity: fields.len().into(),
|
||||||
})),
|
})),
|
||||||
members: sturdy::PCompoundMembers(
|
members: sturdy::PCompoundMembers(
|
||||||
members.iter().map(|(k, v)| (AnyValue::new(k), embed_pattern(v))).collect()),
|
fields.iter().enumerate().map(
|
||||||
|
|(k, v)| (AnyValue::new(k), embed_pattern(v))).collect()),
|
||||||
},
|
},
|
||||||
P::DCompound::Arr { ctor, members } =>
|
P::DCompound::Arr { items } =>
|
||||||
sturdy::PCompound {
|
sturdy::PCompound {
|
||||||
ctor: sturdy::ConstructorSpec::CArr(Box::new(sturdy::CArr {
|
ctor: sturdy::ConstructorSpec::CArr(Box::new(sturdy::CArr {
|
||||||
arity: ctor.arity.clone(),
|
arity: items.len().into(),
|
||||||
})),
|
})),
|
||||||
members: sturdy::PCompoundMembers(
|
members: sturdy::PCompoundMembers(
|
||||||
members.iter().map(|(k, v)| (AnyValue::new(k), embed_pattern(v))).collect()),
|
items.iter().enumerate().map(
|
||||||
|
|(k, v)| (AnyValue::new(k), embed_pattern(v))).collect()),
|
||||||
},
|
},
|
||||||
P::DCompound::Dict { ctor: _, members } =>
|
P::DCompound::Dict { entries } =>
|
||||||
sturdy::PCompound {
|
sturdy::PCompound {
|
||||||
ctor: sturdy::ConstructorSpec::CDict(Box::new(sturdy::CDict)),
|
ctor: sturdy::ConstructorSpec::CDict(Box::new(sturdy::CDict)),
|
||||||
members: sturdy::PCompoundMembers(
|
members: sturdy::PCompoundMembers(
|
||||||
members.iter().map(|(k, v)| (k.clone(), embed_pattern(v))).collect()),
|
entries.iter().map(|(k, v)| (k.clone(), embed_pattern(v))).collect()),
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
}
|
}
|
||||||
|
|
|
@ -352,7 +352,7 @@ fn run(
|
||||||
}))?;
|
}))?;
|
||||||
|
|
||||||
enclose!((config_ds, unready_configs, completed_processes)
|
enclose!((config_ds, unready_configs, completed_processes)
|
||||||
during!(t, config_ds.clone(), language(), <daemon #(service.id) $config>, {
|
during!(t, config_ds.clone(), language(), <daemon #(&service.id) $config>, {
|
||||||
enclose!((spec, config_ds, root_ds, unready_configs, completed_processes)
|
enclose!((spec, config_ds, root_ds, unready_configs, completed_processes)
|
||||||
|t: &mut Activation| {
|
|t: &mut Activation| {
|
||||||
tracing::debug!(?config, "new config");
|
tracing::debug!(?config, "new config");
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use criterion::{criterion_group, criterion_main, Criterion};
|
use criterion::{criterion_group, criterion_main, Criterion};
|
||||||
|
|
||||||
use std::iter::FromIterator;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::AtomicU64;
|
use std::sync::atomic::AtomicU64;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
@ -13,7 +12,6 @@ use syndicate::dataspace::Dataspace;
|
||||||
use syndicate::enclose;
|
use syndicate::enclose;
|
||||||
use syndicate::schemas::dataspace::Observe;
|
use syndicate::schemas::dataspace::Observe;
|
||||||
use syndicate::schemas::dataspace_patterns as p;
|
use syndicate::schemas::dataspace_patterns as p;
|
||||||
use syndicate::value::Map;
|
|
||||||
use syndicate::value::NestedValue;
|
use syndicate::value::NestedValue;
|
||||||
use syndicate::value::Value;
|
use syndicate::value::Value;
|
||||||
|
|
||||||
|
@ -99,7 +97,7 @@ pub fn bench_pub(c: &mut Criterion) {
|
||||||
ds.assert(t, language(), &Observe {
|
ds.assert(t, language(), &Observe {
|
||||||
pattern: p::Pattern::DBind(Box::new(p::DBind {
|
pattern: p::Pattern::DBind(Box::new(p::DBind {
|
||||||
pattern: p::Pattern::DLit(Box::new(p::DLit {
|
pattern: p::Pattern::DLit(Box::new(p::DLit {
|
||||||
value: AnyValue::symbol("consumer"),
|
value: p::AnyAtom::Symbol("consumer".to_owned()),
|
||||||
})),
|
})),
|
||||||
})),
|
})),
|
||||||
observer: shutdown,
|
observer: shutdown,
|
||||||
|
@ -120,25 +118,21 @@ pub fn bench_pub(c: &mut Criterion) {
|
||||||
ds.assert(t, &(), &AnyValue::symbol("consumer"));
|
ds.assert(t, &(), &AnyValue::symbol("consumer"));
|
||||||
ds.assert(t, language(), &Observe {
|
ds.assert(t, language(), &Observe {
|
||||||
pattern: p::Pattern::DCompound(Box::new(p::DCompound::Rec {
|
pattern: p::Pattern::DCompound(Box::new(p::DCompound::Rec {
|
||||||
ctor: Box::new(p::CRec {
|
label: AnyValue::symbol("Says"),
|
||||||
label: AnyValue::symbol("Says"),
|
fields: vec![
|
||||||
arity: 2.into(),
|
p::Pattern::DLit(Box::new(p::DLit {
|
||||||
}),
|
value: p::AnyAtom::String("bench_pub".to_owned()),
|
||||||
members: Map::from_iter(vec![
|
})),
|
||||||
(0.into(), p::Pattern::DLit(Box::new(p::DLit {
|
p::Pattern::DBind(Box::new(p::DBind {
|
||||||
value: AnyValue::new("bench_pub"),
|
|
||||||
}))),
|
|
||||||
(1.into(), p::Pattern::DBind(Box::new(p::DBind {
|
|
||||||
pattern: p::Pattern::DDiscard(Box::new(p::DDiscard)),
|
pattern: p::Pattern::DDiscard(Box::new(p::DDiscard)),
|
||||||
}))),
|
})),
|
||||||
].into_iter()),
|
]})),
|
||||||
})),
|
|
||||||
observer: receiver,
|
observer: receiver,
|
||||||
});
|
});
|
||||||
ds.assert(t, language(), &Observe {
|
ds.assert(t, language(), &Observe {
|
||||||
pattern: p::Pattern::DBind(Box::new(p::DBind {
|
pattern: p::Pattern::DBind(Box::new(p::DBind {
|
||||||
pattern: p::Pattern::DLit(Box::new(p::DLit {
|
pattern: p::Pattern::DLit(Box::new(p::DLit {
|
||||||
value: AnyValue::new(true),
|
value: p::AnyAtom::Bool(true),
|
||||||
})),
|
})),
|
||||||
})),
|
})),
|
||||||
observer: shutdown,
|
observer: shutdown,
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
use crate::schemas::dataspace_patterns::*;
|
use crate::schemas::dataspace_patterns::*;
|
||||||
|
|
||||||
use preserves::value::NestedValue;
|
use super::language;
|
||||||
|
|
||||||
use std::convert::TryFrom;
|
use preserves::value::Map;
|
||||||
use std::convert::TryInto;
|
use preserves::value::NestedValue;
|
||||||
|
use preserves::value::Record;
|
||||||
|
use preserves::value::Value;
|
||||||
|
use preserves_schema::Codec;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
|
||||||
pub enum PathStep {
|
pub enum PathStep {
|
||||||
|
@ -26,8 +29,8 @@ pub struct PatternAnalysis {
|
||||||
pub capture_paths: Paths,
|
pub capture_paths: Paths,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PatternMatcher<N: NestedValue> {
|
struct PatternMatcher {
|
||||||
captures: Vec<N>,
|
captures: Vec<_Any>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PatternAnalysis {
|
impl PatternAnalysis {
|
||||||
|
@ -56,14 +59,18 @@ impl Analyzer {
|
||||||
fn walk(&mut self, path: &mut Path, p: &Pattern) {
|
fn walk(&mut self, path: &mut Path, p: &Pattern) {
|
||||||
match p {
|
match p {
|
||||||
Pattern::DCompound(b) => match &**b {
|
Pattern::DCompound(b) => match &**b {
|
||||||
DCompound::Rec { members, .. } |
|
DCompound::Rec { fields, .. } => {
|
||||||
DCompound::Arr { members, .. } => {
|
for (i, p) in fields.iter().enumerate() {
|
||||||
for (i, p) in members {
|
self.walk_step(path, PathStep::Index(i), p);
|
||||||
self.walk_step(path, PathStep::Index(usize::try_from(i).unwrap_or(0)), p);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DCompound::Dict { members, .. } => {
|
DCompound::Arr { items, .. } => {
|
||||||
for (k, p) in members {
|
for (i, p) in items.iter().enumerate() {
|
||||||
|
self.walk_step(path, PathStep::Index(i), p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DCompound::Dict { entries, .. } => {
|
||||||
|
for (k, p) in entries {
|
||||||
self.walk_step(path, PathStep::Key(k.clone()), p);
|
self.walk_step(path, PathStep::Key(k.clone()), p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,14 +85,14 @@ impl Analyzer {
|
||||||
Pattern::DLit(b) => {
|
Pattern::DLit(b) => {
|
||||||
let DLit { value } = &**b;
|
let DLit { value } = &**b;
|
||||||
self.const_paths.push(path.clone());
|
self.const_paths.push(path.clone());
|
||||||
self.const_values.push(value.clone());
|
self.const_values.push(language().unparse(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: NestedValue> Pattern<N> {
|
impl Pattern<_Any> {
|
||||||
pub fn match_value(&self, value: &N) -> Option<Vec<N>> {
|
pub fn match_value(&self, value: &_Any) -> Option<Vec<_Any>> {
|
||||||
let mut matcher = PatternMatcher::new();
|
let mut matcher = PatternMatcher::new();
|
||||||
if matcher.run(self, value) {
|
if matcher.run(self, value) {
|
||||||
Some(matcher.captures)
|
Some(matcher.captures)
|
||||||
|
@ -95,29 +102,30 @@ impl<N: NestedValue> Pattern<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: NestedValue> PatternMatcher<N> {
|
impl PatternMatcher {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
PatternMatcher {
|
PatternMatcher {
|
||||||
captures: Vec::new(),
|
captures: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&mut self, pattern: &Pattern<N>, value: &N) -> bool {
|
fn run(&mut self, pattern: &Pattern<_Any>, value: &_Any) -> bool {
|
||||||
match pattern {
|
match pattern {
|
||||||
Pattern::DDiscard(_) => true,
|
Pattern::DDiscard(_) => true,
|
||||||
Pattern::DBind(b) => {
|
Pattern::DBind(b) => {
|
||||||
self.captures.push(value.clone());
|
self.captures.push(value.clone());
|
||||||
self.run(&b.pattern, value)
|
self.run(&b.pattern, value)
|
||||||
}
|
}
|
||||||
Pattern::DLit(b) => value == &b.value,
|
Pattern::DLit(b) => value == &language().unparse(&b.value),
|
||||||
Pattern::DCompound(b) => match &**b {
|
Pattern::DCompound(b) => match &**b {
|
||||||
DCompound::Rec { ctor, members } => {
|
DCompound::Rec { label, fields } => {
|
||||||
let arity = (&ctor.arity).try_into().expect("reasonable arity");
|
match value.value().as_record(Some(fields.len())) {
|
||||||
match value.value().as_record(Some(arity)) {
|
|
||||||
None => false,
|
None => false,
|
||||||
Some(r) => {
|
Some(r) => {
|
||||||
for (i, p) in members.iter() {
|
if r.label() != label {
|
||||||
let i: usize = i.try_into().expect("reasonable index");
|
return false;
|
||||||
|
}
|
||||||
|
for (i, p) in fields.iter().enumerate() {
|
||||||
if !self.run(p, &r.fields()[i]) {
|
if !self.run(p, &r.fields()[i]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -126,16 +134,14 @@ impl<N: NestedValue> PatternMatcher<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DCompound::Arr { ctor, members } => {
|
DCompound::Arr { items } => {
|
||||||
let arity: usize = (&ctor.arity).try_into().expect("reasonable arity");
|
|
||||||
match value.value().as_sequence() {
|
match value.value().as_sequence() {
|
||||||
None => false,
|
None => false,
|
||||||
Some(vs) => {
|
Some(vs) => {
|
||||||
if vs.len() != arity {
|
if vs.len() != items.len() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (i, p) in members.iter() {
|
for (i, p) in items.iter().enumerate() {
|
||||||
let i: usize = i.try_into().expect("reasonable index");
|
|
||||||
if !self.run(p, &vs[i]) {
|
if !self.run(p, &vs[i]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -144,12 +150,12 @@ impl<N: NestedValue> PatternMatcher<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DCompound::Dict { ctor: _, members } => {
|
DCompound::Dict { entries: expected_entries } => {
|
||||||
match value.value().as_dictionary() {
|
match value.value().as_dictionary() {
|
||||||
None => false,
|
None => false,
|
||||||
Some(entries) => {
|
Some(actual_entries) => {
|
||||||
for (k, p) in members.iter() {
|
for (k, p) in expected_entries.iter() {
|
||||||
if !entries.get(k).map(|v| self.run(p, v)).unwrap_or(false) {
|
if !actual_entries.get(k).map(|v| self.run(p, v)).unwrap_or(false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,3 +167,45 @@ impl<N: NestedValue> PatternMatcher<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lift_literal(v: &_Any) -> Pattern {
|
||||||
|
match v.value() {
|
||||||
|
Value::Record(r) => Pattern::DCompound(Box::new(DCompound::Rec {
|
||||||
|
label: r.label().clone(),
|
||||||
|
fields: r.fields().iter().map(lift_literal).collect(),
|
||||||
|
})),
|
||||||
|
Value::Sequence(items) => Pattern::DCompound(Box::new(DCompound::Arr {
|
||||||
|
items: items.iter().map(lift_literal).collect(),
|
||||||
|
})),
|
||||||
|
Value::Set(_members) => panic!("Cannot express literal set in pattern"),
|
||||||
|
Value::Dictionary(entries) => Pattern::DCompound(Box::new(DCompound::Dict {
|
||||||
|
entries: entries.iter().map(|(k, v)| (k.clone(), lift_literal(v))).collect(),
|
||||||
|
})),
|
||||||
|
_other => Pattern::DLit(Box::new(DLit {
|
||||||
|
value: language().parse(v).expect("Non-compound datum can be converted to AnyAtom"),
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn drop_literal(p: &Pattern) -> Option<_Any> {
|
||||||
|
match p {
|
||||||
|
Pattern::DCompound(b) => match &**b {
|
||||||
|
DCompound::Rec { label, fields } => {
|
||||||
|
let mut r = vec![label.clone()];
|
||||||
|
for f in fields.iter() {
|
||||||
|
r.push(drop_literal(f)?);
|
||||||
|
}
|
||||||
|
Some(Value::Record(Record(r)).wrap())
|
||||||
|
}
|
||||||
|
DCompound::Arr { items } =>
|
||||||
|
Some(Value::Sequence(items.iter().map(drop_literal)
|
||||||
|
.collect::<Option<Vec<_Any>>>()?).wrap()),
|
||||||
|
DCompound::Dict { entries } =>
|
||||||
|
Some(Value::Dictionary(entries.iter()
|
||||||
|
.map(|(k, p)| Some((k.clone(), drop_literal(p)?)))
|
||||||
|
.collect::<Option<Map<_Any, _Any>>>()?).wrap()),
|
||||||
|
},
|
||||||
|
Pattern::DLit(b) => Some(language().unparse(&b.value)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,8 +9,6 @@ use super::bag;
|
||||||
|
|
||||||
use preserves::value::{Map, NestedValue, Set, Value};
|
use preserves::value::{Map, NestedValue, Set, Value};
|
||||||
use std::collections::btree_map::Entry;
|
use std::collections::btree_map::Entry;
|
||||||
use std::convert::TryFrom;
|
|
||||||
use std::convert::TryInto;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::actor::AnyValue;
|
use crate::actor::AnyValue;
|
||||||
|
@ -216,15 +214,15 @@ impl Node {
|
||||||
) -> (usize, &mut Node) {
|
) -> (usize, &mut Node) {
|
||||||
let (guard, members): (Guard, Vec<(PathStep, &ds::Pattern)>) = match pat {
|
let (guard, members): (Guard, Vec<(PathStep, &ds::Pattern)>) = match pat {
|
||||||
ds::Pattern::DCompound(b) => match &**b {
|
ds::Pattern::DCompound(b) => match &**b {
|
||||||
ds::DCompound::Arr { ctor, members } =>
|
ds::DCompound::Arr { items } =>
|
||||||
(Guard::Seq(usize::try_from(&ctor.arity).unwrap_or(0)),
|
(Guard::Seq(items.len()),
|
||||||
members.iter().map(|(i, p)| (PathStep::Index(i.try_into().unwrap_or(0)), p)).collect()),
|
items.iter().enumerate().map(|(i, p)| (PathStep::Index(i), p)).collect()),
|
||||||
ds::DCompound::Rec { ctor, members } =>
|
ds::DCompound::Rec { label, fields } =>
|
||||||
(Guard::Rec(ctor.label.clone(), usize::try_from(&ctor.arity).unwrap_or(0)),
|
(Guard::Rec(label.clone(), fields.len()),
|
||||||
members.iter().map(|(i, p)| (PathStep::Index(i.try_into().unwrap_or(0)), p)).collect()),
|
fields.iter().enumerate().map(|(i, p)| (PathStep::Index(i), p)).collect()),
|
||||||
ds::DCompound::Dict { members, .. } =>
|
ds::DCompound::Dict { entries, .. } =>
|
||||||
(Guard::Map,
|
(Guard::Map,
|
||||||
members.iter().map(|(k, p)| (PathStep::Key(k.clone()), p)).collect()),
|
entries.iter().map(|(k, p)| (PathStep::Key(k.clone()), p)).collect()),
|
||||||
}
|
}
|
||||||
ds::Pattern::DBind(b) => {
|
ds::Pattern::DBind(b) => {
|
||||||
let ds::DBind { pattern, .. } = &**b;
|
let ds::DBind { pattern, .. } = &**b;
|
||||||
|
|
Loading…
Reference in New Issue