Localname-only placeholders added

Better syntax should be identified for them
Also fixed some pretty stupid logic errors. In dire need of exact
terminology to streamline my thoughts.
This commit is contained in:
2022-08-21 00:51:14 +02:00
parent f506f0f1ab
commit 1913de0c8b
4 changed files with 40 additions and 24 deletions

View File

@@ -1,7 +1,7 @@
use hashbrown::HashMap;
use mappable_rc::Mrc;
use crate::{expression::{Expr, Clause}, utils::{iter::{box_once, into_boxed_iter}, to_mrc_slice}};
use crate::{expression::{Expr, Clause}, utils::{iter::{box_once, into_boxed_iter}, to_mrc_slice, one_mrc_slice}};
use super::{super::RuleError, state::{State, Entry}, slice_matcher::SliceMatcherDnC};
fn verify_scalar_vec(pattern: &Expr, is_vec: &mut HashMap<String, bool>)
@@ -92,12 +92,14 @@ fn write_slice(state: &State, tpl: &Mrc<[Expr]>) -> Mrc<[Expr]> {
tpl.iter().flat_map(|Expr(clause, xpr_typ)| match clause {
Clause::Auto(name_opt, typ, body) => box_once(Expr(Clause::Auto(
name_opt.as_ref().and_then(|name| {
let state_key = name.strip_prefix('$')
.expect("Auto template may only reference, never enforce the name");
match &state[state_key] {
Entry::NameOpt(name) => name.as_ref().map(|s| s.as_ref().to_owned()),
Entry::Name(name) => Some(name.as_ref().to_owned()),
_ => panic!("Auto template name may only be derived from Auto or Lambda name")
if let Some(state_key) = name.strip_prefix('$') {
match &state[state_key] {
Entry::NameOpt(name) => name.as_ref().map(|s| s.as_ref().to_owned()),
Entry::Name(name) => Some(name.as_ref().to_owned()),
_ => panic!("Auto template name may only be derived from Auto or Lambda name")
}
} else {
Some(name.to_owned())
}
}),
write_slice(state, typ),
@@ -118,9 +120,17 @@ fn write_slice(state: &State, tpl: &Mrc<[Expr]>) -> Mrc<[Expr]> {
*c,
write_slice(state, body)
), xpr_typ.to_owned())),
Clause::Placeh{key, vec: None} => if let Entry::Scalar(x) = &state[key] {
box_once(x.as_ref().to_owned())
} else {panic!("Scalar template may only be derived from scalar placeholder")},
Clause::Placeh{key, vec: None} => {
let real_key = if let Some(real_key) = key.strip_prefix('_') {real_key} else {key};
match &state[real_key] {
Entry::Scalar(x) => box_once(x.as_ref().to_owned()),
Entry::Name(n) => box_once(Expr(Clause::Name {
local: Some(n.as_ref().to_owned()),
qualified: one_mrc_slice(n.as_ref().to_owned())
}, None)),
_ => panic!("Scalar template may only be derived from scalar placeholder"),
}
},
Clause::Placeh{key, vec: Some(_)} => if let Entry::Vec(v) = &state[key] {
into_boxed_iter(v.as_ref().to_owned())
} else {panic!("Vectorial template may only be derived from vectorial placeholder")},

View File

@@ -217,8 +217,12 @@ impl SliceMatcherDnC {
(Clause::Literal(val), Clause::Literal(tgt)) => {
if val == tgt {Some(own_state)} else {None}
}
(Clause::Placeh{key, vec: None}, _) => {
own_state.insert_scalar(&key, &target[pos])
(Clause::Placeh{key, vec: None}, tgt_clause) => {
if let Some(real_key) = key.strip_prefix('_') {
if let Clause::Name { local: Some(value), .. } = tgt_clause {
own_state.insert_name(real_key, value)
} else {None}
} else {own_state.insert_scalar(&key, &target[pos])}
}
(Clause::S(c, _), Clause::S(c_tgt, body_range)) => {
if c != c_tgt {return None}
@@ -257,12 +261,10 @@ impl SliceMatcherDnC {
// Step through valid slicings based on reported size constraints in order
// from longest own section to shortest and from left to right
for (left, own, right) in self.valid_subdivisions(target) {
let sides_result = unwrap_or_continue!(
self.apply_side_with_cache(Side::Left, left, cache)
) + self.apply_side_with_cache(Side::Right, right, cache);
return Some(unwrap_or_continue!(
unwrap_or_continue!(sides_result)
.insert_vec(name, own.as_ref())
self.apply_side_with_cache(Side::Left, left, cache)
.and_then(|lres| lres + self.apply_side_with_cache(Side::Right, right, cache))
.and_then(|side_res| side_res.insert_vec(name, own.as_ref()))
))
}
None
@@ -276,11 +278,10 @@ impl SliceMatcherDnC {
if self.pattern.is_empty() {
return if target.is_empty() {Some(State::new())} else {None}
}
match self.clause.as_ref() {
Clause::Placeh{key, vec: Some(_)} =>
self.match_range_vectorial_cached(key, target, cache),
_ => self.match_range_scalar_cached(target, cache)
}
if self.clause_is_vectorial() {
let key = self.state_key().expect("Vectorial implies key");
self.match_range_vectorial_cached(key, target, cache)
} else {self.match_range_scalar_cached(target, cache)}
}
pub fn get_matcher_cache<'a>()