self.inner.ptr = ptr::null_mut();
self.inner.byte_len = 0;
self.inner.byte_cap = 0;
-
- // self.pstr_vec.clear();
}
- // pub(crate) fn append(&mut self, heap_slice: HeapView) -> Result<(), usize> {
- // unsafe {
- // loop {
- // if self.free_space() >= heap_index!(heap_slice.slice_cell_len) {
- // ptr::copy_nonoverlapping(
- // heap_slice.slice,
- // self.inner.ptr.add(self.inner.byte_len),
- // heap_index!(heap_slice.slice_cell_len),
- // );
-
- // self.inner.byte_len += heap_index!(heap_slice.slice_cell_len);
- // // self.pstr_vec.extend(heap_slice.pstr_slice.iter());
-
- // break;
- // } else if !self.grow() {
- // return Err(self.resource_error_offset());
- // }
- // }
- // }
-
- // Ok(())
- // }
-
pub(crate) fn store_resource_error(&mut self) {
RESOURCE_ERROR_OFFSET_INIT.call_once(move || {
let stub = functor!(atom!("resource_error"), [atom_as_cell((atom!("memory")))]);
);
}
&Instruction::GetPartialString(Level::Shallow, ref string, RegType::Temp(t)) => {
- use crate::machine::partial_string::HeapPStrIter;
let cell = self.deref_register(t);
read_heap_cell!(cell,
- (HeapCellValueTag::PStrLoc) => {
- self.machine_st.heap[0] = cell;
- let iter = HeapPStrIter::new(&self.machine_st.heap, 0);
+ (HeapCellValueTag::PStrLoc, pstr_loc) => {
+ let heap_slice = &self.machine_st.heap.as_slice()[pstr_loc ..];
- if iter.compare_pstr_to_string(string).is_none() {
- return false;
+ match compare_pstr_slices(heap_slice, string.as_bytes()) {
+ PStrSegmentCmpResult::Continue(..) => offset += 1,
+ _ => return false,
}
-
- offset += 1;
-
}
(HeapCellValueTag::Lis) => {
offset += 1;
use crate::types::*;
use std::ops::Deref;
-use std::str;
#[derive(Clone, Copy)]
pub struct HeapPStrIter<'a> {
stepper: fn(&mut HeapPStrIter<'a>) -> Option<PStrIteratee>,
}
-#[derive(Debug, Clone, Copy)]
-pub enum PStrCmpResult<'a> {
- ListMatch {
- list_loc: usize,
- },
- CompletePStrMatch {
- chars_matched: usize,
- pstr_loc: usize,
- },
- PartialPStrMatch {
- string: &'a str,
- var_loc: usize,
- },
-}
-
struct PStrIterStep {
iteratee: PStrIteratee,
next_hare: usize,
self.brent_st.hare
}
- pub fn compare_pstr_to_string(self, mut s: &str) -> Option<PStrCmpResult> {
- let mut curr_hare = self.brent_st.hare;
-
- while !s.is_empty() {
- read_heap_cell!(self.heap[curr_hare],
- (HeapCellValueTag::PStrLoc, h) => {
- let t = self.heap.slice_to_str(h, self.heap.byte_len() - h);
-
- let mut bytes_matched = 0;
- let mut chars_matched = 0;
-
- for (sc, tc) in s.chars().zip(t.chars()) {
- if sc != tc {
- if tc != '\u{0}' {
- return None;
- } else {
- break;
- }
- }
-
- bytes_matched += sc.len_utf8();
- chars_matched += 1;
- }
-
- s = &s[bytes_matched ..];
-
- if s.is_empty() {
- return Some(PStrCmpResult::CompletePStrMatch { chars_matched, pstr_loc: h });
- } else {
- let next_hare = Heap::pstr_tail_idx(h + bytes_matched);
- curr_hare = next_hare;
- }
- }
- (HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
- if h == curr_hare {
- return Some(PStrCmpResult::PartialPStrMatch { string: s, var_loc: h });
- }
-
- curr_hare = h;
- continue;
- }
- _ => {
- match self.step(curr_hare).ok() {
- Some(PStrIterStep { iteratee, next_hare }) => {
- let value = if let PStrIteratee::Char { value, .. } = iteratee {
- value
- } else {
- unreachable!()
- };
-
- let c = s.chars().next().unwrap();
-
- if c == value {
- s = &s[c.len_utf8() ..];
-
- if s.is_empty() {
- return Some(
- PStrCmpResult::ListMatch {
- list_loc: next_hare,
- }
- );
- }
-
- curr_hare = next_hare;
- } else {
- return None;
- }
- }
- None => {
- return None;
- }
- }
- }
- );
- }
-
- None
- }
-
fn walk_hare_to_cycle_end(&mut self) {
// walk_hare_to_cycle_end assumes a cycle has been found,
// so it is always safe to unwrap self.step()