evacuate arguments on overwrite.
This commit is contained in:
@@ -611,7 +611,11 @@ mod tests {
|
|||||||
assert_eq!(submit(&mut wam, "?- f(p(three), X, X)."), false);
|
assert_eq!(submit(&mut wam, "?- f(p(three), X, X)."), false);
|
||||||
assert_eq!(submit(&mut wam, "?- f(p(three), one, Y)."), false);
|
assert_eq!(submit(&mut wam, "?- f(p(three), one, Y)."), false);
|
||||||
assert_eq!(submit(&mut wam, "?- f(p(three), one, two)."), false);
|
assert_eq!(submit(&mut wam, "?- f(p(three), one, two)."), false);
|
||||||
assert_eq!(submit(&mut wam, "?- f(p(three), one, three)."), false);
|
assert_eq!(submit(&mut wam, "?- f(p(three), one, three)."), false);
|
||||||
|
|
||||||
|
submit(&mut wam, "f(P, X) :- call(P, X).");
|
||||||
|
|
||||||
|
assert_eq!(submit(&mut wam, "?- f(p(one), one)."), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,15 @@ pub enum GenContext {
|
|||||||
Head, Mid(usize), Last(usize) // Mid & Last: chunk_num
|
Head, Mid(usize), Last(usize) // Mid & Last: chunk_num
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GenContext {
|
||||||
|
pub fn chunk_num(self) -> usize {
|
||||||
|
match self {
|
||||||
|
GenContext::Head => 0,
|
||||||
|
GenContext::Mid(cn) | GenContext::Last(cn) => cn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum PredicateClause {
|
pub enum PredicateClause {
|
||||||
Fact(Term),
|
Fact(Term),
|
||||||
Rule(Rule)
|
Rule(Rule)
|
||||||
@@ -115,7 +124,7 @@ pub enum Term {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub enum QueryTerm {
|
pub enum QueryTerm {
|
||||||
CallN(Cell<VarReg>, Var, Vec<Box<Term>>),
|
CallN(Vec<Box<Term>>),
|
||||||
Cut,
|
Cut,
|
||||||
Term(Term)
|
Term(Term)
|
||||||
}
|
}
|
||||||
@@ -124,15 +133,15 @@ impl QueryTerm {
|
|||||||
pub fn arity(&self) -> usize {
|
pub fn arity(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
&QueryTerm::Term(ref term) => term.arity(),
|
&QueryTerm::Term(ref term) => term.arity(),
|
||||||
&QueryTerm::CallN(_, _, ref terms) => terms.len() + 1,
|
&QueryTerm::CallN(ref terms) => terms.len(),
|
||||||
_ => 0
|
_ => 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_ref(&self) -> QueryTermRef {
|
pub fn to_ref(&self) -> QueryTermRef {
|
||||||
match self {
|
match self {
|
||||||
&QueryTerm::CallN(ref cell, ref var, ref terms) =>
|
&QueryTerm::CallN(ref terms) =>
|
||||||
QueryTermRef::CallN(cell, var, terms),
|
QueryTermRef::CallN(terms),
|
||||||
&QueryTerm::Cut =>
|
&QueryTerm::Cut =>
|
||||||
QueryTermRef::Cut,
|
QueryTermRef::Cut,
|
||||||
&QueryTerm::Term(ref term) =>
|
&QueryTerm::Term(ref term) =>
|
||||||
@@ -148,7 +157,7 @@ pub struct Rule {
|
|||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum ClauseType<'a> {
|
pub enum ClauseType<'a> {
|
||||||
CallN(&'a Cell<VarReg>, &'a Var),
|
CallN,
|
||||||
Deep(Level, &'a Cell<RegType>, &'a Atom),
|
Deep(Level, &'a Cell<RegType>, &'a Atom),
|
||||||
Root
|
Root
|
||||||
}
|
}
|
||||||
@@ -156,7 +165,7 @@ pub enum ClauseType<'a> {
|
|||||||
impl<'a> ClauseType<'a> {
|
impl<'a> ClauseType<'a> {
|
||||||
pub fn level_of_subterms(self) -> Level {
|
pub fn level_of_subterms(self) -> Level {
|
||||||
match self {
|
match self {
|
||||||
ClauseType::CallN(_, _) => Level::Shallow,
|
ClauseType::CallN => Level::Shallow,
|
||||||
ClauseType::Deep(_, _, _) => Level::Deep,
|
ClauseType::Deep(_, _, _) => Level::Deep,
|
||||||
ClauseType::Root => Level::Shallow
|
ClauseType::Root => Level::Shallow
|
||||||
}
|
}
|
||||||
@@ -181,14 +190,14 @@ impl<'a> TermRef<'a> {
|
|||||||
| TermRef::Var(lvl, _, _) => lvl,
|
| TermRef::Var(lvl, _, _) => lvl,
|
||||||
TermRef::Clause(ClauseType::Root, _) => Level::Shallow,
|
TermRef::Clause(ClauseType::Root, _) => Level::Shallow,
|
||||||
TermRef::Clause(ClauseType::Deep(lvl, _, _), _) => lvl,
|
TermRef::Clause(ClauseType::Deep(lvl, _, _), _) => lvl,
|
||||||
TermRef::Clause(ClauseType::CallN(_, _), _) => Level::Shallow
|
TermRef::Clause(ClauseType::CallN, _) => Level::Shallow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum QueryTermRef<'a> {
|
pub enum QueryTermRef<'a> {
|
||||||
CallN(&'a Cell<VarReg>, &'a Var, &'a Vec<Box<Term>>),
|
CallN(&'a Vec<Box<Term>>),
|
||||||
Cut,
|
Cut,
|
||||||
Term(&'a Term)
|
Term(&'a Term)
|
||||||
}
|
}
|
||||||
@@ -197,7 +206,7 @@ impl<'a> QueryTermRef<'a> {
|
|||||||
pub fn arity(self) -> usize {
|
pub fn arity(self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
QueryTermRef::Term(term) => term.arity(),
|
QueryTermRef::Term(term) => term.arity(),
|
||||||
QueryTermRef::CallN(_, _, terms) => terms.len() + 1,
|
QueryTermRef::CallN(terms) => terms.len(),
|
||||||
_ => 0
|
_ => 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,8 +215,7 @@ impl<'a> QueryTermRef<'a> {
|
|||||||
match self {
|
match self {
|
||||||
QueryTermRef::Term(&Term::Clause(_, _, _))
|
QueryTermRef::Term(&Term::Clause(_, _, _))
|
||||||
| QueryTermRef::Term(&Term::Constant(_, Constant::Atom(_)))
|
| QueryTermRef::Term(&Term::Constant(_, Constant::Atom(_)))
|
||||||
| QueryTermRef::CallN(_, _, _) =>
|
| QueryTermRef::CallN(_) => true,
|
||||||
true,
|
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,10 +97,6 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
|||||||
where Target: CompilationTarget<'a>
|
where Target: CompilationTarget<'a>
|
||||||
{
|
{
|
||||||
match ct {
|
match ct {
|
||||||
ClauseType::CallN(_, _) =>
|
|
||||||
for subterm in terms {
|
|
||||||
self.subterm_to_instr(subterm.as_ref(), term_loc, is_exposed, target);
|
|
||||||
},
|
|
||||||
ClauseType::Deep(lvl, cell, atom) => {
|
ClauseType::Deep(lvl, cell, atom) => {
|
||||||
self.marker.mark_non_var(lvl, term_loc, cell, target);
|
self.marker.mark_non_var(lvl, term_loc, cell, target);
|
||||||
target.push(Target::to_structure(lvl, atom.clone(), terms.len(), cell.get()));
|
target.push(Target::to_structure(lvl, atom.clone(), terms.len(), cell.get()));
|
||||||
@@ -182,7 +178,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
|||||||
fn add_conditional_call(compiled_query: &mut Code, qt: QueryTermRef, pvs: usize)
|
fn add_conditional_call(compiled_query: &mut Code, qt: QueryTermRef, pvs: usize)
|
||||||
{
|
{
|
||||||
match qt {
|
match qt {
|
||||||
QueryTermRef::CallN(_, _, terms) => {
|
QueryTermRef::CallN(terms) => {
|
||||||
let call = ControlInstruction::CallN(terms.len());
|
let call = ControlInstruction::CallN(terms.len());
|
||||||
compiled_query.push(Line::Control(call));
|
compiled_query.push(Line::Control(call));
|
||||||
},
|
},
|
||||||
@@ -209,7 +205,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
|
|||||||
if let &mut Line::Control(ref mut ctrl) = body.last_mut().unwrap() {
|
if let &mut Line::Control(ref mut ctrl) = body.last_mut().unwrap() {
|
||||||
*ctrl = ControlInstruction::Execute(name.clone(), last_arity);
|
*ctrl = ControlInstruction::Execute(name.clone(), last_arity);
|
||||||
},
|
},
|
||||||
&QueryTerm::CallN(_, _, ref terms) =>
|
&QueryTerm::CallN(ref terms) =>
|
||||||
if let &mut Line::Control(ref mut ctrl) = body.last_mut().unwrap() {
|
if let &mut Line::Control(ref mut ctrl) = body.last_mut().unwrap() {
|
||||||
*ctrl = ControlInstruction::ExecuteN(terms.len());
|
*ctrl = ControlInstruction::ExecuteN(terms.len());
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,7 +14,14 @@ pub struct DebrayAllocator<'a> {
|
|||||||
in_use: BTreeSet<usize>,
|
in_use: BTreeSet<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DebrayAllocator<'a> {
|
impl<'a> DebrayAllocator<'a> {
|
||||||
|
fn is_curr_arg_distinct_from(&self, var: &'a Var) -> bool {
|
||||||
|
match self.contents.get(&self.arg_c) {
|
||||||
|
Some(t_var) if **t_var != *var => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn occurs_shallowly_in_head(&self, var: &'a Var, r: usize) -> bool
|
fn occurs_shallowly_in_head(&self, var: &'a Var, r: usize) -> bool
|
||||||
{
|
{
|
||||||
match self.bindings.get(var).unwrap() {
|
match self.bindings.get(var).unwrap() {
|
||||||
@@ -142,6 +149,7 @@ impl<'a> DebrayAllocator<'a> {
|
|||||||
match term_loc {
|
match term_loc {
|
||||||
GenContext::Head =>
|
GenContext::Head =>
|
||||||
if let Level::Shallow = lvl {
|
if let Level::Shallow = lvl {
|
||||||
|
self.evacuate_arg(0, target);
|
||||||
self.alloc_with_cr(var)
|
self.alloc_with_cr(var)
|
||||||
} else {
|
} else {
|
||||||
self.alloc_with_ca(var)
|
self.alloc_with_ca(var)
|
||||||
@@ -262,14 +270,22 @@ impl<'a> Allocator<'a> for DebrayAllocator<'a>
|
|||||||
RegType::Perm(0) => {
|
RegType::Perm(0) => {
|
||||||
let pr = cell.get().norm();
|
let pr = cell.get().norm();
|
||||||
self.record_register(var, pr);
|
self.record_register(var, pr);
|
||||||
|
|
||||||
(pr, true)
|
(pr, true)
|
||||||
},
|
},
|
||||||
r => (r, false)
|
r => (r, false)
|
||||||
};
|
};
|
||||||
|
|
||||||
match lvl {
|
match lvl {
|
||||||
Level::Shallow => {
|
Level::Shallow => {
|
||||||
let k = self.arg_c;
|
let k = self.arg_c;
|
||||||
|
|
||||||
|
if !r.is_perm() {
|
||||||
|
if self.is_curr_arg_distinct_from(var) {
|
||||||
|
self.evacuate_arg(term_loc.chunk_num(), target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.arg_c += 1;
|
self.arg_c += 1;
|
||||||
|
|
||||||
cell.set(VarReg::ArgAndNorm(r, k));
|
cell.set(VarReg::ArgAndNorm(r, k));
|
||||||
@@ -295,14 +311,14 @@ impl<'a> Allocator<'a> for DebrayAllocator<'a>
|
|||||||
Level::Deep =>
|
Level::Deep =>
|
||||||
target.push(Target::subterm_to_value(r))
|
target.push(Target::subterm_to_value(r))
|
||||||
};
|
};
|
||||||
|
|
||||||
if !r.is_perm() {
|
if !r.is_perm() {
|
||||||
let o = r.reg_num();
|
let o = r.reg_num();
|
||||||
|
|
||||||
self.contents.insert(o, var);
|
self.contents.insert(o, var);
|
||||||
self.record_register(var, r);
|
self.record_register(var, r);
|
||||||
self.in_use.insert(o);
|
self.in_use.insert(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset(&mut self) {
|
fn reset(&mut self) {
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ Each predicate must have the same name and arity.";
|
|||||||
|
|
||||||
let compiled_fact = cg.compile_fact(fact);
|
let compiled_fact = cg.compile_fact(fact);
|
||||||
wam.add_fact(fact, compiled_fact);
|
wam.add_fact(fact, compiled_fact);
|
||||||
|
|
||||||
EvalSession::EntrySuccess
|
EvalSession::EntrySuccess
|
||||||
},
|
},
|
||||||
&TopLevel::Rule(ref rule) => {
|
&TopLevel::Rule(ref rule) => {
|
||||||
|
|||||||
@@ -69,9 +69,8 @@ impl<'a> QueryIterator<'a> {
|
|||||||
|
|
||||||
fn new(term: QueryTermRef<'a>) -> Self {
|
fn new(term: QueryTermRef<'a>) -> Self {
|
||||||
match term {
|
match term {
|
||||||
QueryTermRef::CallN(cell, var, child_terms) => {
|
QueryTermRef::CallN(child_terms) => {
|
||||||
let state = IteratorState::Clause(0, ClauseType::CallN(cell, var), child_terms);
|
let state = IteratorState::Clause(0, ClauseType::CallN, child_terms);
|
||||||
|
|
||||||
QueryIterator { state_stack: vec![state] }
|
QueryIterator { state_stack: vec![state] }
|
||||||
},
|
},
|
||||||
QueryTermRef::Term(term) => Self::from_term(term),
|
QueryTermRef::Term(term) => Self::from_term(term),
|
||||||
@@ -97,14 +96,10 @@ impl<'a> Iterator for QueryIterator<'a> {
|
|||||||
IteratorState::Clause(child_num, ct, child_terms) => {
|
IteratorState::Clause(child_num, ct, child_terms) => {
|
||||||
if child_num == child_terms.len() {
|
if child_num == child_terms.len() {
|
||||||
match ct {
|
match ct {
|
||||||
ClauseType::Root =>
|
ClauseType::CallN | ClauseType::Root =>
|
||||||
return None,
|
return None,
|
||||||
ClauseType::Deep(_, _, _) =>
|
ClauseType::Deep(_, _, _) =>
|
||||||
return Some(TermRef::Clause(ct, child_terms)),
|
return Some(TermRef::Clause(ct, child_terms))
|
||||||
ClauseType::CallN(cell, var) => {
|
|
||||||
let state = IteratorState::Var(Level::Shallow, cell, var);
|
|
||||||
self.state_stack.push(state);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
self.push_clause(child_num + 1, ct, child_terms);
|
self.push_clause(child_num + 1, ct, child_terms);
|
||||||
@@ -172,15 +167,11 @@ impl<'a> Iterator for FactIterator<'a> {
|
|||||||
self.push_subterm(ct.level_of_subterms(), child_term);
|
self.push_subterm(ct.level_of_subterms(), child_term);
|
||||||
}
|
}
|
||||||
|
|
||||||
match ct {
|
match ct {
|
||||||
ClauseType::Root =>
|
|
||||||
continue,
|
|
||||||
ClauseType::Deep(_, _, _) =>
|
ClauseType::Deep(_, _, _) =>
|
||||||
return Some(TermRef::Clause(ct, child_terms)),
|
return Some(TermRef::Clause(ct, child_terms)),
|
||||||
ClauseType::CallN(cell, var) => {
|
_ =>
|
||||||
let state = IteratorState::Var(Level::Shallow, cell, var);
|
continue
|
||||||
self.state_queue.push_back(state);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
IteratorState::InitialCons(lvl, cell, head, tail) => {
|
IteratorState::InitialCons(lvl, cell, head, tail) => {
|
||||||
@@ -249,8 +240,8 @@ impl<'a> ChunkedIterator<'a>
|
|||||||
let iter = once(QueryTermRef::Term(p0));
|
let iter = once(QueryTermRef::Term(p0));
|
||||||
|
|
||||||
let inner_iter : Box<Iterator<Item=QueryTermRef<'a>>> = match p1 {
|
let inner_iter : Box<Iterator<Item=QueryTermRef<'a>>> = match p1 {
|
||||||
&QueryTerm::CallN(ref cell, ref var, ref child_terms) =>
|
&QueryTerm::CallN(ref child_terms) =>
|
||||||
Box::new(once(QueryTermRef::CallN(cell, var, child_terms))),
|
Box::new(once(QueryTermRef::CallN(child_terms))),
|
||||||
&QueryTerm::Term(ref p1) =>
|
&QueryTerm::Term(ref p1) =>
|
||||||
Box::new(once(QueryTermRef::Term(p1))),
|
Box::new(once(QueryTermRef::Term(p1))),
|
||||||
_ => Box::new(empty())
|
_ => Box::new(empty())
|
||||||
@@ -288,7 +279,7 @@ impl<'a> ChunkedIterator<'a>
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
QueryTermRef::CallN(_, _, child_terms) => {
|
QueryTermRef::CallN(child_terms) => {
|
||||||
result.push(term);
|
result.push(term);
|
||||||
arity = child_terms.len() + 1;
|
arity = child_terms.len() + 1;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -994,7 +994,7 @@ impl MachineState {
|
|||||||
&ControlInstruction::Call(ref name, arity, _) =>
|
&ControlInstruction::Call(ref name, arity, _) =>
|
||||||
self.try_call_predicate(code_dir, name.clone(), arity),
|
self.try_call_predicate(code_dir, name.clone(), arity),
|
||||||
&ControlInstruction::CallN(arity) => {
|
&ControlInstruction::CallN(arity) => {
|
||||||
let addr = self.deref(self.registers[arity + 1].clone());
|
let addr = self.deref(self.registers[arity].clone());
|
||||||
|
|
||||||
match self.store(addr) {
|
match self.store(addr) {
|
||||||
Addr::Str(a) => {
|
Addr::Str(a) => {
|
||||||
@@ -1006,13 +1006,13 @@ impl MachineState {
|
|||||||
self.registers[i] = self.heap[a + i].as_addr(a + i);
|
self.registers[i] = self.heap[a + i].as_addr(a + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.try_call_predicate(code_dir, name, arity + narity);
|
self.try_call_predicate(code_dir, name, arity + narity - 1);
|
||||||
} else {
|
} else {
|
||||||
self.fail = true;
|
self.fail = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Addr::Con(Constant::Atom(name)) =>
|
Addr::Con(Constant::Atom(name)) =>
|
||||||
self.try_call_predicate(code_dir, name, arity),
|
self.try_call_predicate(code_dir, name, arity - 1),
|
||||||
_ => self.fail = true
|
_ => self.fail = true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -1027,7 +1027,7 @@ impl MachineState {
|
|||||||
&ControlInstruction::Execute(ref name, arity) =>
|
&ControlInstruction::Execute(ref name, arity) =>
|
||||||
self.try_execute_predicate(code_dir, name.clone(), arity),
|
self.try_execute_predicate(code_dir, name.clone(), arity),
|
||||||
&ControlInstruction::ExecuteN(arity) => {
|
&ControlInstruction::ExecuteN(arity) => {
|
||||||
let addr = self.deref(self.registers[arity + 1].clone());
|
let addr = self.deref(self.registers[arity].clone());
|
||||||
|
|
||||||
match self.store(addr) {
|
match self.store(addr) {
|
||||||
Addr::Str(a) => {
|
Addr::Str(a) => {
|
||||||
@@ -1039,13 +1039,13 @@ impl MachineState {
|
|||||||
self.registers[i] = self.heap[a + i].as_addr(a + i);
|
self.registers[i] = self.heap[a + i].as_addr(a + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.try_execute_predicate(code_dir, name, arity + narity);
|
self.try_execute_predicate(code_dir, name, arity + narity - 1);
|
||||||
} else {
|
} else {
|
||||||
self.fail = true;
|
self.fail = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Addr::Con(Constant::Atom(name)) =>
|
Addr::Con(Constant::Atom(name)) =>
|
||||||
self.try_execute_predicate(code_dir, name, arity),
|
self.try_execute_predicate(code_dir, name, arity - 1),
|
||||||
_ => self.fail = true
|
_ => self.fail = true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -32,8 +32,13 @@ Call : QueryTerm = {
|
|||||||
},
|
},
|
||||||
"call" "(" <a:Atom> <ts: ("," <BoxedTerm>)*> ")" =>
|
"call" "(" <a:Atom> <ts: ("," <BoxedTerm>)*> ")" =>
|
||||||
QueryTerm::Term(Term::Clause(Cell::default(), a, ts)),
|
QueryTerm::Term(Term::Clause(Cell::default(), a, ts)),
|
||||||
"call" "(" <v:Var> <ts: ("," <BoxedTerm>)*> ")" =>
|
"call" "(" <v:Var> <ts: ("," <BoxedTerm>)*> ")" => {
|
||||||
QueryTerm::CallN(Cell::default(), v, ts)
|
let mut ts = ts;
|
||||||
|
let bv = Box::new(Term::Var(Cell::default(), v));
|
||||||
|
|
||||||
|
ts.push(bv);
|
||||||
|
QueryTerm::CallN(ts)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Clause : Term = {
|
Clause : Term = {
|
||||||
@@ -93,7 +98,7 @@ Rule : Rule = {
|
|||||||
QueryTerm : QueryTerm = {
|
QueryTerm : QueryTerm = {
|
||||||
<Call> => <>,
|
<Call> => <>,
|
||||||
"!" => QueryTerm::Cut,
|
"!" => QueryTerm::Cut,
|
||||||
<Var> => QueryTerm::CallN(Cell::default(), <>, Vec::new()),
|
<Var> => QueryTerm::CallN(vec![Box::new(Term::Var(Cell::default(), <>))]),
|
||||||
<Clause> => QueryTerm::Term(<>),
|
<Clause> => QueryTerm::Term(<>),
|
||||||
<Atom> => QueryTerm::Term(Term::Constant(Cell::default(), Constant::Atom(<>)))
|
<Atom> => QueryTerm::Term(Term::Constant(Cell::default(), Constant::Atom(<>)))
|
||||||
};
|
};
|
||||||
@@ -108,4 +113,4 @@ Term : Term = {
|
|||||||
|
|
||||||
Var : Var = {
|
Var : Var = {
|
||||||
r"[A-Z][A-Za-z0-9_]*" => <>.trim().to_string()
|
r"[A-Z][A-Za-z0-9_]*" => <>.trim().to_string()
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2901,7 +2901,13 @@ pub fn __action9<
|
|||||||
(_, _, _): (usize, &'input str, usize),
|
(_, _, _): (usize, &'input str, usize),
|
||||||
) -> QueryTerm
|
) -> QueryTerm
|
||||||
{
|
{
|
||||||
QueryTerm::CallN(Cell::default(), v, ts)
|
{
|
||||||
|
let mut ts = ts;
|
||||||
|
let bv = Box::new(Term::Var(Cell::default(), v));
|
||||||
|
|
||||||
|
ts.push(bv);
|
||||||
|
QueryTerm::CallN(ts)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
@@ -3105,7 +3111,7 @@ pub fn __action24<
|
|||||||
(_, __0, _): (usize, Var, usize),
|
(_, __0, _): (usize, Var, usize),
|
||||||
) -> QueryTerm
|
) -> QueryTerm
|
||||||
{
|
{
|
||||||
QueryTerm::CallN(Cell::default(), __0, Vec::new())
|
QueryTerm::CallN(vec![Box::new(Term::Var(Cell::default(), __0))])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
|
|||||||
Reference in New Issue
Block a user