Commit ce22e14c authored by Jeff Smits's avatar Jeff Smits

Cleaning up the Scope type

parent e6a1b089
......@@ -28,28 +28,16 @@ pub struct MutContext<'d, 'f: 'd> {
impl<'d, 'f: 'd> MutContext<'d, 'f> {
pub fn new(
factory: &'f ATermFactory,
scopes: Vec<Scope<'d, 'f, ATermRef<'f>>>,
strat_scopes: Vec<StrategyScope<'d, 'f>>,
primitives: Vec<&'static Primitives>,
) -> MutContext<'d, 'f> {
let mut term_maps = Vec::new();
let mut strat_maps = Vec::new();
for scope in scopes {
if !scope.term.is_empty() {
term_maps.push(scope.term);
}
if !scope.strategy.is_empty() {
strat_maps.push(scope.strategy);
}
}
MutContext {
stack_tracer: RefCell::new(StackTracer::default()),
factory: factory,
primitives: primitives,
term: RefCell::new(term_maps),
term: RefCell::new(Vec::new()),
overlays: RefCell::new(Vec::new()),
strategy: RefCell::new(strat_maps),
strategy: RefCell::new(strat_scopes),
ssl_state: RefCell::new(State::new()),
}
}
......@@ -97,17 +85,16 @@ impl<'d, 'f: 'd> MutContext<'d, 'f> {
Scopes::match_term(&mut self.overlays.borrow_mut(), &mut self.term.borrow_mut(), term_name, current)
}
pub fn in_scope<F>(&self, scope: Scope<'d, 'f, ATermRef<'f>>, body: F) -> Result<ATermRef<'f>>
pub fn in_scope<F>(&self, (term_scope, strat_scope): ScopePair<'d, 'f>, body: F) -> Result<ATermRef<'f>>
where F: FnOnce() -> Result<ATermRef<'f>>
{
let term_empty = !scope.term.is_empty();
let strat_empty = !scope.strategy.is_empty();
let term_empty = !term_scope.is_empty();
let strat_empty = !strat_scope.is_empty();
if term_empty {
debug_assert!(!scope.is_overlay, "in_scope called with overlay");
self.term.borrow_mut().push(scope.term);
self.term.borrow_mut().push(term_scope);
}
if strat_empty {
self.strategy.borrow_mut().push(scope.strategy);
self.strategy.borrow_mut().push(strat_scope);
}
let result = body();
if term_empty {
......@@ -119,6 +106,34 @@ impl<'d, 'f: 'd> MutContext<'d, 'f> {
result
}
pub fn in_term_scope<F>(&self, scope: TermScope<'f>, body: F) -> Result<ATermRef<'f>>
where F: FnOnce() -> Result<ATermRef<'f>>
{
let empty = !scope.is_empty();
if empty {
self.term.borrow_mut().push(scope);
}
let result = body();
if empty {
self.term.borrow_mut().pop();
}
result
}
pub fn in_strategy_scope<F>(&self, scope: StrategyScope<'d, 'f>, body: F) -> Result<ATermRef<'f>>
where F: FnOnce() -> Result<ATermRef<'f>>
{
let empty = !scope.is_empty();
if empty {
self.strategy.borrow_mut().push(scope);
}
let result = body();
if empty {
self.strategy.borrow_mut().pop();
}
result
}
pub fn push_overlay(&self) {
self.overlays.borrow_mut().push((self.term.borrow().len(), FnvHashMap::default()));
// To check closure offsets that can differentiate between an offset with or without an
......@@ -221,66 +236,42 @@ impl<'a> fmt::Display for StackTracer<'a> {
}
}
#[derive(Debug, Default, Clone)]
pub struct Scope<'d, 'f: 'd, ATerm> {
pub term: FnvHashMap<InternedString<'f>, Option<ATerm>>,
pub strategy: FnvHashMap<InternedString<'f>, StrategyDef<'d, 'f>>,
is_overlay: bool,
}
pub type TermScope<'f> = FnvHashMap<InternedString<'f>, Option<ATermRef<'f>>>;
pub type StrategyScope<'d, 'f> = FnvHashMap<InternedString<'f>, StrategyDef<'d, 'f>>;
pub type ScopePair<'d, 'f> = (TermScope<'f>, StrategyScope<'d, 'f>);
impl<'d, 'f: 'd, ATerm> Scope<'d, 'f, ATerm> {
pub fn new<IA, IS>(terms: IA, defs: IS) -> Self
where
IA: IntoIterator<Item = (InternedString<'f>, ATerm)>,
IS: IntoIterator<Item = (InternedString<'f>, StrategyDef<'d, 'f>)>,
{
Scope {
term: terms.into_iter().map(|(n, a)| (n, Some(a))).collect(),
strategy: defs.into_iter().collect(),
is_overlay: false,
}
}
#[allow(non_snake_case)]
pub mod Scope {
use super::*;
pub fn from_defs<I>(defs: I) -> Self
pub fn from_defs<'d, 'f: 'd, I>(defs: I) -> StrategyScope<'d, 'f>
where
I: IntoIterator<Item = &'d Def<'f>>,
{
Scope {
term: FnvHashMap::default(),
strategy: defs.into_iter()
.map(|def| (def.name, StrategyDef::from_def(def)))
.collect(),
is_overlay: false,
}
defs.into_iter()
.map(|def| (def.name, StrategyDef::from_def(def)))
.collect()
}
pub fn from_let_defs<I>(term_scope_offset: usize, strat_scope_offset: usize, defs: I) -> Self
pub fn from_let_defs<'d, 'f: 'd, I>(term_scope_offset: usize, strat_scope_offset: usize, defs: I) -> StrategyScope<'d, 'f>
where
I: IntoIterator<Item = &'d Def<'f>>,
{
Scope {
term: FnvHashMap::default(),
strategy: defs.into_iter()
.map(|def| {
(def.name, StrategyDef::from_let_def(def, term_scope_offset, strat_scope_offset))
})
.collect(),
is_overlay: false,
}
defs.into_iter()
.map(|def| {
(def.name, StrategyDef::from_let_def(def, term_scope_offset, strat_scope_offset))
})
.collect()
}
pub fn from_fresh_variables<I>(fresh_vars: I) -> Self
pub fn from_fresh_variables<'d, 'f: 'd, I>(fresh_vars: I) -> TermScope<'f>
where
I: IntoIterator<Item = InternedString<'f>>,
{
Scope {
term: fresh_vars
.into_iter()
.map(|fresh_var| (fresh_var, None))
.collect(),
strategy: FnvHashMap::default(),
is_overlay: false,
}
fresh_vars
.into_iter()
.map(|fresh_var| (fresh_var, None))
.collect()
}
}
......
......@@ -147,7 +147,7 @@ impl<'d, 'f: 'd> Eval<'d, 'f> for preprocess::Strategy<'f> {
let strat_scope_offset = context.strategy.borrow().len() + 1;
let scope = Scope::from_let_defs(term_scope_offset, strat_scope_offset, defs.iter());
context.in_scope(scope, || {
context.in_strategy_scope(scope, || {
body.eval(context, current)
})
}
......@@ -204,7 +204,7 @@ impl<'d, 'f: 'd> Eval<'d, 'f> for preprocess::Strategy<'f> {
}
Build(ref term) => build_term::build(term, context),
Scope(ref fresh_names, ref body) => {
context.in_scope(
context.in_term_scope(
context::Scope::from_fresh_variables(fresh_names.iter().cloned()),
|| body.eval(context, current),
)
......
use context::Scope;
use context::{TermScope, StrategyScope};
use ctree;
use error::{Result, Error};
use factory::ATermRef;
......@@ -69,20 +69,20 @@ impl<'d, 'f> StrategyDef<'d, 'f> {
}
}
pub fn build_scope<ATerm>(
pub fn build_scope(
&self,
actual_sargs: Vec<StrategyDef<'d, 'f>>,
actual_targs: Vec<ATerm>,
) -> Scope<'d, 'f, ATerm> {
actual_targs: Vec<ATermRef<'f>>,
) -> (TermScope<'f>, StrategyScope<'d, 'f>) {
match *self {
StrategyDef::TopLevel(def) |
StrategyDef::Predefined { def, .. } => {
Scope::new(
def.targs.iter().cloned().zip(actual_targs),
def.sargs.iter().cloned().zip(actual_sargs),
(
def.targs.iter().cloned().zip(actual_targs).map(|(n, a)| (n, Some(a))).collect(),
def.sargs.iter().cloned().zip(actual_sargs).collect(),
)
}
StrategyDef::Anonymous { .. } => Scope::new(Vec::new(), Vec::new()),
StrategyDef::Anonymous { .. } => (FnvHashMap::default(), FnvHashMap::default()),
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment