[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)",
[package]
name = "rusty-wam"
-version = "0.6.1"
+version = "0.6.2"
authors = ["Mark Thom"]
build = "build.rs"
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
},
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>),
#[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 {
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)
}
impl Default for CodePtr {
fn default() -> Self {
- CodePtr::TopLevel(0, 0, 0)
+ CodePtr::TopLevel(0, 0)
}
}
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)
}
}
}
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
}
}
}
var_count: HashMap<&'a Var, usize>
}
-pub enum EvalResult<'a> {
+pub enum EvalSession<'a> {
EntryFailure,
EntrySuccess,
InitialQuerySuccess(AllocVarDict<'a>, HeapVarDict<'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
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) => {
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) => {
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();
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();
}
}
-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() {
}
'outer: loop {
- let mut result = EvalResult::QueryFailure;
+ let mut result = EvalSession::QueryFailure;
let bindings = wam.heap_view(&heap_locs);
let stdin = stdin();
}
}
- if let &EvalResult::QueryFailure = &result {
+ if let &EvalSession::QueryFailure = &result {
write!(stdout, "no\n\r").unwrap();
stdout.flush().unwrap();
break;
}
}
},
- EvalResult::QueryFailure => println!("no"),
+ EvalSession::QueryFailure => println!("no"),
_ => {}
};
}
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.")
}
}
- 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
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;
}
}
- 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
};
}
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);
},
_ => {}
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;
-
- 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;
+ let end_ptr = CodePtr::TopLevel(0, self.cached_query_size());
+
+ 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);
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
}
}