slight tweaks.
This commit is contained in:
@@ -32,6 +32,7 @@ impl AndStack {
|
|||||||
self.0.push(Frame::new(global_index, e, cp, n));
|
self.0.push(Frame::new(global_index, e, cp, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn top(&self) -> Option<&Frame> {
|
pub fn top(&self) -> Option<&Frame> {
|
||||||
self.0.last()
|
self.0.last()
|
||||||
}
|
}
|
||||||
@@ -45,6 +46,7 @@ impl AndStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// drop the last n frames.
|
// drop the last n frames.
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn drop_frames(&mut self, n: usize) {
|
pub fn drop_frames(&mut self, n: usize) {
|
||||||
let len = self.0.len();
|
let len = self.0.len();
|
||||||
self.0.truncate(len - n);
|
self.0.truncate(len - n);
|
||||||
|
|||||||
@@ -344,6 +344,14 @@ pub type Heap = Vec<HeapCellValue>;
|
|||||||
pub type Registers = Vec<Addr>;
|
pub type Registers = Vec<Addr>;
|
||||||
|
|
||||||
impl Term {
|
impl Term {
|
||||||
|
pub fn is_clause(&self) -> bool {
|
||||||
|
if let &Term::Clause(_, _, _) = self {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn subterms(&self) -> usize {
|
pub fn subterms(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
&Term::Clause(_, _, ref terms) => terms.len(),
|
&Term::Clause(_, _, ref terms) => terms.len(),
|
||||||
@@ -354,7 +362,6 @@ impl Term {
|
|||||||
pub fn name(&self) -> Option<&Atom> {
|
pub fn name(&self) -> Option<&Atom> {
|
||||||
match self {
|
match self {
|
||||||
&Term::Constant(_, Constant::Atom(ref atom))
|
&Term::Constant(_, Constant::Atom(ref atom))
|
||||||
| &Term::Var(_, ref atom)
|
|
||||||
| &Term::Clause(_, ref atom, _) => Some(atom),
|
| &Term::Clause(_, ref atom, _) => Some(atom),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -704,14 +704,18 @@ impl<'a> CodeGenerator<'a> {
|
|||||||
self.marker.advance(term);
|
self.marker.advance(term);
|
||||||
self.update_var_count(term.breadth_first_iter());
|
self.update_var_count(term.breadth_first_iter());
|
||||||
|
|
||||||
let mut compiled_fact = self.compile_target(term, false);
|
let mut code = Vec::new();
|
||||||
Self::mark_unsafe_fact_vars(&mut compiled_fact, self.vars());
|
|
||||||
|
if term.is_clause() {
|
||||||
let mut compiled_fact = vec![Line::Fact(compiled_fact)];
|
let mut compiled_fact = self.compile_target(term, false);
|
||||||
|
Self::mark_unsafe_fact_vars(&mut compiled_fact, self.vars());
|
||||||
|
code.push(Line::Fact(compiled_fact));
|
||||||
|
}
|
||||||
|
|
||||||
let proceed = Line::Control(ControlInstruction::Proceed);
|
let proceed = Line::Control(ControlInstruction::Proceed);
|
||||||
|
|
||||||
compiled_fact.push(proceed);
|
code.push(proceed);
|
||||||
compiled_fact
|
code
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_internal_query(&mut self, term: &'a Term, index: usize) -> Code
|
fn compile_internal_query(&mut self, term: &'a Term, index: usize) -> Code
|
||||||
@@ -719,20 +723,32 @@ impl<'a> CodeGenerator<'a> {
|
|||||||
self.marker.advance(term);
|
self.marker.advance(term);
|
||||||
self.update_var_count(term.breadth_first_iter());
|
self.update_var_count(term.breadth_first_iter());
|
||||||
|
|
||||||
let mut compiled_query = vec![Line::Query(self.compile_target(term, false))];
|
let mut code = Vec::new();
|
||||||
Self::add_conditional_call(&mut compiled_query, term, index);
|
|
||||||
|
|
||||||
compiled_query
|
if term.is_clause() {
|
||||||
|
let compiled_query = Line::Query(self.compile_target(term, false));
|
||||||
|
code.push(compiled_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::add_conditional_call(&mut code, term, index);
|
||||||
|
|
||||||
|
code
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_query(&mut self, term: &'a Term) -> Code {
|
pub fn compile_query(&mut self, term: &'a Term) -> Code {
|
||||||
self.marker.advance(term);
|
self.marker.advance(term);
|
||||||
self.update_var_count(term.breadth_first_iter());
|
self.update_var_count(term.breadth_first_iter());
|
||||||
|
|
||||||
let mut compiled_query = vec![Line::Query(self.compile_target(term, true))];
|
let mut code = Vec::new();
|
||||||
Self::add_conditional_call(&mut compiled_query, term, 0);
|
|
||||||
|
|
||||||
compiled_query
|
if term.is_clause() {
|
||||||
|
let compiled_query = Line::Query(self.compile_target(term, false));
|
||||||
|
code.push(compiled_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::add_conditional_call(&mut code, term, 0);
|
||||||
|
|
||||||
|
code
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_predicate(&mut self, clauses: &'a Vec<PredicateClause>) -> Code
|
pub fn compile_predicate(&mut self, clauses: &'a Vec<PredicateClause>) -> Code
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ pub fn eval(wam: &mut Machine, buffer: &str) -> EvalResult
|
|||||||
match &result {
|
match &result {
|
||||||
&Ok(TopLevel::Predicate(ref clauses)) => {
|
&Ok(TopLevel::Predicate(ref clauses)) => {
|
||||||
if is_consistent(clauses) {
|
if is_consistent(clauses) {
|
||||||
let compiled_pred = cg.compile_predicate(clauses);
|
let compiled_pred = cg.compile_predicate(clauses);
|
||||||
wam.add_predicate(clauses, compiled_pred);
|
wam.add_predicate(clauses, compiled_pred);
|
||||||
|
|
||||||
EvalResult::EntrySuccess
|
EvalResult::EntrySuccess
|
||||||
@@ -231,17 +231,17 @@ Each predicate must have the same name and arity.";
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
&Ok(TopLevel::Fact(ref fact)) => {
|
&Ok(TopLevel::Fact(ref fact)) => {
|
||||||
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);
|
||||||
EvalResult::EntrySuccess
|
EvalResult::EntrySuccess
|
||||||
},
|
},
|
||||||
&Ok(TopLevel::Rule(ref rule)) => {
|
&Ok(TopLevel::Rule(ref rule)) => {
|
||||||
let compiled_rule = cg.compile_rule(&rule);
|
let compiled_rule = cg.compile_rule(&rule);
|
||||||
wam.add_rule(rule, compiled_rule);
|
wam.add_rule(rule, compiled_rule);
|
||||||
EvalResult::EntrySuccess
|
EvalResult::EntrySuccess
|
||||||
},
|
},
|
||||||
&Ok(TopLevel::Query(ref query)) => {
|
&Ok(TopLevel::Query(ref query)) => {
|
||||||
let compiled_query = cg.compile_query(&query);
|
let compiled_query = cg.compile_query(&query);
|
||||||
wam.run_query(compiled_query, &cg)
|
wam.run_query(compiled_query, &cg)
|
||||||
},
|
},
|
||||||
&Err(_) => {
|
&Err(_) => {
|
||||||
|
|||||||
@@ -81,24 +81,22 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_fact(&mut self, fact: &Term, mut code: Code) {
|
pub fn add_fact(&mut self, fact: &Term, mut code: Code) {
|
||||||
if fact.name().is_some() {
|
if let Some(name) = fact.name() {
|
||||||
let p = self.code.len();
|
let p = self.code.len();
|
||||||
let name = fact.name().unwrap().clone();
|
|
||||||
let arity = fact.arity();
|
let arity = fact.arity();
|
||||||
|
|
||||||
self.code.append(&mut code);
|
self.code.append(&mut code);
|
||||||
self.code_dir.insert((name, arity), p);
|
self.code_dir.insert((name.clone(), arity), p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_rule(&mut self, rule: &Rule, mut code: Code) {
|
pub fn add_rule(&mut self, rule: &Rule, mut code: Code) {
|
||||||
if rule.head.0.name().is_some() {
|
if let Some(name) = rule.head.0.name() {
|
||||||
let p = self.code.len();
|
let p = self.code.len();
|
||||||
let name = rule.head.0.name().unwrap().clone();
|
|
||||||
let arity = rule.head.0.arity();
|
let arity = rule.head.0.arity();
|
||||||
|
|
||||||
self.code.append(&mut code);
|
self.code.append(&mut code);
|
||||||
self.code_dir.insert((name, arity), p);
|
self.code_dir.insert((name.clone(), arity), p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ impl OrStack {
|
|||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.0.clear()
|
self.0.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn top(&self) -> Option<&Frame> {
|
pub fn top(&self) -> Option<&Frame> {
|
||||||
self.0.last()
|
self.0.last()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user