From: Mark Thom Date: Sun, 1 May 2022 01:51:19 +0000 (-0600) Subject: fix match_partial_string, compare_pstr_to_string (#1451) X-Git-Tag: v0.9.1~42 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=789f662ec87d30f9783d82c847a8bd926d82cf50;p=scryer-prolog.git fix match_partial_string, compare_pstr_to_string (#1451) --- diff --git a/src/machine/dispatch.rs b/src/machine/dispatch.rs index d81cb600..514f80ac 100644 --- a/src/machine/dispatch.rs +++ b/src/machine/dispatch.rs @@ -2790,12 +2790,25 @@ impl Machine { 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; diff --git a/src/machine/machine_state_impl.rs b/src/machine/machine_state_impl.rs index 5223dc92..44509680 100644 --- a/src/machine/machine_state_impl.rs +++ b/src/machine/machine_state_impl.rs @@ -1863,7 +1863,9 @@ impl MachineState { 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) { @@ -1911,37 +1913,65 @@ impl MachineState { } } ); - } - 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) { @@ -1979,9 +2009,9 @@ impl MachineState { } (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) => { diff --git a/src/machine/partial_string.rs b/src/machine/partial_string.rs index b31935e2..cdc424dd 100644 --- a/src/machine/partial_string.rs +++ b/src/machine/partial_string.rs @@ -109,7 +109,7 @@ impl<'a> HeapPStrIter<'a> { self.brent_st.num_steps() } - #[inline] + #[inline(always)] pub fn chars(mut self) -> PStrCharsIter<'a> { let item = self.next(); PStrCharsIter { iter: self, item } @@ -122,9 +122,11 @@ impl<'a> HeapPStrIter<'a> { 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(); @@ -139,7 +141,8 @@ impl<'a> HeapPStrIter<'a> { result.offset += c1.len_utf8(); } } else { - return Some(result); + final_result = Some(result); + break; } } PStrIteratee::PStrSegment(_, pstr_atom, n) => { @@ -158,7 +161,8 @@ impl<'a> HeapPStrIter<'a> { result.prefix_len += s.len(); result.offset += s.len(); - return Some(result); + final_result = Some(result); + break; } else { return None; } @@ -166,11 +170,19 @@ impl<'a> HeapPStrIter<'a> { } 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) { @@ -371,7 +383,7 @@ impl<'a> HeapPStrIter<'a> { 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();