let (h, n) = pstr_loc_and_offset(&self.machine_st.heap, h);
self.machine_st.s = HeapPtr::PStrChar(h, n.get_num() as usize);
+ self.machine_st.s_offset = 0;
self.machine_st.mode = MachineMode::Read;
}
(HeapCellValueTag::CStr) => {
self.machine_st.heap.push(store_v);
self.machine_st.s = HeapPtr::PStrChar(h, 0);
+ self.machine_st.s_offset = 0;
self.machine_st.mode = MachineMode::Read;
}
(HeapCellValueTag::Lis, l) => {
self.machine_st.s = HeapPtr::HeapCell(l);
+ self.machine_st.s_offset = 0;
self.machine_st.mode = MachineMode::Read;
}
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => {
(HeapCellValueTag::Atom, (result_name, result_arity)) => {
if arity == result_arity && name == result_name {
self.machine_st.s = HeapPtr::HeapCell(a + 1);
+ self.machine_st.s_offset = 0;
self.machine_st.mode = MachineMode::Read;
} else {
self.machine_st.backtrack();
self.machine_st.backtrack();
continue;
} else {
- self.machine_st.increment_s_ptr(1);
+ self.machine_st.s_offset += 1;
}
}
MachineMode::Write => {
self.machine_st.backtrack();
continue;
} else {
- self.machine_st.increment_s_ptr(1);
+ self.machine_st.s_offset += 1;
}
}
MachineMode::Write => {
let value = self.machine_st.heap[hc];
self.machine_st.heap.push(value);
- self.machine_st.increment_s_ptr(1);
+ self.machine_st.s_offset += 1;
}
_ => {
self.machine_st.heap.push(heap_loc_as_cell!(h));
match self.machine_st.mode {
MachineMode::Read => {
self.machine_st[reg] = self.machine_st.read_s();
- self.machine_st.increment_s_ptr(1);
+ self.machine_st.s_offset += 1;
}
MachineMode::Write => {
let h = self.machine_st.heap.len();
self.machine_st.backtrack();
continue;
} else {
- self.machine_st.increment_s_ptr(1);
+ self.machine_st.s_offset += 1;
}
}
MachineMode::Write => {
&Instruction::UnifyVoid(n) => {
match self.machine_st.mode {
MachineMode::Read => {
- self.machine_st.increment_s_ptr(n);
+ self.machine_st.s_offset += n;
}
MachineMode::Write => {
let h = self.machine_st.heap.len();
atom_tbl: AtomTable::new(),
pdl: Vec::with_capacity(1024),
s: HeapPtr::default(),
+ s_offset: 0,
p: 0,
oip: 0,
iip: 0,
)
}
+ #[inline]
pub fn deref(&self, mut addr: HeapCellValue) -> HeapCellValue {
loop {
let value = self.store(addr);
}
pub(crate) fn read_s(&mut self) -> HeapCellValue {
- match &self.s {
- &HeapPtr::HeapCell(h) => self.deref(self.heap[h]),
- &HeapPtr::PStrChar(h, n) => {
+ match &mut self.s {
+ &mut HeapPtr::HeapCell(h) => self.deref(self.heap[h + self.s_offset]),
+ &mut HeapPtr::PStrChar(h, n) if self.s_offset == 0 => {
read_heap_cell!(self.heap[h],
(HeapCellValueTag::PStr, pstr_atom) => {
let pstr = PartialString::from(pstr_atom);
if let Some(c) = pstr.as_str_from(n).chars().next() {
char_as_cell!(c)
- } else { // if has_tail {
- self.deref(self.heap[h+1]) // heap_loc_as_cell!(h+1)
+ } else {
+ self.deref(self.heap[h+1])
}
- // } else {
- // empty_list_as_cell!()
- // }
}
(HeapCellValueTag::CStr, cstr_atom) => {
let pstr = PartialString::from(cstr_atom);
if let Some(c) = pstr.as_str_from(n).chars().next() {
char_as_cell!(c)
- } else { // if has_tail {
+ } else {
empty_list_as_cell!()
}
}
}
)
}
- &HeapPtr::PStrLocation(h, n) => {
+ &mut HeapPtr::PStrChar(h, ref mut n) |
+ &mut HeapPtr::PStrLocation(h, ref mut n) => {
read_heap_cell!(self.heap[h],
(HeapCellValueTag::PStr, pstr_atom) => {
- if n < pstr_atom.len() {
+ let pstr = PartialString::from(pstr_atom);
+ let n_offset: usize = pstr.as_str_from(*n)
+ .chars()
+ .take(self.s_offset)
+ .map(|c| c.len_utf8())
+ .sum();
+
+ self.s_offset = 0;
+ *n += n_offset;
+
+ if *n < pstr_atom.len() {
let h_len = self.heap.len();
self.heap.push(pstr_offset_as_cell!(h));
- self.heap.push(fixnum_as_cell!(Fixnum::build_with(n as i64)));
+ self.heap.push(fixnum_as_cell!(Fixnum::build_with(*n as i64)));
pstr_loc_as_cell!(h_len)
} else {
}
}
(HeapCellValueTag::CStr, cstr_atom) => {
- if n < cstr_atom.len() {
+ let pstr = PartialString::from(cstr_atom);
+ let n_offset: usize = pstr.as_str_from(*n)
+ .chars()
+ .take(self.s_offset)
+ .map(|c| c.len_utf8())
+ .sum();
+
+ self.s_offset = 0;
+ *n += n_offset;
+
+ if *n < cstr_atom.len() {
let h_len = self.heap.len();
self.heap.push(pstr_offset_as_cell!(h));
- self.heap.push(fixnum_as_cell!(Fixnum::build_with(n as i64)));
+ self.heap.push(fixnum_as_cell!(Fixnum::build_with(*n as i64)));
pstr_loc_as_cell!(h_len)
} else {
Some(Ordering::Equal)
}
- pub(crate) fn increment_s_ptr(&mut self, rhs: usize) {
- match &mut self.s {
- HeapPtr::HeapCell(ref mut h) => {
- *h += rhs;
- }
- &mut HeapPtr::PStrChar(h, ref mut n) | &mut HeapPtr::PStrLocation(h, ref mut n) => {
- read_heap_cell!(self.heap[h],
- (HeapCellValueTag::PStr | HeapCellValueTag::CStr, pstr_atom) => {
- let pstr = PartialString::from(pstr_atom);
-
- for c in pstr.as_str_from(*n).chars().take(rhs) {
- *n += c.len_utf8();
- }
-
- self.s = HeapPtr::PStrLocation(h, *n);
- }
- _ => {
- unreachable!()
- }
- )
- }
- }
- }
-
pub fn match_partial_string(&mut self, value: HeapCellValue, string: Atom, has_tail: bool) {
let h = self.heap.len();
self.heap.push(value);
(HeapCellValueTag::PStr | HeapCellValueTag::CStr, pstr_atom) => {
if has_tail {
self.s = HeapPtr::PStrLocation(focus, offset);
+ self.s_offset = 0;
self.mode = MachineMode::Read;
} else if offset == pstr_atom.len() {
- let focus_addr = heap_pstr_iter.focus;
- unify!(self, focus_addr, empty_list_as_cell!());
+ let focus = heap_pstr_iter.focus;
+ unify!(self, focus, empty_list_as_cell!());
} else {
self.fail = true;
}
}
(HeapCellValueTag::PStrLoc | HeapCellValueTag::PStrOffset, h) => {
- if has_tail {
- let (h, _) = pstr_loc_and_offset(&self.heap, h);
+ let (focus, _) = pstr_loc_and_offset(&self.heap, h);
+ let pstr_atom = read_heap_cell!(self.heap[focus],
+ (HeapCellValueTag::CStr | HeapCellValueTag::PStr, pstr_atom) => {
+ pstr_atom
+ }
+ _ => {
+ unreachable!()
+ }
+ );
- self.s = HeapPtr::PStrLocation(h, offset);
+ if has_tail {
+ self.s = HeapPtr::PStrLocation(focus, offset);
+ self.s_offset = 0;
self.mode = MachineMode::Read;
+ } else if offset == pstr_atom.len() {
+ let focus = heap_pstr_iter.focus;
+ unify!(self, focus, empty_list_as_cell!());
} else {
- let end_cell = heap_pstr_iter.focus;
- self.fail = end_cell != empty_list_as_cell!();
+ self.fail = true;
}
}
_ => {
if has_tail {
self.s = HeapPtr::HeapCell(focus);
+ self.s_offset = 0;
self.mode = MachineMode::Read;
} else {
let focus = heap_pstr_iter.focus;
let target_cell = if has_tail {
self.s = HeapPtr::HeapCell(h + 1);
+ self.s_offset = 0;
self.mode = MachineMode::Read;
put_partial_string(