optimizations up to section 5.7.
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1,6 +1,6 @@
|
|||||||
[root]
|
[root]
|
||||||
name = "rusty-wam"
|
name = "rusty-wam"
|
||||||
version = "0.5.3"
|
version = "0.5.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lalrpop 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lalrpop 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lalrpop-util 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lalrpop-util 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rusty-wam"
|
name = "rusty-wam"
|
||||||
version = "0.5.4"
|
version = "0.5.6"
|
||||||
authors = ["Mark Thom"]
|
authors = ["Mark Thom"]
|
||||||
|
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ pure Prolog.
|
|||||||
Pure Prolog is implemented as a simple REPL. "Pure Prolog" is Prolog
|
Pure Prolog is implemented as a simple REPL. "Pure Prolog" is Prolog
|
||||||
without cut, meta- or extra-logical operators, or side effects of any
|
without cut, meta- or extra-logical operators, or side effects of any
|
||||||
kind. In terms of the tutorial pacing, the work has progressed to the
|
kind. In terms of the tutorial pacing, the work has progressed to the
|
||||||
to the end of section 5.3, skipping past 5.4. Atoms and lists
|
to the end of section 5.6, skipping past 5.4. Atoms and lists are the
|
||||||
are the only two data types currently supported.
|
only two data types currently supported.
|
||||||
|
|
||||||
## Tutorial
|
## Tutorial
|
||||||
To enter a multi-clause predicate, the brackets ":{" and "}:" are used
|
To enter a multi-clause predicate, the brackets ":{" and "}:" are used
|
||||||
|
|||||||
@@ -117,6 +117,15 @@ pub struct Rule {
|
|||||||
pub clauses: Vec<Term>
|
pub clauses: Vec<Term>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Rule {
|
||||||
|
pub fn last_clause(&self) -> &Term {
|
||||||
|
match self.clauses.last() {
|
||||||
|
None => &self.head.1,
|
||||||
|
Some(clause) => clause
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum TermRef<'a> {
|
pub enum TermRef<'a> {
|
||||||
AnonVar(Level),
|
AnonVar(Level),
|
||||||
Cons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
|
Cons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
|
||||||
@@ -159,6 +168,7 @@ pub enum ControlInstruction {
|
|||||||
Allocate(usize),
|
Allocate(usize),
|
||||||
Call(Atom, usize),
|
Call(Atom, usize),
|
||||||
Deallocate,
|
Deallocate,
|
||||||
|
Execute(Atom, usize),
|
||||||
Proceed
|
Proceed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -517,7 +517,8 @@ impl<'a> CodeGenerator<'a> {
|
|||||||
vfs
|
vfs
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_conditional_call(compiled_query: &mut Code, term: &Term) {
|
fn add_conditional_call(compiled_query: &mut Code, term: &Term)
|
||||||
|
{
|
||||||
match term {
|
match term {
|
||||||
&Term::Constant(_, Constant::Atom(ref atom)) => {
|
&Term::Constant(_, Constant::Atom(ref atom)) => {
|
||||||
let call = ControlInstruction::Call(atom.clone(), 0);
|
let call = ControlInstruction::Call(atom.clone(), 0);
|
||||||
@@ -544,7 +545,9 @@ impl<'a> CodeGenerator<'a> {
|
|||||||
|
|
||||||
let mut body = Vec::new();
|
let mut body = Vec::new();
|
||||||
|
|
||||||
body.push(Line::Control(ControlInstruction::Allocate(perm_vars)));
|
if clauses.len() > 0 {
|
||||||
|
body.push(Line::Control(ControlInstruction::Allocate(perm_vars)));
|
||||||
|
}
|
||||||
|
|
||||||
self.marker.advance(p0);
|
self.marker.advance(p0);
|
||||||
body.push(Line::Fact(self.compile_target(p0, false)));
|
body.push(Line::Fact(self.compile_target(p0, false)));
|
||||||
@@ -561,7 +564,23 @@ impl<'a> CodeGenerator<'a> {
|
|||||||
body
|
body
|
||||||
});
|
});
|
||||||
|
|
||||||
body.push(Line::Control(ControlInstruction::Deallocate));
|
let last_arity = rule.last_clause().arity();
|
||||||
|
let mut dealloc_index = body.len() - 1;
|
||||||
|
|
||||||
|
match rule.last_clause() {
|
||||||
|
&Term::Clause(_, ref name, _)
|
||||||
|
| &Term::Constant(_, Constant::Atom(ref name)) => {
|
||||||
|
if let &mut Line::Control(ref mut ctrl) = body.last_mut().unwrap() {
|
||||||
|
*ctrl = ControlInstruction::Execute(name.clone(), last_arity);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => dealloc_index = body.len()
|
||||||
|
};
|
||||||
|
|
||||||
|
if clauses.len() > 0 {
|
||||||
|
body.insert(dealloc_index, Line::Control(ControlInstruction::Deallocate));
|
||||||
|
}
|
||||||
|
|
||||||
body
|
body
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ impl fmt::Display for ControlInstruction {
|
|||||||
write!(f, "call {}/{}", name, arity),
|
write!(f, "call {}/{}", name, arity),
|
||||||
&ControlInstruction::Deallocate =>
|
&ControlInstruction::Deallocate =>
|
||||||
write!(f, "deallocate"),
|
write!(f, "deallocate"),
|
||||||
|
&ControlInstruction::Execute(ref name, arity) =>
|
||||||
|
write!(f, "execute {}/{}", name, arity),
|
||||||
&ControlInstruction::Proceed =>
|
&ControlInstruction::Proceed =>
|
||||||
write!(f, "proceed")
|
write!(f, "proceed")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -682,19 +682,22 @@ impl MachineState {
|
|||||||
&ControlInstruction::Deallocate => {
|
&ControlInstruction::Deallocate => {
|
||||||
let e = self.e;
|
let e = self.e;
|
||||||
|
|
||||||
let num_frame_e = self.and_stack.top().unwrap().global_index;
|
self.cp = self.and_stack[e].cp;
|
||||||
let num_frame_b = self.or_stack
|
self.e = self.and_stack[e].e;
|
||||||
.top()
|
|
||||||
.map(|fr| fr.global_index)
|
|
||||||
.unwrap_or(0);
|
|
||||||
|
|
||||||
self.p = self.and_stack[e].cp;
|
self.p += 1;
|
||||||
self.e = self.and_stack[e].e;
|
},
|
||||||
|
&ControlInstruction::Execute(ref name, arity) => {
|
||||||
|
let compiled_tl_index = code_dir.get(&(name.clone(), arity))
|
||||||
|
.map(|index| *index);
|
||||||
|
|
||||||
if num_frame_e > num_frame_b {
|
match compiled_tl_index {
|
||||||
let top_e = self.and_stack.top().unwrap().e;
|
Some(compiled_tl_index) => {
|
||||||
self.and_stack.drop_frames(top_e - self.e + 1);
|
self.num_of_args = arity;
|
||||||
}
|
self.p = CodePtr::DirEntry(compiled_tl_index);
|
||||||
|
},
|
||||||
|
None => self.fail = true
|
||||||
|
};
|
||||||
},
|
},
|
||||||
&ControlInstruction::Proceed =>
|
&ControlInstruction::Proceed =>
|
||||||
self.p = self.cp,
|
self.p = self.cp,
|
||||||
|
|||||||
Reference in New Issue
Block a user