forked from Orchid/orchid
backup commit
This commit is contained in:
@@ -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, one_mrc_slice}};
|
||||
use crate::{ast::{Expr, Clause}, utils::{iter::{box_once, into_boxed_iter}, to_mrc_slice, one_mrc_slice}, unwrap_or};
|
||||
use super::{super::RuleError, state::{State, Entry}, slice_matcher::SliceMatcherDnC};
|
||||
|
||||
fn verify_scalar_vec(pattern: &Expr, is_vec: &mut HashMap<String, bool>)
|
||||
@@ -36,18 +36,18 @@ fn verify_scalar_vec(pattern: &Expr, is_vec: &mut HashMap<String, bool>)
|
||||
};
|
||||
Ok(())
|
||||
};
|
||||
let Expr(val, typ_opt) = pattern;
|
||||
let Expr(val, typ) = pattern;
|
||||
verify_clause(val, is_vec)?;
|
||||
if let Some(typ) = typ_opt {
|
||||
verify_scalar_vec(typ, is_vec)?;
|
||||
for typ in typ.as_ref() {
|
||||
verify_clause(typ, is_vec)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
fn slice_to_vec(src: &mut Mrc<[Expr]>, tgt: &mut Mrc<[Expr]>) {
|
||||
let prefix_expr = Expr(Clause::Placeh{key: "::prefix".to_string(), vec: Some((0, false))}, None);
|
||||
let postfix_expr = Expr(Clause::Placeh{key: "::postfix".to_string(), vec: Some((0, false))}, None);
|
||||
let prefix_expr = Expr(Clause::Placeh{key: "::prefix".to_string(), vec: Some((0, false))}, to_mrc_slice(vec![]));
|
||||
let postfix_expr = Expr(Clause::Placeh{key: "::postfix".to_string(), vec: Some((0, false))}, to_mrc_slice(vec![]));
|
||||
// Prefix or postfix to match the full vector
|
||||
let head_multi = matches!(src.first().expect("Src can never be empty!").0, Clause::Placeh{vec: Some(_), ..});
|
||||
let tail_multi = matches!(src.last().expect("Impossible branch!").0, Clause::Placeh{vec: Some(_), ..});
|
||||
@@ -121,13 +121,13 @@ fn write_slice(state: &State, tpl: &Mrc<[Expr]>) -> Mrc<[Expr]> {
|
||||
write_slice(state, body)
|
||||
), xpr_typ.to_owned())),
|
||||
Clause::Placeh{key, vec: None} => {
|
||||
let real_key = if let Some(real_key) = key.strip_prefix('_') {real_key} else {key};
|
||||
let real_key = unwrap_or!(key.strip_prefix('_'); 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)),
|
||||
}, to_mrc_slice(vec![]))),
|
||||
_ => panic!("Scalar template may only be derived from scalar placeholder"),
|
||||
}
|
||||
},
|
||||
@@ -135,7 +135,7 @@ fn write_slice(state: &State, tpl: &Mrc<[Expr]>) -> Mrc<[Expr]> {
|
||||
into_boxed_iter(v.as_ref().to_owned())
|
||||
} else {panic!("Vectorial template may only be derived from vectorial placeholder")},
|
||||
// Explicit base case so that we get an error if Clause gets new values
|
||||
c@Clause::Literal(_) | c@Clause::Name { .. } =>
|
||||
c@Clause::Literal(_) | c@Clause::Name { .. } | c@Clause::ExternFn(_) | c@Clause::Atom(_) =>
|
||||
box_once(Expr(c.to_owned(), xpr_typ.to_owned()))
|
||||
}).collect()
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ use std::fmt::Debug;
|
||||
|
||||
use mappable_rc::Mrc;
|
||||
|
||||
use crate::expression::{Expr, Clause};
|
||||
use crate::unwrap_or_continue;
|
||||
use crate::ast::{Expr, Clause};
|
||||
use crate::unwrap_or;
|
||||
use crate::utils::iter::box_empty;
|
||||
use crate::utils::{Side, Cache, mrc_derive, mrc_try_derive, to_mrc_slice};
|
||||
|
||||
@@ -92,10 +92,7 @@ impl SliceMatcherDnC {
|
||||
pub fn valid_subdivisions(&self,
|
||||
range: Mrc<[Expr]>
|
||||
) -> impl Iterator<Item = (Mrc<[Expr]>, Mrc<[Expr]>, Mrc<[Expr]>)> {
|
||||
let own_max = {
|
||||
if let Some(x) = self.own_max_size(range.len()) {x}
|
||||
else {return box_empty()}
|
||||
};
|
||||
let own_max = unwrap_or!(self.own_max_size(range.len()); return box_empty());
|
||||
let own_min = self.own_min_size();
|
||||
let lmin = self.min(Side::Left);
|
||||
let _lmax = self.max(Side::Left, range.len());
|
||||
@@ -261,10 +258,11 @@ 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) {
|
||||
return Some(unwrap_or_continue!(
|
||||
return Some(unwrap_or!(
|
||||
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()))
|
||||
.and_then(|side_res| side_res.insert_vec(name, own.as_ref()));
|
||||
continue
|
||||
))
|
||||
}
|
||||
None
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use mappable_rc::Mrc;
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::expression::{Expr, Clause};
|
||||
use crate::ast::{Expr, Clause};
|
||||
use crate::utils::{mrc_derive, mrc_try_derive};
|
||||
|
||||
pub type MaxVecSplit = (Mrc<[Expr]>, (Mrc<str>, usize, bool), Mrc<[Expr]>);
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::{ops::{Add, Index}, rc::Rc, fmt::Debug};
|
||||
|
||||
use hashbrown::HashMap;
|
||||
|
||||
use crate::expression::Expr;
|
||||
use crate::ast::Expr;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Entry {
|
||||
@@ -76,7 +76,9 @@ impl State {
|
||||
{
|
||||
if let Some(old) = self.0.get(k.as_ref()) {
|
||||
if let Entry::NameOpt(val) = old {
|
||||
if val.as_ref().map(|s| s.as_ref().as_str()) != v.map(|s| s.as_ref()) {return None}
|
||||
if val.as_ref().map(|s| s.as_ref().as_str()) != v.map(|s| s.as_ref()) {
|
||||
return None
|
||||
}
|
||||
} else {return None}
|
||||
} else {
|
||||
self.0.insert(k.to_string(), Entry::NameOpt(v.map(|s| Rc::new(s.to_string()))));
|
||||
@@ -142,4 +144,4 @@ impl Debug for State {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{:?}", self.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,11 @@ use std::fmt::Debug;
|
||||
|
||||
use mappable_rc::Mrc;
|
||||
|
||||
use crate::expression::Expr;
|
||||
use crate::representations::ast::Expr;
|
||||
|
||||
use super::{super::expression::Rule, executor::execute, RuleError};
|
||||
use super::{super::ast::Rule, executor::execute, RuleError};
|
||||
|
||||
/// Manages a priority queue of substitution rules and allows to apply them
|
||||
pub struct Repository(Vec<Rule>);
|
||||
impl Repository {
|
||||
pub fn new(mut rules: Vec<Rule>) -> Self {
|
||||
@@ -13,6 +14,7 @@ impl Repository {
|
||||
Self(rules)
|
||||
}
|
||||
|
||||
/// Attempt to run each rule in priority order once
|
||||
pub fn step(&self, mut code: Mrc<[Expr]>) -> Result<Option<Mrc<[Expr]>>, RuleError> {
|
||||
let mut ran_once = false;
|
||||
for rule in self.0.iter() {
|
||||
@@ -27,11 +29,16 @@ impl Repository {
|
||||
Ok(if ran_once {Some(code)} else {None})
|
||||
}
|
||||
|
||||
pub fn long_step(&self, mut code: Mrc<[Expr]>) -> Result<Mrc<[Expr]>, RuleError> {
|
||||
/// Attempt to run each rule in priority order `limit` times. Returns the final
|
||||
/// tree and the number of iterations left to the limit.
|
||||
pub fn long_step(&self, mut code: Mrc<[Expr]>, mut limit: usize)
|
||||
-> Result<(Mrc<[Expr]>, usize), RuleError> {
|
||||
while let Some(tmp) = self.step(Mrc::clone(&code))? {
|
||||
if 0 >= limit {break}
|
||||
limit -= 1;
|
||||
code = tmp
|
||||
}
|
||||
Ok(code)
|
||||
Ok((code, limit))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user