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

View File

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

View File

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

View File

@@ -213,6 +213,16 @@ pub enum ControlInstruction {
Proceed Proceed
} }
impl ControlInstruction {
pub fn is_jump_instr(&self) -> bool {
match self {
&ControlInstruction::Call(_, _, _) => true,
&ControlInstruction::Execute(_, _) => true,
_ => false
}
}
}
pub enum IndexingInstruction { pub enum IndexingInstruction {
SwitchOnTerm(usize, usize, usize, usize), SwitchOnTerm(usize, usize, usize, usize),
SwitchOnConstant(usize, HashMap<Constant, usize>), SwitchOnConstant(usize, HashMap<Constant, usize>),
@@ -362,7 +372,7 @@ impl HeapCellValue {
#[derive(Clone, Copy, PartialEq)] #[derive(Clone, Copy, PartialEq)]
pub enum CodePtr { pub enum CodePtr {
DirEntry(usize), DirEntry(usize),
TopLevel(usize, usize, usize) // chunk_num, e, offset. TopLevel(usize, usize) // chunk_num, offset.
} }
impl PartialOrd<CodePtr> for CodePtr { impl PartialOrd<CodePtr> for CodePtr {
@@ -370,9 +380,9 @@ impl PartialOrd<CodePtr> for CodePtr {
match (self, other) { match (self, other) {
(&CodePtr::DirEntry(p1), &CodePtr::DirEntry(ref p2)) => (&CodePtr::DirEntry(p1), &CodePtr::DirEntry(ref p2)) =>
p1.partial_cmp(p2), p1.partial_cmp(p2),
(&CodePtr::DirEntry(_), &CodePtr::TopLevel(_, _, _)) => (&CodePtr::DirEntry(_), &CodePtr::TopLevel(_, _)) =>
Some(Ordering::Less), Some(Ordering::Less),
(&CodePtr::TopLevel(_, _, p1), &CodePtr::TopLevel(_, _, ref p2)) => (&CodePtr::TopLevel(_, p1), &CodePtr::TopLevel(_, ref p2)) =>
p1.partial_cmp(p2), p1.partial_cmp(p2),
_ => Some(Ordering::Greater) _ => Some(Ordering::Greater)
} }
@@ -381,7 +391,7 @@ impl PartialOrd<CodePtr> for CodePtr {
impl Default for CodePtr { impl Default for CodePtr {
fn default() -> Self { 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 { fn add(self, rhs: usize) -> Self::Output {
match self { match self {
CodePtr::DirEntry(p) => CodePtr::DirEntry(p + rhs), 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) { fn add_assign(&mut self, rhs: usize) {
match self { match self {
&mut CodePtr::DirEntry(ref mut p) | &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> var_count: HashMap<&'a Var, usize>
} }
pub enum EvalResult<'a> { pub enum EvalSession<'a> {
EntryFailure, EntryFailure,
EntrySuccess, EntrySuccess,
InitialQuerySuccess(AllocVarDict<'a>, HeapVarDict<'a>), InitialQuerySuccess(AllocVarDict<'a>, HeapVarDict<'a>),
@@ -22,10 +22,10 @@ pub enum EvalResult<'a> {
SubsequentQuerySuccess, SubsequentQuerySuccess,
} }
impl<'a> EvalResult<'a> { impl<'a> EvalSession<'a> {
#[allow(dead_code)] #[allow(dead_code)]
pub fn failed_query(&self) -> bool { pub fn failed_query(&self) -> bool {
if let &EvalResult::QueryFailure = self { if let &EvalSession::QueryFailure = self {
true true
} else { } else {
false false

View File

@@ -257,7 +257,7 @@ pub fn read() -> String {
result 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 { match tl {
&TopLevel::Predicate(ref clauses) => { &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); let compiled_pred = cg.compile_predicate(clauses);
wam.add_predicate(clauses, compiled_pred); wam.add_predicate(clauses, compiled_pred);
EvalResult::EntrySuccess EvalSession::EntrySuccess
} else { } else {
let msg = r"Error: predicate is inconsistent. let msg = r"Error: predicate is inconsistent.
Each predicate must have the same name and arity."; Each predicate must have the same name and arity.";
println!("{}", msg); println!("{}", msg);
EvalResult::EntryFailure EvalSession::EntryFailure
} }
}, },
&TopLevel::Fact(ref fact) => { &TopLevel::Fact(ref fact) => {
@@ -282,7 +282,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);
EvalResult::EntrySuccess EvalSession::EntrySuccess
}, },
&TopLevel::Rule(ref rule) => { &TopLevel::Rule(ref rule) => {
let mut cg = CodeGenerator::<DebrayAllocator>::new(); 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); let compiled_rule = cg.compile_rule(rule);
wam.add_rule(rule, compiled_rule); wam.add_rule(rule, compiled_rule);
EvalResult::EntrySuccess EvalSession::EntrySuccess
}, },
&TopLevel::Query(ref query) => { &TopLevel::Query(ref query) => {
let mut cg = CodeGenerator::<DebrayAllocator>::new(); 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 { match result {
EvalResult::InitialQuerySuccess(alloc_locs, mut heap_locs) => { EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => {
println!("yes"); println!("yes");
if heap_locs.is_empty() { if heap_locs.is_empty() {
@@ -311,7 +311,7 @@ pub fn print(wam: &mut Machine, result: EvalResult) {
} }
'outer: loop { 'outer: loop {
let mut result = EvalResult::QueryFailure; let mut result = EvalSession::QueryFailure;
let bindings = wam.heap_view(&heap_locs); let bindings = wam.heap_view(&heap_locs);
let stdin = stdin(); 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(); write!(stdout, "no\n\r").unwrap();
stdout.flush().unwrap(); stdout.flush().unwrap();
break; 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 { fn index(&self, ptr: CodePtr) -> &Self::Output {
match ptr { match ptr {
CodePtr::TopLevel(_, _, p) => { CodePtr::TopLevel(_, p) => {
match &self.cached_query { match &self.cached_query {
&Some(ref cq) => &cq[p], &Some(ref cq) => &cq[p],
&None => panic!("Out-of-bounds top level index.") &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 // can't use self[ptr] or self.index(ptr) to set the value of
// instr! instr is then typed as Line, not &Line. WHY???? // instr! instr is then typed as Line, not &Line. WHY????
// This is a compiler bug. Has to be. // This is a compiler bug. Has to be.
let instr = match ptr { let instr = match self.ms.p {
CodePtr::TopLevel(_, _, p) => { CodePtr::TopLevel(_, p) => {
match &self.cached_query { match &self.cached_query {
&Some(ref cq) => &cq[p], &Some(ref cq) => &cq[p],
&None => return &None => return
@@ -203,13 +203,13 @@ impl Machine {
let b = self.ms.b - 1; let b = self.ms.b - 1;
self.ms.or_stack[b].bp self.ms.or_stack[b].bp
} else { } else {
self.ms.p = CodePtr::TopLevel(0, 0, 0); self.ms.p = CodePtr::TopLevel(0, 0);
return; return;
}; };
self.ms.p = p; self.ms.p = p;
if let CodePtr::TopLevel(_, _, p) = p { if let CodePtr::TopLevel(_, p) = p {
self.ms.fail = p == 0; self.ms.fail = p == 0;
self.ms.b0 = b0; 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 loop
{ {
self.execute_instr(ptr); self.execute_instr();
if self.failed() { if self.failed() {
self.backtrack(); self.backtrack();
} }
match self.ms.p { match self.ms.p {
CodePtr::DirEntry(p) if p < self.code.len() => CodePtr::DirEntry(p) if p < self.code.len() => {},
ptr = self.ms.p,
_ => break _ => break
}; };
} }
@@ -239,22 +238,22 @@ impl Machine {
fn record_var_places<'a>(&self, fn record_var_places<'a>(&self,
chunk_num: usize, chunk_num: usize,
e: usize,
alloc_locs: &AllocVarDict<'a>, alloc_locs: &AllocVarDict<'a>,
heap_locs: &mut HeapVarDict<'a>) heap_locs: &mut HeapVarDict<'a>)
{ {
for (var, var_data) in alloc_locs { for (var, var_data) in alloc_locs {
match var_data { match var_data {
&VarData::Perm(_) => { &VarData::Perm(_) => {
let e = self.ms.e;
let r = var_data.as_reg_type().reg_num(); let r = var_data.as_reg_type().reg_num();
let addr = self.ms.and_stack[e][r].clone(); let addr = self.ms.and_stack[e][r].clone();
heap_locs.insert(var, addr); heap_locs.insert(var, addr);
}, },
&VarData::Temp(cn, _, _) if cn == chunk_num => { &VarData::Temp(cn, _, _) if cn == chunk_num => {
let r = var_data.as_reg_type(); let r = var_data.as_reg_type();
let addr = self.ms[r].clone(); let addr = self.ms[r].clone();
heap_locs.insert(var, addr); 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>) 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 end_ptr = CodePtr::TopLevel(0, self.cached_query_size());
let mut tl_ptr = self.ms.p;
while tl_ptr < end_ptr { while self.ms.p < end_ptr {
self.query_stepper(tl_ptr); if let CodePtr::TopLevel(mut cn, p) = self.ms.p {
if let &Line::Control(ref ctrl_instr) = &self[CodePtr::TopLevel(cn, p)] {
tl_ptr = self.ms.p; if ctrl_instr.is_jump_instr() {
self.record_var_places(cn, alloc_locs, heap_locs);
if let &mut CodePtr::TopLevel(ref mut cn, ref mut e, p) = &mut tl_ptr { cn += 1;
if p == 0 { }
break;
} }
match &self[CodePtr::TopLevel(*cn, *e, p)] { self.ms.p = CodePtr::TopLevel(cn, 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.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(); let mut heap_locs = HashMap::new();
self.cached_query = Some(code); self.cached_query = Some(code);
@@ -303,38 +294,38 @@ impl Machine {
self.run_query(&alloc_locs, &mut heap_locs); self.run_query(&alloc_locs, &mut heap_locs);
if self.failed() { if self.failed() {
EvalResult::QueryFailure EvalSession::QueryFailure
} else { } else {
EvalResult::InitialQuerySuccess(alloc_locs, heap_locs) EvalSession::InitialQuerySuccess(alloc_locs, heap_locs)
} }
} }
pub fn continue_query<'a>(&mut self, pub fn continue_query<'a>(&mut self,
alloc_locs: &AllocVarDict<'a>, alloc_locs: &AllocVarDict<'a>,
heap_locs: &mut HeapVarDict<'a>) heap_locs: &mut HeapVarDict<'a>)
-> EvalResult -> EvalSession
{ {
if !self.or_stack_is_empty() { if !self.or_stack_is_empty() {
if self.ms.b == 0 { if self.ms.b == 0 {
return EvalResult::QueryFailure; return EvalSession::QueryFailure;
} }
let b = self.ms.b - 1; let b = self.ms.b - 1;
self.ms.p = self.ms.or_stack[b].bp; self.ms.p = self.ms.or_stack[b].bp;
if let CodePtr::TopLevel(_, _, 0) = self.ms.p { if let CodePtr::TopLevel(_, 0) = self.ms.p {
return EvalResult::QueryFailure return EvalSession::QueryFailure
} }
self.run_query(alloc_locs, heap_locs); self.run_query(alloc_locs, heap_locs);
if self.failed() { if self.failed() {
EvalResult::QueryFailure EvalSession::QueryFailure
} else { } else {
EvalResult::SubsequentQuerySuccess EvalSession::SubsequentQuerySuccess
} }
} else { } else {
EvalResult::QueryFailure EvalSession::QueryFailure
} }
} }