add callable is/2

This commit is contained in:
Mark Thom
2018-01-19 00:08:55 -07:00
parent 1b402b2673
commit f9b53856ac
8 changed files with 353 additions and 247 deletions

View File

@@ -3,21 +3,18 @@ use prolog::machine::machine_state::MachineState;
use std::vec::Vec;
pub struct HeapCellIterator<'a> {
pub struct HeapCellPreOrderIterator<'a> {
machine_st : &'a MachineState,
state_stack : Vec<Ref>
}
impl<'a> HeapCellIterator<'a> {
impl<'a> HeapCellPreOrderIterator<'a> {
pub fn new(machine_st: &'a MachineState, r: Ref) -> Self
{
let mut iter = HeapCellIterator {
HeapCellPreOrderIterator {
machine_st,
state_stack: vec![]
};
iter.state_stack.push(r);
iter
state_stack: vec![r]
}
}
// called under the assumption that the location at r is about to
@@ -64,11 +61,11 @@ impl<'a> HeapCellIterator<'a> {
self.follow_heap(s); // record terms of structure.
Addr::HeapCell(s)
}
}
}
}
}
impl<'a> Iterator for HeapCellIterator<'a> {
impl<'a> Iterator for HeapCellPreOrderIterator<'a> {
type Item = HeapCellValue;
fn next(&mut self) -> Option<Self::Item> {
@@ -86,3 +83,53 @@ impl<'a> Iterator for HeapCellIterator<'a> {
}
}
}
pub struct HeapCellPostOrderIterator<'a> {
pre_iter: HeapCellPreOrderIterator<'a>,
parent_stack: Vec<(usize, HeapCellValue)> // number of children, parent node.
}
impl<'a> HeapCellPostOrderIterator<'a> {
pub fn new(pre_iter: HeapCellPreOrderIterator<'a>) -> Self {
HeapCellPostOrderIterator {
pre_iter,
parent_stack: vec![]
}
}
}
impl<'a> Iterator for HeapCellPostOrderIterator<'a> {
type Item = HeapCellValue;
fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some((child_count, node)) = self.parent_stack.pop() {
if child_count == 0 {
return Some(node);
}
self.parent_stack.push((child_count - 1, node));
}
if let Some(item) = self.pre_iter.next() {
match item {
HeapCellValue::NamedStr(arity, name, fix) =>
self.parent_stack.push((arity, HeapCellValue::NamedStr(arity, name, fix))),
HeapCellValue::Addr(Addr::Lis(a)) =>
self.parent_stack.push((2, HeapCellValue::Addr(Addr::Lis(a)))),
child_node => {
return Some(child_node);
}
}
} else {
return None;
}
}
}
}
impl MachineState {
pub fn post_order_iter<'a>(&'a self, r: Ref) -> HeapCellPostOrderIterator<'a> {
HeapCellPostOrderIterator::new(HeapCellPreOrderIterator::new(self, r))
}
}