fix match_partial_string, compare_pstr_to_string (#1451)
This commit is contained in:
@@ -2790,12 +2790,25 @@ impl Machine {
|
|||||||
let store_v = self.machine_st.store(deref_v);
|
let store_v = self.machine_st.store(deref_v);
|
||||||
|
|
||||||
read_heap_cell!(store_v,
|
read_heap_cell!(store_v,
|
||||||
(HeapCellValueTag::Str | HeapCellValueTag::Lis |
|
(HeapCellValueTag::Str |
|
||||||
HeapCellValueTag::PStrLoc | HeapCellValueTag::AttrVar |
|
HeapCellValueTag::Lis |
|
||||||
HeapCellValueTag::StackVar | HeapCellValueTag::Var |
|
HeapCellValueTag::PStrLoc |
|
||||||
HeapCellValueTag::CStr) => {
|
HeapCellValueTag::CStr) => {
|
||||||
self.machine_st.match_partial_string(store_v, string, has_tail);
|
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();
|
self.machine_st.backtrack();
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -1863,7 +1863,9 @@ impl MachineState {
|
|||||||
let h = self.heap.len();
|
let h = self.heap.len();
|
||||||
self.heap.push(value);
|
self.heap.push(value);
|
||||||
|
|
||||||
|
let prefix_len;
|
||||||
let mut heap_pstr_iter = HeapPStrIter::new(&self.heap, h);
|
let mut heap_pstr_iter = HeapPStrIter::new(&self.heap, h);
|
||||||
|
|
||||||
let s = string.as_str();
|
let s = string.as_str();
|
||||||
|
|
||||||
match heap_pstr_iter.compare_pstr_to_string(s) {
|
match heap_pstr_iter.compare_pstr_to_string(s) {
|
||||||
@@ -1911,37 +1913,65 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
Some(PStrPrefixCmpResult { prefix_len, .. }) => {
|
Some(PStrPrefixCmpResult { prefix_len: inner_prefix_len, .. }) => {
|
||||||
let focus = heap_pstr_iter.focus();
|
prefix_len = inner_prefix_len;
|
||||||
let tail_addr = self.heap[focus];
|
|
||||||
|
|
||||||
let h = self.heap.len();
|
|
||||||
|
|
||||||
let target_cell = if has_tail {
|
|
||||||
self.s = HeapPtr::HeapCell(h + 1);
|
|
||||||
self.s_offset = 0;
|
|
||||||
self.mode = MachineMode::Read;
|
|
||||||
|
|
||||||
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,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
unify!(self, tail_addr, target_cell);
|
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.fail = true;
|
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);
|
||||||
|
|
||||||
|
if !(is_list && self.store(self.deref(cell)).is_var()) {
|
||||||
|
self.fail = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::Lis, l) => {
|
||||||
|
let cell = heap_loc_as_cell!(l);
|
||||||
|
|
||||||
|
if !self.store(self.deref(cell)).is_var() {
|
||||||
|
self.fail = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(HeapCellValueTag::AttrVar |
|
||||||
|
HeapCellValueTag::StackVar |
|
||||||
|
HeapCellValueTag::Var) => {
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
self.fail = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
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) {
|
pub(super) fn write_literal_to_var(&mut self, deref_v: HeapCellValue, lit: HeapCellValue) {
|
||||||
@@ -1979,9 +2009,9 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
(HeapCellValueTag::CStr, cstr_atom) => {
|
(HeapCellValueTag::CStr, cstr_atom) => {
|
||||||
read_heap_cell!(store_v,
|
read_heap_cell!(store_v,
|
||||||
(HeapCellValueTag::PStrLoc
|
(HeapCellValueTag::PStrLoc |
|
||||||
| HeapCellValueTag::Lis
|
HeapCellValueTag::Lis |
|
||||||
| HeapCellValueTag::Str) => {
|
HeapCellValueTag::Str) => {
|
||||||
self.match_partial_string(store_v, cstr_atom, false);
|
self.match_partial_string(store_v, cstr_atom, false);
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var) => {
|
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var) => {
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ impl<'a> HeapPStrIter<'a> {
|
|||||||
self.brent_st.num_steps()
|
self.brent_st.num_steps()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline(always)]
|
||||||
pub fn chars(mut self) -> PStrCharsIter<'a> {
|
pub fn chars(mut self) -> PStrCharsIter<'a> {
|
||||||
let item = self.next();
|
let item = self.next();
|
||||||
PStrCharsIter { iter: self, item }
|
PStrCharsIter { iter: self, item }
|
||||||
@@ -122,9 +122,11 @@ impl<'a> HeapPStrIter<'a> {
|
|||||||
prefix_len: 0,
|
prefix_len: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut final_result = None;
|
||||||
|
|
||||||
while let Some(PStrIterStep { iteratee, next_hare }) = self.step(self.brent_st.hare) {
|
while let Some(PStrIterStep { iteratee, next_hare }) = self.step(self.brent_st.hare) {
|
||||||
self.brent_st.hare = next_hare;
|
self.brent_st.hare = next_hare;
|
||||||
self.focus = self.heap[next_hare];
|
self.focus = self.heap[iteratee.focus()];
|
||||||
|
|
||||||
result.focus = iteratee.focus();
|
result.focus = iteratee.focus();
|
||||||
result.offset = iteratee.offset();
|
result.offset = iteratee.offset();
|
||||||
@@ -139,7 +141,8 @@ impl<'a> HeapPStrIter<'a> {
|
|||||||
result.offset += c1.len_utf8();
|
result.offset += c1.len_utf8();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Some(result);
|
final_result = Some(result);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PStrIteratee::PStrSegment(_, pstr_atom, n) => {
|
PStrIteratee::PStrSegment(_, pstr_atom, n) => {
|
||||||
@@ -158,7 +161,8 @@ impl<'a> HeapPStrIter<'a> {
|
|||||||
result.prefix_len += s.len();
|
result.prefix_len += s.len();
|
||||||
result.offset += s.len();
|
result.offset += s.len();
|
||||||
|
|
||||||
return Some(result);
|
final_result = Some(result);
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@@ -166,11 +170,19 @@ impl<'a> HeapPStrIter<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s.len() == result.prefix_len {
|
if s.len() == result.prefix_len {
|
||||||
return Some(result);
|
final_result = Some(result);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(result)
|
if let Some(result) = &final_result {
|
||||||
|
if self.at_string_terminator() {
|
||||||
|
self.focus = empty_list_as_cell!();
|
||||||
|
self.brent_st.hare = result.focus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final_result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn walk_hare_to_cycle_end(&mut self) {
|
fn walk_hare_to_cycle_end(&mut self) {
|
||||||
@@ -371,7 +383,7 @@ impl<'a> HeapPStrIter<'a> {
|
|||||||
|
|
||||||
self.focus = self.heap[iteratee.focus()];
|
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.focus = empty_list_as_cell!();
|
||||||
self.brent_st.hare = iteratee.focus();
|
self.brent_st.hare = iteratee.focus();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user