]> Repositorios git - scryer-prolog.git/commitdiff
fix match_partial_string, compare_pstr_to_string (#1451)
authorMark Thom <[email protected]>
Sun, 1 May 2022 01:51:19 +0000 (19:51 -0600)
committerMark Thom <[email protected]>
Sun, 1 May 2022 01:51:19 +0000 (19:51 -0600)
src/machine/dispatch.rs
src/machine/machine_state_impl.rs
src/machine/partial_string.rs

index d81cb600d1541e98aecbb3a6b15d248f1edb7123..514f80ac8fa0f18cfb8896410edc14f88f47ffe5 100644 (file)
@@ -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;
index 5223dc92e32ea68131795e9b040b3c157dfe91fe..445096806b4619aca85b4edd5f0956b1f586ba6f 100644 (file)
@@ -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) => {
index b31935e20b1be83eb6929e7b1980463d68c0a59c..cdc424dd8676975bb6ae2d21c59d7262ace84403 100644 (file)
@@ -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();