incomplete cut corrections.
This commit is contained in:
@@ -8,19 +8,22 @@ use std::rc::Rc;
|
||||
pub trait Allocator<'a>
|
||||
{
|
||||
fn new() -> Self;
|
||||
|
||||
|
||||
fn mark_anon_var<Target>(&mut self, Level, &mut Vec<Target>)
|
||||
where Target: CompilationTarget<'a>;
|
||||
fn mark_non_var<Target>(&mut self, Level, GenContext, &'a Cell<RegType>, &mut Vec<Target>)
|
||||
where Target: CompilationTarget<'a>;
|
||||
fn mark_reserved_var<Target>(&mut self, Rc<Var>, Level, &'a Cell<VarReg>, GenContext,
|
||||
&mut Vec<Target>, RegType, bool)
|
||||
where Target: CompilationTarget<'a>;
|
||||
fn mark_var<Target>(&mut self, Rc<Var>, Level, &'a Cell<VarReg>, GenContext, &mut Vec<Target>)
|
||||
where Target: CompilationTarget<'a>;
|
||||
|
||||
where Target: CompilationTarget<'a>;
|
||||
|
||||
fn reset(&mut self);
|
||||
fn reset_contents(&mut self) {}
|
||||
fn reset_arg(&mut self, usize);
|
||||
fn reset_at_head(&mut self, &Vec<Box<Term>>);
|
||||
|
||||
|
||||
fn advance_arg(&mut self);
|
||||
|
||||
fn bindings(&self) -> &AllocVarDict;
|
||||
@@ -46,15 +49,15 @@ pub trait Allocator<'a>
|
||||
|
||||
perm_vs
|
||||
}
|
||||
|
||||
|
||||
fn get(&self, var: Rc<Var>) -> RegType {
|
||||
self.bindings().get(&var).map_or(temp_v!(0), |v| v.as_reg_type())
|
||||
}
|
||||
|
||||
fn is_unbound(&self, var: Rc<Var>) -> bool {
|
||||
self.get(var) == temp_v!(0)
|
||||
self.get(var).reg_num() == 0
|
||||
}
|
||||
|
||||
|
||||
fn record_register(&mut self, var: Rc<Var>, r: RegType) {
|
||||
match self.bindings_mut().get_mut(&var).unwrap() {
|
||||
&mut VarData::Temp(_, ref mut s, _) => *s = r.reg_num(),
|
||||
|
||||
@@ -668,7 +668,8 @@ pub type JumpStub = Vec<Term>;
|
||||
|
||||
pub enum QueryTerm {
|
||||
Clause(Cell<RegType>, ClauseType, Vec<Box<Term>>),
|
||||
Cut,
|
||||
BlockedCut, // a cut which is 'blocked by letters', like the P term in P -> Q.
|
||||
UnblockedCut,
|
||||
Jump(JumpStub)
|
||||
}
|
||||
|
||||
@@ -676,7 +677,7 @@ impl QueryTerm {
|
||||
pub fn arity(&self) -> usize {
|
||||
match self {
|
||||
&QueryTerm::Clause(_, _, ref subterms) => subterms.len(),
|
||||
&QueryTerm::Cut => 0,
|
||||
&QueryTerm::BlockedCut | &QueryTerm::UnblockedCut => 0,
|
||||
&QueryTerm::Jump(ref vars) => vars.len()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,6 +161,17 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
||||
} else {
|
||||
self.marker.mark_anon_var(lvl, &mut target);
|
||||
},
|
||||
TermRef::Var(lvl @ Level::Shallow, cell, ref var) if var.as_str() == "!" => {
|
||||
if self.marker.is_unbound(var.clone()) {
|
||||
if term_loc != GenContext::Head {
|
||||
self.marker.mark_reserved_var(var.clone(), lvl, cell, term_loc,
|
||||
&mut target, perm_v!(1), false);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target);
|
||||
},
|
||||
TermRef::Var(lvl @ Level::Shallow, cell, var) =>
|
||||
self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target),
|
||||
_ => {}
|
||||
@@ -397,7 +408,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
||||
};
|
||||
|
||||
match *term {
|
||||
&QueryTerm::Cut =>
|
||||
&QueryTerm::UnblockedCut =>
|
||||
code.push(set_cp!(self.marker.get(rc_atom!("!")))),
|
||||
&QueryTerm::BlockedCut =>
|
||||
code.push(if chunk_num == 0 {
|
||||
Line::Cut(CutInstruction::NeckCut)
|
||||
} else {
|
||||
@@ -469,7 +482,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
||||
{
|
||||
// add a proceed to bookend any trailing cuts.
|
||||
match toc {
|
||||
&QueryTerm::Cut => code.push(proceed!()),
|
||||
&QueryTerm::BlockedCut | &QueryTerm::UnblockedCut => code.push(proceed!()),
|
||||
_ => {}
|
||||
};
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ impl<'a> Allocator<'a> for DebrayAllocator
|
||||
}
|
||||
}
|
||||
|
||||
fn mark_var<Target>(&mut self, var: Rc<Var>, lvl: Level, cell: &Cell<VarReg>,
|
||||
fn mark_var<Target>(&mut self, var: Rc<Var>, lvl: Level, cell: &'a Cell<VarReg>,
|
||||
term_loc: GenContext, target: &mut Vec<Target>)
|
||||
where Target: CompilationTarget<'a>
|
||||
{
|
||||
@@ -271,6 +271,14 @@ impl<'a> Allocator<'a> for DebrayAllocator
|
||||
r => (r, false)
|
||||
};
|
||||
|
||||
self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var);
|
||||
}
|
||||
|
||||
fn mark_reserved_var<Target>(&mut self, var: Rc<Var>, lvl: Level, cell: &'a Cell<VarReg>,
|
||||
term_loc: GenContext, target: &mut Vec<Target>, r: RegType,
|
||||
is_new_var: bool)
|
||||
where Target: CompilationTarget<'a>
|
||||
{
|
||||
match lvl {
|
||||
Level::Root | Level::Shallow => {
|
||||
let k = self.arg_c;
|
||||
|
||||
@@ -540,6 +540,8 @@ fn compile_query(terms: Vec<QueryTerm>, queue: Vec<TopLevel>, code_size: usize,
|
||||
let query_info = QueryInfo {};
|
||||
query_info.label_clauses(code_size, code_dir, &mut code);
|
||||
|
||||
print_code(&code);
|
||||
|
||||
Ok((code, cg.take_vars()))
|
||||
}
|
||||
|
||||
@@ -571,6 +573,8 @@ fn compile_decl(wam: &mut Machine, tl: TopLevel, queue: Vec<TopLevel>) -> EvalSe
|
||||
|
||||
decl_info.label_clauses(wam.code_size(), &mut wam.code_dir, &mut code);
|
||||
|
||||
print_code(&code);
|
||||
|
||||
if !code.is_empty() {
|
||||
wam.add_user_code(name, tl.arity(), code, tl.as_predicate().unwrap())
|
||||
} else {
|
||||
|
||||
@@ -50,7 +50,8 @@ impl<'a> QueryIterator<'a> {
|
||||
let state = TermIterState::Clause(Level::Root, 0, cell, ct.clone(), terms);
|
||||
QueryIterator { state_stack: vec![state] }
|
||||
},
|
||||
&QueryTerm::Cut => QueryIterator { state_stack: vec![] },
|
||||
&QueryTerm::BlockedCut | &QueryTerm::UnblockedCut =>
|
||||
QueryIterator { state_stack: vec![] },
|
||||
&QueryTerm::Jump(ref vars) => {
|
||||
let state_stack = vars.iter().rev().map(|t| {
|
||||
TermIterState::subterm_to_state(Level::Shallow, t)
|
||||
@@ -213,11 +214,24 @@ impl<'a> ChunkedTerm<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn contains_cut_var<'a, Iter: Iterator<Item=&'a Term>>(terms: Iter) -> bool {
|
||||
for term in terms {
|
||||
if let &Term::Var(_, ref var) = term {
|
||||
if var.as_str() == "!" {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
pub struct ChunkedIterator<'a>
|
||||
{
|
||||
pub chunk_num: usize,
|
||||
iter: Box<Iterator<Item=ChunkedTerm<'a>> + 'a>,
|
||||
deep_cut_encountered: bool
|
||||
deep_cut_encountered: bool,
|
||||
cut_var_in_head: bool
|
||||
}
|
||||
|
||||
type ChunkedIteratorItem<'a> = (usize, usize, Vec<ChunkedTerm<'a>>);
|
||||
@@ -248,7 +262,8 @@ impl<'a> ChunkedIterator<'a>
|
||||
ChunkedIterator {
|
||||
chunk_num: 0,
|
||||
iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))),
|
||||
deep_cut_encountered: false
|
||||
deep_cut_encountered: false,
|
||||
cut_var_in_head: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,7 +275,8 @@ impl<'a> ChunkedIterator<'a>
|
||||
ChunkedIterator {
|
||||
chunk_num: 0,
|
||||
iter: Box::new(iter),
|
||||
deep_cut_encountered: false
|
||||
deep_cut_encountered: false,
|
||||
cut_var_in_head: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,6 +292,7 @@ impl<'a> ChunkedIterator<'a>
|
||||
chunk_num: 0,
|
||||
iter: Box::new(iter),
|
||||
deep_cut_encountered: false,
|
||||
cut_var_in_head: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,20 +308,32 @@ impl<'a> ChunkedIterator<'a>
|
||||
|
||||
while let Some(term) = item {
|
||||
match term {
|
||||
ChunkedTerm::HeadClause(..) =>
|
||||
result.push(term),
|
||||
ChunkedTerm::HeadClause(_, terms) => {
|
||||
if contains_cut_var(terms.iter().map(|t| t.as_ref())) {
|
||||
self.cut_var_in_head = true;
|
||||
}
|
||||
|
||||
result.push(term);
|
||||
},
|
||||
ChunkedTerm::BodyTerm(&QueryTerm::Jump(ref vars)) => {
|
||||
result.push(term);
|
||||
arity = vars.len();
|
||||
|
||||
if contains_cut_var(vars.iter()) && !self.cut_var_in_head {
|
||||
self.deep_cut_encountered = true;
|
||||
}
|
||||
|
||||
break;
|
||||
},
|
||||
ChunkedTerm::BodyTerm(&QueryTerm::Cut) => {
|
||||
ChunkedTerm::BodyTerm(&QueryTerm::BlockedCut) => {
|
||||
result.push(term);
|
||||
|
||||
if self.chunk_num > 0 {
|
||||
self.deep_cut_encountered = true;
|
||||
}
|
||||
},
|
||||
ChunkedTerm::BodyTerm(&QueryTerm::UnblockedCut) =>
|
||||
result.push(term),
|
||||
ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), _)) =>
|
||||
result.push(term),
|
||||
ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::CallN, ref subterms)) => {
|
||||
|
||||
@@ -306,13 +306,12 @@ impl Machine {
|
||||
{
|
||||
for (var, var_data) in alloc_locs {
|
||||
match var_data {
|
||||
&VarData::Perm(_) => {
|
||||
&VarData::Perm(p) if p > 0 => {
|
||||
let e = self.ms.e;
|
||||
|
||||
let r = var_data.as_reg_type().reg_num();
|
||||
let addr = self.ms.and_stack[e][r].clone();
|
||||
|
||||
heap_locs.insert(var.clone(), addr);
|
||||
|
||||
heap_locs.insert(var.clone(), addr);
|
||||
},
|
||||
&VarData::Temp(cn, _, _) if cn == chunk_num => {
|
||||
let r = var_data.as_reg_type();
|
||||
|
||||
Submodule src/prolog/parser updated: ad4f9e5730...737d6ba091
Reference in New Issue
Block a user