let store_v = self.machine_st.store(deref_v);
read_heap_cell!(store_v,
- (HeapCellValueTag::Str | HeapCellValueTag::Lis |
- HeapCellValueTag::PStrLoc | HeapCellValueTag::AttrVar |
- HeapCellValueTag::StackVar | HeapCellValueTag::Var |
+ (HeapCellValueTag::Str |
+ HeapCellValueTag::Lis |
+ HeapCellValueTag::PStrLoc |
HeapCellValueTag::CStr) => {
self.machine_st.match_partial_string(store_v, string, has_tail);
}
+ (HeapCellValueTag::AttrVar |
+ HeapCellValueTag::StackVar |
+ HeapCellValueTag::Var) => {
+ let target_cell = self.machine_st.push_str_to_heap(
+ string.as_str(),
+ has_tail,
+ );
+
+ self.machine_st.bind(
+ store_v.as_var().unwrap(),
+ target_cell,
+ );
+ }
_ => {
self.machine_st.backtrack();
continue;
let h = self.heap.len();
self.heap.push(value);
+ let prefix_len;
let mut heap_pstr_iter = HeapPStrIter::new(&self.heap, h);
+
let s = string.as_str();
match heap_pstr_iter.compare_pstr_to_string(s) {
}
}
);
- }
- Some(PStrPrefixCmpResult { prefix_len, .. }) => {
- let focus = heap_pstr_iter.focus();
- let tail_addr = self.heap[focus];
- let h = self.heap.len();
+ return;
+ }
+ Some(PStrPrefixCmpResult { prefix_len: inner_prefix_len, .. }) => {
+ prefix_len = inner_prefix_len;
+ }
+ None => {
+ read_heap_cell!(value,
+ (HeapCellValueTag::Str, s) => {
+ let cell = heap_loc_as_cell!(s + 1);
+ let is_list = self.heap[s] == atom_as_cell!(atom!("."), 2);
- let target_cell = if has_tail {
- self.s = HeapPtr::HeapCell(h + 1);
- self.s_offset = 0;
- self.mode = MachineMode::Read;
+ if !(is_list && self.store(self.deref(cell)).is_var()) {
+ self.fail = true;
+ return;
+ }
+ }
+ (HeapCellValueTag::Lis, l) => {
+ let cell = heap_loc_as_cell!(l);
- put_partial_string(
- &mut self.heap,
- &string.as_str()[prefix_len ..],
- &mut self.atom_tbl,
- )
- } else {
- put_complete_string(
- &mut self.heap,
- &string.as_str()[prefix_len ..],
- &mut self.atom_tbl,
- )
- };
+ if !self.store(self.deref(cell)).is_var() {
+ self.fail = true;
+ return;
+ }
+ }
+ (HeapCellValueTag::AttrVar |
+ HeapCellValueTag::StackVar |
+ HeapCellValueTag::Var) => {
+ }
+ _ => {
+ self.fail = true;
+ return;
+ }
+ );
- unify!(self, tail_addr, target_cell);
- }
- None => {
- self.fail = true;
+ prefix_len = 0;
}
}
+
+ let focus = heap_pstr_iter.focus();
+ let tail_addr = self.heap[focus];
+ let target_cell = self.push_str_to_heap(&string.as_str()[prefix_len..], has_tail);
+
+ unify!(self, tail_addr, target_cell);
+ }
+
+ #[inline(always)]
+ pub(super) fn push_str_to_heap(&mut self, pstr: &str, has_tail: bool) -> HeapCellValue {
+ let h = self.heap.len();
+
+ if has_tail {
+ self.s = HeapPtr::HeapCell(h + 1);
+ self.s_offset = 0;
+ self.mode = MachineMode::Read;
+
+ put_partial_string(&mut self.heap, pstr, &mut self.atom_tbl)
+ } else {
+ put_complete_string(&mut self.heap, pstr, &mut self.atom_tbl)
+ }
}
pub(super) fn write_literal_to_var(&mut self, deref_v: HeapCellValue, lit: HeapCellValue) {
}
(HeapCellValueTag::CStr, cstr_atom) => {
read_heap_cell!(store_v,
- (HeapCellValueTag::PStrLoc
- | HeapCellValueTag::Lis
- | HeapCellValueTag::Str) => {
+ (HeapCellValueTag::PStrLoc |
+ HeapCellValueTag::Lis |
+ HeapCellValueTag::Str) => {
self.match_partial_string(store_v, cstr_atom, false);
}
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var) => {
self.brent_st.num_steps()
}
- #[inline]
+ #[inline(always)]
pub fn chars(mut self) -> PStrCharsIter<'a> {
let item = self.next();
PStrCharsIter { iter: self, item }
prefix_len: 0,
};
+ let mut final_result = None;
+
while let Some(PStrIterStep { iteratee, next_hare }) = self.step(self.brent_st.hare) {
self.brent_st.hare = next_hare;
- self.focus = self.heap[next_hare];
+ self.focus = self.heap[iteratee.focus()];
result.focus = iteratee.focus();
result.offset = iteratee.offset();
result.offset += c1.len_utf8();
}
} else {
- return Some(result);
+ final_result = Some(result);
+ break;
}
}
PStrIteratee::PStrSegment(_, pstr_atom, n) => {
result.prefix_len += s.len();
result.offset += s.len();
- return Some(result);
+ final_result = Some(result);
+ break;
} else {
return None;
}
}
if s.len() == result.prefix_len {
- return Some(result);
+ final_result = Some(result);
+ break;
+ }
+ }
+
+ if let Some(result) = &final_result {
+ if self.at_string_terminator() {
+ self.focus = empty_list_as_cell!();
+ self.brent_st.hare = result.focus;
}
}
- Some(result)
+ final_result
}
fn walk_hare_to_cycle_end(&mut self) {
self.focus = self.heap[iteratee.focus()];
- if self.focus.is_string_terminator(self.heap) {
+ if self.at_string_terminator() {
self.focus = empty_list_as_cell!();
self.brent_st.hare = iteratee.focus();