change arithmetic evaluation iterator to new target type

This commit is contained in:
Mark Thom
2018-01-17 21:39:59 -07:00
parent d8be7b5b49
commit f95901a6d0
3 changed files with 64 additions and 64 deletions

View File

@@ -1,6 +1,7 @@
use prolog::ast::*; use prolog::ast::*;
use prolog::fixtures::*; use prolog::fixtures::*;
use std::cell::Cell;
use std::cmp::{min, max}; use std::cmp::{min, max};
use std::vec::Vec; use std::vec::Vec;
@@ -39,33 +40,34 @@ impl Term {
} }
} }
pub enum ArithTermRef<'a> {
Constant(&'a Constant),
Op(ClauseType<'a>, &'a Vec<Box<Term>>),
Var(&'a Cell<VarReg>, &'a Var)
}
impl<'a> Iterator for ArithExprIterator<'a> { impl<'a> Iterator for ArithExprIterator<'a> {
type Item = TermRef<'a>; type Item = Result<ArithTermRef<'a>, ArithmeticError>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
while let Some(iter_state) = self.state_stack.pop() { while let Some(iter_state) = self.state_stack.pop() {
match iter_state { match iter_state {
TermIterState::AnonVar(lvl) => TermIterState::AnonVar(_) =>
return Some(TermRef::AnonVar(lvl)), return Some(Err(ArithmeticError::UninstantiatedVar)),
TermIterState::Clause(child_num, ct, child_terms) => { TermIterState::Clause(child_num, ct, child_terms) => {
if child_num == child_terms.len() { if child_num == child_terms.len() {
return Some(TermRef::Clause(ct, child_terms)); return Some(Ok(ArithTermRef::Op(ct, child_terms)));
} else { } else {
self.state_stack.push(TermIterState::Clause(child_num + 1, ct, child_terms)); self.state_stack.push(TermIterState::Clause(child_num + 1, ct, child_terms));
self.push_subterm(ct.level_of_subterms(), child_terms[child_num].as_ref()); self.push_subterm(ct.level_of_subterms(), child_terms[child_num].as_ref());
} }
}, },
TermIterState::InitialCons(lvl, cell, head, tail) => { TermIterState::Constant(_, _, c) =>
self.state_stack.push(TermIterState::FinalCons(lvl, cell, head, tail)); return Some(Ok(ArithTermRef::Constant(c))),
self.push_subterm(Level::Deep, tail); TermIterState::Var(_, cell, var) =>
self.push_subterm(Level::Deep, head); return Some(Ok(ArithTermRef::Var(cell, var))),
}, _ =>
TermIterState::FinalCons(lvl, cell, head, tail) => return Some(Err(ArithmeticError::InvalidTerm))
return Some(TermRef::Cons(lvl, cell, head, tail)),
TermIterState::Constant(lvl, cell, constant) =>
return Some(TermRef::Constant(lvl, cell, constant)),
TermIterState::Var(lvl, cell, var) =>
return Some(TermRef::Var(lvl, cell, var))
}; };
} }
@@ -183,26 +185,25 @@ impl<'a> ArithmeticEvaluator<'a> {
let mut code = Vec::new(); let mut code = Vec::new();
for term_ref in term.arith_expr_iter()? { for term_ref in term.arith_expr_iter()? {
match term_ref { match term_ref? {
TermRef::Constant(_, _, c) => ArithTermRef::Constant(c) => self.push_constant(c)?,
try!(self.push_constant(c)), ArithTermRef::Var(cell, name) => {
TermRef::Var(_, vr, name) => { let r = if cell.get().norm().reg_num() == 0 {
let r = if vr.get().norm().reg_num() == 0 {
match self.bindings.get(name) { match self.bindings.get(name) {
Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t), Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t),
Some(&VarData::Perm(p)) if p != 0 => RegType::Perm(p), Some(&VarData::Perm(p)) if p != 0 => RegType::Perm(p),
_ => return Err(ArithmeticError::UninstantiatedVar) _ => return Err(ArithmeticError::UninstantiatedVar)
} }
} else { } else {
vr.get().norm() cell.get().norm()
}; };
self.interm.push(ArithmeticTerm::Reg(r)); self.interm.push(ArithmeticTerm::Reg(r));
}, },
TermRef::Clause(ClauseType::Deep(_, _, name, _), terms) => { ArithTermRef::Op(ClauseType::Deep(_, _, name, _), terms) => {
code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?)); code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?));
}, },
TermRef::Clause(ClauseType::Root, terms) => { ArithTermRef::Op(ClauseType::Root, terms) => {
let name = term.name().unwrap(); let name = term.name().unwrap();
code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?)); code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?));
}, },

View File

@@ -1139,15 +1139,14 @@ impl MachineState {
self.p = CodePtr::DirEntry(59); self.p = CodePtr::DirEntry(59);
} }
fn throw_exception fn throw_exception(&mut self, hcv: Vec<HeapCellValue>) {
(&mut self, hcv: Vec<HeapCellValue>) { let h = self.heap.h;
let h = self.heap.h;
self.registers[1] = Addr::HeapCell(h); self.registers[1] = Addr::HeapCell(h);
self.heap.append(hcv); self.heap.append(hcv);
self.goto_throw(); self.goto_throw();
} }
fn setup_call_n(&mut self, arity: usize) -> Option<PredicateKey> fn setup_call_n(&mut self, arity: usize) -> Option<PredicateKey>
{ {