forked from Orchid/orchid
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:
@@ -26,7 +26,7 @@ pub struct Module {
|
|||||||
pub type RuleCollectionResult<ELoad> = Result<Vec<super::Rule>, ModuleError<ELoad>>;
|
pub type RuleCollectionResult<ELoad> = Result<Vec<super::Rule>, ModuleError<ELoad>>;
|
||||||
|
|
||||||
pub fn rule_collector<F: 'static, ELoad>(
|
pub fn rule_collector<F: 'static, ELoad>(
|
||||||
mut load_mod: F,
|
load_mod: F,
|
||||||
prelude: Vec<String>
|
prelude: Vec<String>
|
||||||
) -> Cache<'static, Mrc<[String]>, RuleCollectionResult<ELoad>>
|
) -> Cache<'static, Mrc<[String]>, RuleCollectionResult<ELoad>>
|
||||||
where
|
where
|
||||||
@@ -131,7 +131,7 @@ where
|
|||||||
} else { Err(ModuleError::None) }
|
} else { Err(ModuleError::None) }
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
let mut name_resolver_rc = RefCell::new(NameResolver::new({
|
let name_resolver_rc = RefCell::new(NameResolver::new({
|
||||||
let modname = Rc::clone(&modname);
|
let modname = Rc::clone(&modname);
|
||||||
move |path| {
|
move |path| {
|
||||||
Some(modname.try_find(&path).ok()?.as_ref().clone())
|
Some(modname.try_find(&path).ok()?.as_ref().clone())
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use mappable_rc::Mrc;
|
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};
|
use super::{super::RuleError, state::{State, Entry}, slice_matcher::SliceMatcherDnC};
|
||||||
|
|
||||||
fn verify_scalar_vec(pattern: &Expr, is_vec: &mut HashMap<String, bool>)
|
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 {
|
tpl.iter().flat_map(|Expr(clause, xpr_typ)| match clause {
|
||||||
Clause::Auto(name_opt, typ, body) => box_once(Expr(Clause::Auto(
|
Clause::Auto(name_opt, typ, body) => box_once(Expr(Clause::Auto(
|
||||||
name_opt.as_ref().and_then(|name| {
|
name_opt.as_ref().and_then(|name| {
|
||||||
let state_key = name.strip_prefix('$')
|
if let Some(state_key) = name.strip_prefix('$') {
|
||||||
.expect("Auto template may only reference, never enforce the name");
|
match &state[state_key] {
|
||||||
match &state[state_key] {
|
Entry::NameOpt(name) => name.as_ref().map(|s| s.as_ref().to_owned()),
|
||||||
Entry::NameOpt(name) => name.as_ref().map(|s| s.as_ref().to_owned()),
|
Entry::Name(name) => Some(name.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")
|
||||||
_ => panic!("Auto template name may only be derived from Auto or Lambda name")
|
}
|
||||||
|
} else {
|
||||||
|
Some(name.to_owned())
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
write_slice(state, typ),
|
write_slice(state, typ),
|
||||||
@@ -118,9 +120,17 @@ fn write_slice(state: &State, tpl: &Mrc<[Expr]>) -> Mrc<[Expr]> {
|
|||||||
*c,
|
*c,
|
||||||
write_slice(state, body)
|
write_slice(state, body)
|
||||||
), xpr_typ.to_owned())),
|
), xpr_typ.to_owned())),
|
||||||
Clause::Placeh{key, vec: None} => if let Entry::Scalar(x) = &state[key] {
|
Clause::Placeh{key, vec: None} => {
|
||||||
box_once(x.as_ref().to_owned())
|
let real_key = if let Some(real_key) = key.strip_prefix('_') {real_key} else {key};
|
||||||
} else {panic!("Scalar template may only be derived from scalar placeholder")},
|
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] {
|
Clause::Placeh{key, vec: Some(_)} => if let Entry::Vec(v) = &state[key] {
|
||||||
into_boxed_iter(v.as_ref().to_owned())
|
into_boxed_iter(v.as_ref().to_owned())
|
||||||
} else {panic!("Vectorial template may only be derived from vectorial placeholder")},
|
} else {panic!("Vectorial template may only be derived from vectorial placeholder")},
|
||||||
|
|||||||
@@ -217,8 +217,12 @@ impl SliceMatcherDnC {
|
|||||||
(Clause::Literal(val), Clause::Literal(tgt)) => {
|
(Clause::Literal(val), Clause::Literal(tgt)) => {
|
||||||
if val == tgt {Some(own_state)} else {None}
|
if val == tgt {Some(own_state)} else {None}
|
||||||
}
|
}
|
||||||
(Clause::Placeh{key, vec: None}, _) => {
|
(Clause::Placeh{key, vec: None}, tgt_clause) => {
|
||||||
own_state.insert_scalar(&key, &target[pos])
|
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)) => {
|
(Clause::S(c, _), Clause::S(c_tgt, body_range)) => {
|
||||||
if c != c_tgt {return None}
|
if c != c_tgt {return None}
|
||||||
@@ -257,12 +261,10 @@ impl SliceMatcherDnC {
|
|||||||
// Step through valid slicings based on reported size constraints in order
|
// Step through valid slicings based on reported size constraints in order
|
||||||
// from longest own section to shortest and from left to right
|
// from longest own section to shortest and from left to right
|
||||||
for (left, own, right) in self.valid_subdivisions(target) {
|
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!(
|
return Some(unwrap_or_continue!(
|
||||||
unwrap_or_continue!(sides_result)
|
self.apply_side_with_cache(Side::Left, left, cache)
|
||||||
.insert_vec(name, own.as_ref())
|
.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
|
None
|
||||||
@@ -276,11 +278,10 @@ impl SliceMatcherDnC {
|
|||||||
if self.pattern.is_empty() {
|
if self.pattern.is_empty() {
|
||||||
return if target.is_empty() {Some(State::new())} else {None}
|
return if target.is_empty() {Some(State::new())} else {None}
|
||||||
}
|
}
|
||||||
match self.clause.as_ref() {
|
if self.clause_is_vectorial() {
|
||||||
Clause::Placeh{key, vec: Some(_)} =>
|
let key = self.state_key().expect("Vectorial implies key");
|
||||||
self.match_range_vectorial_cached(key, target, cache),
|
self.match_range_vectorial_cached(key, target, cache)
|
||||||
_ => self.match_range_scalar_cached(target, cache)
|
} else {self.match_range_scalar_cached(target, cache)}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_matcher_cache<'a>()
|
pub fn get_matcher_cache<'a>()
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ mod side;
|
|||||||
mod merge_sorted;
|
mod merge_sorted;
|
||||||
mod unwrap_or_continue;
|
mod unwrap_or_continue;
|
||||||
pub mod iter;
|
pub mod iter;
|
||||||
|
|
||||||
pub use cache::Cache;
|
pub use cache::Cache;
|
||||||
use mappable_rc::Mrc;
|
use mappable_rc::Mrc;
|
||||||
pub use substack::Stackframe;
|
pub use substack::Stackframe;
|
||||||
@@ -32,3 +33,7 @@ pub fn collect_to_mrc<I>(iter: I) -> Mrc<[I::Item]> where I: Iterator {
|
|||||||
pub fn mrc_derive_slice<T>(mv: &Mrc<Vec<T>>) -> Mrc<[T]> {
|
pub fn mrc_derive_slice<T>(mv: &Mrc<Vec<T>>) -> Mrc<[T]> {
|
||||||
mrc_derive(mv, |v| v.as_slice())
|
mrc_derive(mv, |v| v.as_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn one_mrc_slice<T>(t: T) -> Mrc<[T]> {
|
||||||
|
Mrc::map(Mrc::new([t; 1]), |v| v.as_slice())
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user