]> Repositorios git - scryer-prolog.git/commitdiff
don't read into the heap while incrementing self.s (#1233, #1245)
authorMark Thom <[email protected]>
Tue, 25 Jan 2022 01:47:53 +0000 (18:47 -0700)
committerMark Thom <[email protected]>
Wed, 26 Jan 2022 03:37:29 +0000 (20:37 -0700)
src/examples/least_time.pl
src/machine/dispatch.rs
src/machine/machine_state.rs
src/machine/machine_state_impl.rs
src/machine/partial_string.rs

index 06eccd314ee147cfd2d60a738b0b4fdba8a4eca4..2b599b6028fb9712c830e1dc5a11e0e2947b2374 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 :- module(least_time, [find_min_time/2,
-                              write_time_nl/1]).
+                       write_time_nl/1]).
 
 
 :- use_module(library(dcgs)).
@@ -27,10 +27,10 @@ valid_time([H1,H2,M1,M2], T) :-
     memberd_t(M2, [0,1,2,3,4,5,6,7,8,9], TM2),
     (  maplist(=(true), [TH1, TH2, TM1, TM2]) ->
        (  H1 =:= 2 ->
-             (  H2 =< 3 ->
-                T = true
-             ;  T = false
-             )
+          (  H2 =< 3 ->
+             T = true
+          ;  T = false
+          )
        ;  T = true
        )
     ;  T = false
index 546781c7bc38fd8db2e126970c70c6d8d35af00a..4c02ea8bfae24d84ac36bace64eae34ba5e0bdb2 100644 (file)
@@ -2769,6 +2769,7 @@ impl Machine {
                             let (h, n) = pstr_loc_and_offset(&self.machine_st.heap, h);
 
                             self.machine_st.s = HeapPtr::PStrChar(h, n.get_num() as usize);
+                            self.machine_st.s_offset = 0;
                             self.machine_st.mode = MachineMode::Read;
                         }
                         (HeapCellValueTag::CStr) => {
@@ -2776,10 +2777,12 @@ impl Machine {
                             self.machine_st.heap.push(store_v);
 
                             self.machine_st.s = HeapPtr::PStrChar(h, 0);
+                            self.machine_st.s_offset = 0;
                             self.machine_st.mode = MachineMode::Read;
                         }
                         (HeapCellValueTag::Lis, l) => {
                             self.machine_st.s = HeapPtr::HeapCell(l);
+                            self.machine_st.s_offset = 0;
                             self.machine_st.mode = MachineMode::Read;
                         }
                         (HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => {
@@ -2827,6 +2830,7 @@ impl Machine {
                                 (HeapCellValueTag::Atom, (result_name, result_arity)) => {
                                     if arity == result_arity && name == result_name {
                                         self.machine_st.s = HeapPtr::HeapCell(a + 1);
+                                        self.machine_st.s_offset = 0;
                                         self.machine_st.mode = MachineMode::Read;
                                     } else {
                                         self.machine_st.backtrack();
@@ -2883,7 +2887,7 @@ impl Machine {
                                 self.machine_st.backtrack();
                                 continue;
                             } else {
-                                self.machine_st.increment_s_ptr(1);
+                                self.machine_st.s_offset += 1;
                             }
                         }
                         MachineMode::Write => {
@@ -2905,7 +2909,7 @@ impl Machine {
                                 self.machine_st.backtrack();
                                 continue;
                             } else {
-                                self.machine_st.increment_s_ptr(1);
+                                self.machine_st.s_offset += 1;
                             }
                         }
                         MachineMode::Write => {
@@ -2917,7 +2921,7 @@ impl Machine {
                                     let value = self.machine_st.heap[hc];
 
                                     self.machine_st.heap.push(value);
-                                    self.machine_st.increment_s_ptr(1);
+                                    self.machine_st.s_offset += 1;
                                 }
                                 _ => {
                                     self.machine_st.heap.push(heap_loc_as_cell!(h));
@@ -2937,7 +2941,7 @@ impl Machine {
                     match self.machine_st.mode {
                         MachineMode::Read => {
                             self.machine_st[reg] = self.machine_st.read_s();
-                            self.machine_st.increment_s_ptr(1);
+                            self.machine_st.s_offset += 1;
                         }
                         MachineMode::Write => {
                             let h = self.machine_st.heap.len();
@@ -2961,7 +2965,7 @@ impl Machine {
                                 self.machine_st.backtrack();
                                 continue;
                             } else {
-                                self.machine_st.increment_s_ptr(1);
+                                self.machine_st.s_offset += 1;
                             }
                         }
                         MachineMode::Write => {
@@ -2988,7 +2992,7 @@ impl Machine {
                 &Instruction::UnifyVoid(n) => {
                     match self.machine_st.mode {
                         MachineMode::Read => {
-                            self.machine_st.increment_s_ptr(n);
+                            self.machine_st.s_offset += n;
                         }
                         MachineMode::Write => {
                             let h = self.machine_st.heap.len();
index 11b2672add23b48b2eecea120380877cfba2ef9c..27a358845b2c88150a26d7d6778c59fe30dc57fb 100644 (file)
@@ -55,6 +55,7 @@ pub struct MachineState {
     pub arena: Arena,
     pub(super) pdl: Vec<HeapCellValue>,
     pub(super) s: HeapPtr,
+    pub(super) s_offset: usize,
     pub(super) p: usize,
     pub(super) oip: u32, // first internal code ptr
     pub(super) iip : u32, // second internal code ptr
index 6461f7f05309dcd0f5e4af65c05db6dbb8c0a521..373f87048b718d6b7868b20d5f0491cd9bbec02f 100644 (file)
@@ -28,6 +28,7 @@ impl MachineState {
             atom_tbl: AtomTable::new(),
             pdl: Vec::with_capacity(1024),
             s: HeapPtr::default(),
+            s_offset: 0,
             p: 0,
             oip: 0,
             iip: 0,
@@ -77,6 +78,7 @@ impl MachineState {
         )
     }
 
+    #[inline]
     pub fn deref(&self, mut addr: HeapCellValue) -> HeapCellValue {
         loop {
             let value = self.store(addr);
@@ -1390,28 +1392,25 @@ impl MachineState {
     }
 
     pub(crate) fn read_s(&mut self) -> HeapCellValue {
-        match &self.s {
-            &HeapPtr::HeapCell(h) => self.deref(self.heap[h]),
-            &HeapPtr::PStrChar(h, n) => {
+        match &mut self.s {
+            &mut HeapPtr::HeapCell(h) => self.deref(self.heap[h + self.s_offset]),
+            &mut HeapPtr::PStrChar(h, n) if self.s_offset == 0 => {
                 read_heap_cell!(self.heap[h],
                     (HeapCellValueTag::PStr, pstr_atom) => {
                         let pstr = PartialString::from(pstr_atom);
 
                         if let Some(c) = pstr.as_str_from(n).chars().next() {
                             char_as_cell!(c)
-                        } else { // if has_tail {
-                            self.deref(self.heap[h+1]) // heap_loc_as_cell!(h+1)
+                        } else {
+                            self.deref(self.heap[h+1])
                         }
-                        // } else {
-                        //     empty_list_as_cell!()
-                        // }
                     }
                     (HeapCellValueTag::CStr, cstr_atom) => {
                         let pstr = PartialString::from(cstr_atom);
 
                         if let Some(c) = pstr.as_str_from(n).chars().next() {
                             char_as_cell!(c)
-                        } else { // if has_tail {
+                        } else {
                             empty_list_as_cell!()
                         }
                     }
@@ -1420,14 +1419,25 @@ impl MachineState {
                     }
                 )
             }
-            &HeapPtr::PStrLocation(h, n) => {
+            &mut HeapPtr::PStrChar(h, ref mut n) |
+            &mut HeapPtr::PStrLocation(h, ref mut n) => {
                 read_heap_cell!(self.heap[h],
                     (HeapCellValueTag::PStr, pstr_atom) => {
-                        if n < pstr_atom.len() {
+                        let pstr = PartialString::from(pstr_atom);
+                        let n_offset: usize = pstr.as_str_from(*n)
+                            .chars()
+                            .take(self.s_offset)
+                            .map(|c| c.len_utf8())
+                            .sum();
+
+                        self.s_offset = 0;
+                        *n += n_offset;
+
+                        if *n < pstr_atom.len() {
                             let h_len = self.heap.len();
 
                             self.heap.push(pstr_offset_as_cell!(h));
-                            self.heap.push(fixnum_as_cell!(Fixnum::build_with(n as i64)));
+                            self.heap.push(fixnum_as_cell!(Fixnum::build_with(*n as i64)));
 
                             pstr_loc_as_cell!(h_len)
                         } else {
@@ -1435,11 +1445,21 @@ impl MachineState {
                         }
                     }
                     (HeapCellValueTag::CStr, cstr_atom) => {
-                        if n < cstr_atom.len() {
+                        let pstr = PartialString::from(cstr_atom);
+                        let n_offset: usize = pstr.as_str_from(*n)
+                            .chars()
+                            .take(self.s_offset)
+                            .map(|c| c.len_utf8())
+                            .sum();
+
+                        self.s_offset = 0;
+                        *n += n_offset;
+
+                        if *n < cstr_atom.len() {
                             let h_len = self.heap.len();
 
                             self.heap.push(pstr_offset_as_cell!(h));
-                            self.heap.push(fixnum_as_cell!(Fixnum::build_with(n as i64)));
+                            self.heap.push(fixnum_as_cell!(Fixnum::build_with(*n as i64)));
 
                             pstr_loc_as_cell!(h_len)
                         } else {
@@ -1821,30 +1841,6 @@ impl MachineState {
         Some(Ordering::Equal)
     }
 
-    pub(crate) fn increment_s_ptr(&mut self, rhs: usize) {
-        match &mut self.s {
-            HeapPtr::HeapCell(ref mut h) => {
-                *h += rhs;
-            }
-            &mut HeapPtr::PStrChar(h, ref mut n) | &mut HeapPtr::PStrLocation(h, ref mut n) => {
-                read_heap_cell!(self.heap[h],
-                    (HeapCellValueTag::PStr | HeapCellValueTag::CStr, pstr_atom) => {
-                        let pstr = PartialString::from(pstr_atom);
-
-                        for c in pstr.as_str_from(*n).chars().take(rhs) {
-                            *n += c.len_utf8();
-                        }
-
-                        self.s = HeapPtr::PStrLocation(h, *n);
-                    }
-                    _ => {
-                        unreachable!()
-                    }
-                )
-            }
-        }
-    }
-
     pub fn match_partial_string(&mut self, value: HeapCellValue, string: Atom, has_tail: bool) {
         let h = self.heap.len();
         self.heap.push(value);
@@ -1860,23 +1856,35 @@ impl MachineState {
                     (HeapCellValueTag::PStr | HeapCellValueTag::CStr, pstr_atom) => {
                         if has_tail {
                             self.s = HeapPtr::PStrLocation(focus, offset);
+                            self.s_offset = 0;
                             self.mode = MachineMode::Read;
                         } else if offset == pstr_atom.len() {
-                            let focus_addr = heap_pstr_iter.focus;
-                            unify!(self, focus_addr, empty_list_as_cell!());
+                            let focus = heap_pstr_iter.focus;
+                            unify!(self, focus, empty_list_as_cell!());
                         } else {
                             self.fail = true;
                         }
                     }
                     (HeapCellValueTag::PStrLoc | HeapCellValueTag::PStrOffset, h) => {
-                        if has_tail {
-                            let (h, _) = pstr_loc_and_offset(&self.heap, h);
+                        let (focus, _) = pstr_loc_and_offset(&self.heap, h);
+                        let pstr_atom = read_heap_cell!(self.heap[focus],
+                            (HeapCellValueTag::CStr | HeapCellValueTag::PStr, pstr_atom) => {
+                                pstr_atom
+                            }
+                            _ => {
+                                unreachable!()
+                            }
+                        );
 
-                            self.s = HeapPtr::PStrLocation(h, offset);
+                        if has_tail {
+                            self.s = HeapPtr::PStrLocation(focus, offset);
+                            self.s_offset = 0;
                             self.mode = MachineMode::Read;
+                        } else if offset == pstr_atom.len() {
+                            let focus = heap_pstr_iter.focus;
+                            unify!(self, focus, empty_list_as_cell!());
                         } else {
-                            let end_cell = heap_pstr_iter.focus;
-                            self.fail = end_cell != empty_list_as_cell!();
+                            self.fail = true;
                         }
                     }
                     _ => {
@@ -1884,6 +1892,7 @@ impl MachineState {
 
                         if has_tail {
                             self.s = HeapPtr::HeapCell(focus);
+                            self.s_offset = 0;
                             self.mode = MachineMode::Read;
                         } else {
                             let focus = heap_pstr_iter.focus;
@@ -1900,6 +1909,7 @@ impl MachineState {
 
                 let target_cell = if has_tail {
                     self.s = HeapPtr::HeapCell(h + 1);
+                    self.s_offset = 0;
                     self.mode = MachineMode::Read;
 
                     put_partial_string(
index ed1ad919b728ff8fcac6983bf818321f7715ecc2..421842970bf5f710aeadd05570673001872f9b71 100644 (file)
@@ -499,28 +499,6 @@ impl<'a> Iterator for PStrCharsIter<'a> {
             }
         }
 
-        /*
-        if !self.iter.at_string_terminator() {
-            // at a cycle. emit the final character.
-            match self.iter.step(self.iter.brent_st.hare) {
-                Some(PStrIterStep { iteratee: PStrIteratee::Char(_, c), .. }) => {
-                    self.iter.focus = empty_list_as_cell!();
-                    return Some(c);
-                }
-                Some(PStrIterStep { iteratee: PStrIteratee::PStrSegment(_, pstr_atom, _), .. }) => {
-                    self.iter.focus = empty_list_as_cell!();
-
-                    let c = PartialString::from(pstr_atom).as_str_from(0).chars().next().unwrap();
-                    return Some(c);
-                }
-                _ => {
-                    self.iter.focus = empty_list_as_cell!();
-                    return None;
-                }
-            }
-        }
-        */
-
         None
     }
 }