cleanup of run_query

This commit is contained in:
Mark Thom
2017-05-08 14:33:27 -06:00
parent f155b5b2c2
commit 9c72177b60
7 changed files with 72 additions and 71 deletions

2
Cargo.lock generated
View File

@@ -1,6 +1,6 @@
[root]
name = "rusty-wam"
version = "0.6.1"
version = "0.6.2"
dependencies = [
"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)",

View File

@@ -1,6 +1,6 @@
[package]
name = "rusty-wam"
version = "0.6.1"
version = "0.6.2"
authors = ["Mark Thom"]
build = "build.rs"

View File

@@ -16,9 +16,9 @@ mod tests {
match parse_TopLevel(buffer.trim()) {
Ok(tl) =>
match eval(wam, &tl) {
EvalResult::InitialQuerySuccess(_, _) |
EvalResult::EntrySuccess |
EvalResult::SubsequentQuerySuccess =>
EvalSession::InitialQuerySuccess(_, _) |
EvalSession::EntrySuccess |
EvalSession::SubsequentQuerySuccess =>
true,
_ => false
},

View File

@@ -213,6 +213,16 @@ pub enum ControlInstruction {
Proceed
}
impl ControlInstruction {
pub fn is_jump_instr(&self) -> bool {
match self {
&ControlInstruction::Call(_, _, _) => true,
&ControlInstruction::Execute(_, _) => true,
_ => false
}
}
}
pub enum IndexingInstruction {
SwitchOnTerm(usize, usize, usize, usize),
SwitchOnConstant(usize, HashMap<Constant, usize>),
@@ -362,7 +372,7 @@ impl HeapCellValue {
#[derive(Clone, Copy, PartialEq)]
pub enum CodePtr {
DirEntry(usize),
TopLevel(usize, usize, usize) // chunk_num, e, offset.
TopLevel(usize, usize) // chunk_num, offset.
}
impl PartialOrd<CodePtr> for CodePtr {
@@ -370,9 +380,9 @@ impl PartialOrd<CodePtr> for CodePtr {
match (self, other) {
(&CodePtr::DirEntry(p1), &CodePtr::DirEntry(ref p2)) =>
p1.partial_cmp(p2),
(&CodePtr::DirEntry(_), &CodePtr::TopLevel(_, _, _)) =>
(&CodePtr::DirEntry(_), &CodePtr::TopLevel(_, _)) =>
Some(Ordering::Less),
(&CodePtr::TopLevel(_, _, p1), &CodePtr::TopLevel(_, _, ref p2)) =>
(&CodePtr::TopLevel(_, p1), &CodePtr::TopLevel(_, ref p2)) =>
p1.partial_cmp(p2),
_ => Some(Ordering::Greater)
}
@@ -381,7 +391,7 @@ impl PartialOrd<CodePtr> for CodePtr {
impl Default for CodePtr {
fn default() -> Self {
CodePtr::TopLevel(0, 0, 0)
CodePtr::TopLevel(0, 0)
}
}
@@ -391,7 +401,7 @@ impl Add<usize> for CodePtr {
fn add(self, rhs: usize) -> Self::Output {
match self {
CodePtr::DirEntry(p) => CodePtr::DirEntry(p + rhs),
CodePtr::TopLevel(cn, e, p) => CodePtr::TopLevel(cn, e, p + rhs)
CodePtr::TopLevel(cn, p) => CodePtr::TopLevel(cn, p + rhs)
}
}
}
@@ -400,7 +410,7 @@ impl AddAssign<usize> for CodePtr {
fn add_assign(&mut self, rhs: usize) {
match self {
&mut CodePtr::DirEntry(ref mut p) |
&mut CodePtr::TopLevel(_, _, ref mut p) => *p += rhs
&mut CodePtr::TopLevel(_, ref mut p) => *p += rhs
}
}
}

View File

@@ -14,7 +14,7 @@ pub struct CodeGenerator<'a, TermMarker> {
var_count: HashMap<&'a Var, usize>
}
pub enum EvalResult<'a> {
pub enum EvalSession<'a> {
EntryFailure,
EntrySuccess,
InitialQuerySuccess(AllocVarDict<'a>, HeapVarDict<'a>),
@@ -22,10 +22,10 @@ pub enum EvalResult<'a> {
SubsequentQuerySuccess,
}
impl<'a> EvalResult<'a> {
impl<'a> EvalSession<'a> {
#[allow(dead_code)]
pub fn failed_query(&self) -> bool {
if let &EvalResult::QueryFailure = self {
if let &EvalSession::QueryFailure = self {
true
} else {
false

View File

@@ -257,7 +257,7 @@ pub fn read() -> String {
result
}
pub fn eval<'a, 'b: 'a>(wam: &'a mut Machine, tl: &'b TopLevel) -> EvalResult<'b>
pub fn eval<'a, 'b: 'a>(wam: &'a mut Machine, tl: &'b TopLevel) -> EvalSession<'b>
{
match tl {
&TopLevel::Predicate(ref clauses) => {
@@ -267,13 +267,13 @@ pub fn eval<'a, 'b: 'a>(wam: &'a mut Machine, tl: &'b TopLevel) -> EvalResult<'b
let compiled_pred = cg.compile_predicate(clauses);
wam.add_predicate(clauses, compiled_pred);
EvalResult::EntrySuccess
EvalSession::EntrySuccess
} else {
let msg = r"Error: predicate is inconsistent.
Each predicate must have the same name and arity.";
println!("{}", msg);
EvalResult::EntryFailure
EvalSession::EntryFailure
}
},
&TopLevel::Fact(ref fact) => {
@@ -282,7 +282,7 @@ Each predicate must have the same name and arity.";
let compiled_fact = cg.compile_fact(fact);
wam.add_fact(fact, compiled_fact);
EvalResult::EntrySuccess
EvalSession::EntrySuccess
},
&TopLevel::Rule(ref rule) => {
let mut cg = CodeGenerator::<DebrayAllocator>::new();
@@ -290,7 +290,7 @@ Each predicate must have the same name and arity.";
let compiled_rule = cg.compile_rule(rule);
wam.add_rule(rule, compiled_rule);
EvalResult::EntrySuccess
EvalSession::EntrySuccess
},
&TopLevel::Query(ref query) => {
let mut cg = CodeGenerator::<DebrayAllocator>::new();
@@ -301,9 +301,9 @@ Each predicate must have the same name and arity.";
}
}
pub fn print(wam: &mut Machine, result: EvalResult) {
pub fn print(wam: &mut Machine, result: EvalSession) {
match result {
EvalResult::InitialQuerySuccess(alloc_locs, mut heap_locs) => {
EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => {
println!("yes");
if heap_locs.is_empty() {
@@ -311,7 +311,7 @@ pub fn print(wam: &mut Machine, result: EvalResult) {
}
'outer: loop {
let mut result = EvalResult::QueryFailure;
let mut result = EvalSession::QueryFailure;
let bindings = wam.heap_view(&heap_locs);
let stdin = stdin();
@@ -336,7 +336,7 @@ pub fn print(wam: &mut Machine, result: EvalResult) {
}
}
if let &EvalResult::QueryFailure = &result {
if let &EvalSession::QueryFailure = &result {
write!(stdout, "no\n\r").unwrap();
stdout.flush().unwrap();
break;
@@ -346,7 +346,7 @@ pub fn print(wam: &mut Machine, result: EvalResult) {
}
}
},
EvalResult::QueryFailure => println!("no"),
EvalSession::QueryFailure => println!("no"),
_ => {}
};
}

View File

@@ -75,7 +75,7 @@ impl Index<CodePtr> for Machine {
fn index(&self, ptr: CodePtr) -> &Self::Output {
match ptr {
CodePtr::TopLevel(_, _, p) => {
CodePtr::TopLevel(_, p) => {
match &self.cached_query {
&Some(ref cq) => &cq[p],
&None => panic!("Out-of-bounds top level index.")
@@ -142,13 +142,13 @@ impl Machine {
}
}
fn execute_instr(&mut self, ptr: CodePtr)
fn execute_instr(&mut self)
{
// can't use self[ptr] or self.index(ptr) to set the value of
// instr! instr is then typed as Line, not &Line. WHY????
// This is a compiler bug. Has to be.
let instr = match ptr {
CodePtr::TopLevel(_, _, p) => {
let instr = match self.ms.p {
CodePtr::TopLevel(_, p) => {
match &self.cached_query {
&Some(ref cq) => &cq[p],
&None => return
@@ -203,13 +203,13 @@ impl Machine {
let b = self.ms.b - 1;
self.ms.or_stack[b].bp
} else {
self.ms.p = CodePtr::TopLevel(0, 0, 0);
self.ms.p = CodePtr::TopLevel(0, 0);
return;
};
self.ms.p = p;
if let CodePtr::TopLevel(_, _, p) = p {
if let CodePtr::TopLevel(_, p) = p {
self.ms.fail = p == 0;
self.ms.b0 = b0;
@@ -219,19 +219,18 @@ impl Machine {
}
}
fn query_stepper<'a>(&mut self, mut ptr: CodePtr)
fn query_stepper<'a>(&mut self)
{
loop
{
self.execute_instr(ptr);
self.execute_instr();
if self.failed() {
self.backtrack();
}
match self.ms.p {
CodePtr::DirEntry(p) if p < self.code.len() =>
ptr = self.ms.p,
CodePtr::DirEntry(p) if p < self.code.len() => {},
_ => break
};
}
@@ -239,22 +238,22 @@ impl Machine {
fn record_var_places<'a>(&self,
chunk_num: usize,
e: usize,
alloc_locs: &AllocVarDict<'a>,
heap_locs: &mut HeapVarDict<'a>)
{
for (var, var_data) in alloc_locs {
match var_data {
&VarData::Perm(_) => {
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, addr);
},
&VarData::Temp(cn, _, _) if cn == chunk_num => {
let r = var_data.as_reg_type();
let addr = self.ms[r].clone();
heap_locs.insert(var, addr);
},
_ => {}
@@ -264,38 +263,30 @@ impl Machine {
fn run_query<'a>(&mut self, alloc_locs: &AllocVarDict<'a>, heap_locs: &mut HeapVarDict<'a>)
{
let end_ptr = CodePtr::TopLevel(0, 0, self.cached_query_size());
let mut tl_ptr = self.ms.p;
let end_ptr = CodePtr::TopLevel(0, self.cached_query_size());
while tl_ptr < end_ptr {
self.query_stepper(tl_ptr);
tl_ptr = self.ms.p;
if let &mut CodePtr::TopLevel(ref mut cn, ref mut e, p) = &mut tl_ptr {
if p == 0 {
break;
while self.ms.p < end_ptr {
if let CodePtr::TopLevel(mut cn, p) = self.ms.p {
if let &Line::Control(ref ctrl_instr) = &self[CodePtr::TopLevel(cn, p)] {
if ctrl_instr.is_jump_instr() {
self.record_var_places(cn, alloc_locs, heap_locs);
cn += 1;
}
}
match &self[CodePtr::TopLevel(*cn, *e, p)] {
&Line::Control(ControlInstruction::Call(_, _, _))
| &Line::Control(ControlInstruction::Execute(_, _)) => {
self.record_var_places(*cn, *e, alloc_locs, heap_locs);
*cn += 1;
},
&Line::Control(ControlInstruction::Allocate(_)) =>
*e = self.ms.e,
_ => {}
};
self.ms.p = CodePtr::TopLevel(*cn, *e, p);
} else {
break;
self.ms.p = CodePtr::TopLevel(cn, p);
}
self.query_stepper();
match self.ms.p {
CodePtr::TopLevel(_, p) if p > 0 => {},
_ => break
};
}
}
pub fn submit_query<'a>(&mut self, code: Code, alloc_locs: AllocVarDict<'a>) -> EvalResult<'a>
pub fn submit_query<'a>(&mut self, code: Code, alloc_locs: AllocVarDict<'a>) -> EvalSession<'a>
{
let mut heap_locs = HashMap::new();
self.cached_query = Some(code);
@@ -303,38 +294,38 @@ impl Machine {
self.run_query(&alloc_locs, &mut heap_locs);
if self.failed() {
EvalResult::QueryFailure
EvalSession::QueryFailure
} else {
EvalResult::InitialQuerySuccess(alloc_locs, heap_locs)
EvalSession::InitialQuerySuccess(alloc_locs, heap_locs)
}
}
pub fn continue_query<'a>(&mut self,
alloc_locs: &AllocVarDict<'a>,
heap_locs: &mut HeapVarDict<'a>)
-> EvalResult
-> EvalSession
{
if !self.or_stack_is_empty() {
if self.ms.b == 0 {
return EvalResult::QueryFailure;
return EvalSession::QueryFailure;
}
let b = self.ms.b - 1;
self.ms.p = self.ms.or_stack[b].bp;
if let CodePtr::TopLevel(_, _, 0) = self.ms.p {
return EvalResult::QueryFailure
if let CodePtr::TopLevel(_, 0) = self.ms.p {
return EvalSession::QueryFailure
}
self.run_query(alloc_locs, heap_locs);
if self.failed() {
EvalResult::QueryFailure
EvalSession::QueryFailure
} else {
EvalResult::SubsequentQuerySuccess
EvalSession::SubsequentQuerySuccess
}
} else {
EvalResult::QueryFailure
EvalSession::QueryFailure
}
}