change arithmetic evaluation iterator to new target type
This commit is contained in:
@@ -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)?));
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1139,8 +1139,7 @@ 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);
|
||||||
|
|||||||
Reference in New Issue
Block a user