fix match_partial_string, compare_pstr_to_string (#1451)

This commit is contained in:
Mark Thom
2022-04-30 19:51:19 -06:00
parent 72536037ca
commit 789f662ec8
3 changed files with 94 additions and 39 deletions

View File

@@ -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;

View File

@@ -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) => {

View File

@@ -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();