]> Repositorios git - scryer-prolog.git/commitdiff
add s pointers for strings and partial strings, put_unsafe_value calls store earlier...
authorMark Thom <[email protected]>
Sat, 29 Feb 2020 06:42:40 +0000 (23:42 -0700)
committerMark Thom <[email protected]>
Sat, 29 Feb 2020 06:42:40 +0000 (23:42 -0700)
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/mod.rs

index 143379e250fc16f700670439c76417f7d2210b7e..0cb9a42e7c118cdd8c8884f033046f5b0839d26f 100644 (file)
@@ -18,6 +18,7 @@ use std::cmp::Ordering;
 use std::io::{stdout, Write};
 use std::mem;
 use std::ops::{Index, IndexMut};
+use std::rc::Rc;
 
 pub struct Ball {
     pub(super) boundary: usize,
@@ -245,8 +246,33 @@ pub(super) enum MachineMode {
     Write,
 }
 
+#[derive(Clone)]
+pub(super) enum HeapPtr {
+    HeapCell(usize),
+    PStrLocation(usize, usize),
+    String(usize, Rc<String>),
+}
+
+impl HeapPtr {
+    #[inline]
+    pub(super)
+    fn as_addr(&self) -> Addr {
+        match self {
+            &HeapPtr::HeapCell(h) => Addr::HeapCell(h),
+            &HeapPtr::PStrLocation(h, n) => Addr::PStrLocation(h, n),
+            &HeapPtr::String(n, ref s) => Addr::Con(Constant::String(n, s.clone())),
+        }
+    }
+}
+
+impl Default for HeapPtr {
+    fn default() -> Self {
+        HeapPtr::HeapCell(0)
+    }
+}
+
 pub struct MachineState {
-    pub(super) s: usize,
+    pub(super) s: HeapPtr,
     pub(super) p: CodePtr,
     pub(super) b: usize,
     pub(super) b0: usize,
index 6b8849a53e489719576c9f84e1f42e2f1be8035a..fb36d8cbab93135795ad377a7cbe680f1ac515f1 100644 (file)
@@ -52,7 +52,7 @@ impl MachineState {
     pub(crate)
     fn new() -> Self {
         MachineState {
-            s: 0,
+            s: HeapPtr::default(),
             p: CodePtr::default(),
             b: 0,
             b0: 0,
@@ -82,7 +82,7 @@ impl MachineState {
     pub(crate)
     fn with_small_heap() -> Self {
         MachineState {
-            s: 0,
+            s: HeapPtr::default(),
             p: CodePtr::default(),
             b: 0,
             b0: 0,
@@ -645,6 +645,33 @@ impl MachineState {
         }
     }
 
+    fn increment_s_ptr(&mut self, rhs: usize) {
+        match &mut self.s {
+            HeapPtr::HeapCell(ref mut h) => {
+                *h += rhs;
+            }
+            HeapPtr::PStrLocation(h, n) => {
+                match &self.heap[*h] {
+                    HeapCellValue::PartialString(ref pstr) => {
+                        let s = pstr.block_as_str();
+
+                        for c in s[*n ..].chars().take(rhs) {
+                            *n += c.len_utf8();
+                        }
+                    }
+                    _ => {
+                        unreachable!()
+                    }
+                }
+            }
+            HeapPtr::String(ref mut n, ref s) => {
+                for c in s[*n ..].chars().take(rhs) {
+                    *n += c.len_utf8();
+                }
+            }
+        }
+    }
+
     pub(super)
     fn unwind_trail(&mut self, a1: usize, a2: usize) {
         // the sequence is reversed to respect the chronology of trail
@@ -1564,45 +1591,6 @@ impl MachineState {
         };
     }
 
-    fn get_char_list(&mut self, offset: usize, s: Rc<String>)
-    {
-        if let Some(c) = s[offset ..].chars().next() {
-            let h = self.heap.h();
-
-            self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::Char(c))));
-            self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String(
-                offset + c.len_utf8(),
-                s,
-            ))));
-
-            self.s = h;
-            self.mode = MachineMode::Read;
-        }
-    }
-
-    fn get_partial_string_list(&mut self, pstr_h: usize, offset: usize)
-    {
-        let (c, pstr_tail) =
-            if let HeapCellValue::PartialString(ref pstr) = &self.heap[pstr_h] {
-                let s = pstr.block_as_str();
-
-                if let Some(c) = s[offset ..].chars().next() {
-                    (c, Addr::PStrTail(pstr_h, offset + c.len_utf8()))
-                } else {
-                    unreachable!()
-                }
-            } else {
-                unreachable!()
-            };
-
-        self.s = self.heap.h();
-
-        self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::Char(c))));
-        self.heap.push(HeapCellValue::Addr(pstr_tail));
-
-        self.mode = MachineMode::Read;
-    }
-
     pub(super)
     fn execute_fact_instr(&mut self, instr: &FactInstruction) {
         match instr {
@@ -1618,14 +1606,16 @@ impl MachineState {
                         match self.flags.double_quotes {
                             DoubleQuotes::Chars | DoubleQuotes::Codes
                                 if s.len() > n => {
-                                    self.get_char_list(n, s)
+                                    self.s = HeapPtr::String(n, s);
+                                    self.mode = MachineMode::Read;
                                 }
                             _ => {
                                 self.fail = true
                             }
                         },
                     Addr::PStrLocation(h, n) => {
-                        self.get_partial_string_list(h, n)
+                        self.s = HeapPtr::PStrLocation(h, n);
+                        self.mode = MachineMode::Read;
                     }
                     addr @ Addr::AttrVar(_)
                   | addr @ Addr::StackCell(..)
@@ -1639,7 +1629,7 @@ impl MachineState {
                         self.mode = MachineMode::Write;
                     }
                     Addr::Lis(a) => {
-                        self.s = a;
+                        self.s = HeapPtr::HeapCell(a);
                         self.mode = MachineMode::Read;
                     }
                     _ => self.fail = true,
@@ -1654,7 +1644,7 @@ impl MachineState {
 
                         if let &HeapCellValue::NamedStr(narity, ref s, _) = result {
                             if narity == arity && ct.name() == *s {
-                                self.s = a + 1;
+                                self.s = HeapPtr::HeapCell(a + 1);
                                 self.mode = MachineMode::Read;
                             } else {
                                 self.fail = true;
@@ -1685,7 +1675,7 @@ impl MachineState {
             &FactInstruction::UnifyConstant(ref c) => {
                 match self.mode {
                     MachineMode::Read => {
-                        let addr = Addr::HeapCell(self.s);
+                        let addr = self.s.as_addr();
                         self.write_constant_to_var(addr, c.clone());
                     }
                     MachineMode::Write => {
@@ -1693,11 +1683,11 @@ impl MachineState {
                     }
                 };
 
-                self.s += 1;
+                self.increment_s_ptr(1);
             }
             &FactInstruction::UnifyVariable(reg) => {
                 match self.mode {
-                    MachineMode::Read => self[reg] = self.heap[self.s].as_addr(self.s),
+                    MachineMode::Read => self[reg] = self.s.as_addr(),
                     MachineMode::Write => {
                         let h = self.heap.h();
 
@@ -1706,15 +1696,13 @@ impl MachineState {
                     }
                 };
 
-                self.s += 1;
+                self.increment_s_ptr(1);
             }
             &FactInstruction::UnifyLocalValue(reg) => {
-                let s = self.s;
-
                 match self.mode {
                     MachineMode::Read => {
                         let reg_addr = self[reg].clone();
-                        self.unify(reg_addr, Addr::HeapCell(s));
+                        self.unify(reg_addr, self.s.as_addr());
                     }
                     MachineMode::Write => {
                         let addr = self.deref(self[reg].clone());
@@ -1725,7 +1713,7 @@ impl MachineState {
                                 let val = self.heap[hc].clone();
 
                                 self.heap.push(val);
-                                self.s += 1;
+                                self.increment_s_ptr(1);
 
                                 return;
                             }
@@ -1736,15 +1724,13 @@ impl MachineState {
                     }
                 };
 
-                self.s += 1;
+                self.increment_s_ptr(1);
             }
             &FactInstruction::UnifyValue(reg) => {
-                let s = self.s;
-
                 match self.mode {
                     MachineMode::Read => {
                         let reg_addr = self[reg].clone();
-                        self.unify(reg_addr, Addr::HeapCell(s));
+                        self.unify(reg_addr, self.s.as_addr());
                     }
                     MachineMode::Write => {
                         let heap_val = self.store(self[reg].clone());
@@ -1752,11 +1738,11 @@ impl MachineState {
                     }
                 };
 
-                self.s += 1;
+                self.increment_s_ptr(1);
             }
             &FactInstruction::UnifyVoid(n) => {
                 match self.mode {
-                    MachineMode::Read => self.s += n,
+                    MachineMode::Read => self.increment_s_ptr(n),
                     MachineMode::Write => {
                         let h = self.heap.h();
 
@@ -1865,16 +1851,15 @@ impl MachineState {
             &QueryInstruction::PutStructure(ref ct, arity, reg) => {
                 let h = self.heap.h();
 
-                self.heap
-                    .push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec()));
+                self.heap.push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec()));
                 self[reg] = Addr::Str(h);
             }
             &QueryInstruction::PutUnsafeValue(n, arg) => {
                 let e = self.e;
-                let addr = self.deref(Addr::StackCell(e, n));
+                let addr = self.store(self.deref(Addr::StackCell(e, n)));
 
                 if addr.is_protected(e) {
-                    self.registers[arg] = self.store(addr);
+                    self.registers[arg] = addr;
                 } else {
                     let h = self.heap.h();
 
@@ -3454,7 +3439,7 @@ impl MachineState {
         self.e = 0;
         self.b = 0;
         self.b0 = 0;
-        self.s = 0;
+        self.s = HeapPtr::default();
         self.tr = 0;
         self.p = CodePtr::default();
         self.cp = LocalCodePtr::default();
index accccbdcdfd4c4962610de01f4a76d1c72111bdf..5d20f00b62f1d019fce0e460631c6e913adbb95f 100644 (file)
@@ -699,7 +699,7 @@ impl Machine {
         snapshot.e = self.machine_st.e;
         snapshot.b = self.machine_st.b;
         snapshot.b0 = self.machine_st.b0;
-        snapshot.s = self.machine_st.s;
+        snapshot.s = self.machine_st.s.clone();
         snapshot.tr = self.machine_st.tr;
         snapshot.num_of_args = self.machine_st.num_of_args;