]> Repositorios git - scryer-prolog.git/commitdiff
correct handling of strings and partial strings as lists, print bar operator with...
authorMark Thom <[email protected]>
Sun, 1 Mar 2020 07:00:40 +0000 (00:00 -0700)
committerMark Thom <[email protected]>
Sun, 1 Mar 2020 07:00:40 +0000 (00:00 -0700)
src/prolog/heap_print.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs

index 407f57a38b1edb3eaeff7578f98482889ae4dabd..7f8fed170eae5c557988d051d54acdb31453d7df 100644 (file)
@@ -157,6 +157,7 @@ fn char_to_string(c: char) -> String {
 #[derive(Clone)]
 pub enum TokenOrRedirect {
     Atom(ClauseName),
+    BarAsOp,
     Op(ClauseName, SharedOpDesc),
     NumberedVar(String),
     CompositeRedirect(DirectedOp),
@@ -531,8 +532,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
     fn format_prefix_op_with_space(&mut self, name: ClauseName, spec: SharedOpDesc) {
         let op = DirectedOp::Left(name.clone(), spec);
 
-        self.state_stack
-            .push(TokenOrRedirect::CompositeRedirect(op));
+        self.state_stack.push(TokenOrRedirect::CompositeRedirect(op));
         self.state_stack.push(TokenOrRedirect::Space);
         self.state_stack.push(TokenOrRedirect::Atom(name));
     }
@@ -541,11 +541,9 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
         let left_directed_op = DirectedOp::Left(name.clone(), spec.clone());
         let right_directed_op = DirectedOp::Right(name.clone(), spec.clone());
 
-        self.state_stack
-            .push(TokenOrRedirect::CompositeRedirect(left_directed_op));
-        self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
-        self.state_stack
-            .push(TokenOrRedirect::CompositeRedirect(right_directed_op));
+        self.state_stack.push(TokenOrRedirect::CompositeRedirect(left_directed_op));
+        self.state_stack.push(TokenOrRedirect::BarAsOp);
+        self.state_stack.push(TokenOrRedirect::CompositeRedirect(right_directed_op));
     }
 
     fn format_curly_braces(&mut self) {
@@ -994,6 +992,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
             if let Some(loc_data) = self.state_stack.pop() {
                 match loc_data {
                     TokenOrRedirect::Atom(atom) => self.print_atom(&atom),
+                    TokenOrRedirect::BarAsOp => self.append_str(" | "),
                     TokenOrRedirect::Op(atom, _) => self.print_op(atom.as_str()),
                     TokenOrRedirect::NumberedVar(num_var) => self.append_str(num_var.as_str()),
                     TokenOrRedirect::CompositeRedirect(op) => {
index 0cb9a42e7c118cdd8c8884f033046f5b0839d26f..b2f009726a8df89b8ad744a4fe61e9e45b8debcd 100644 (file)
@@ -249,18 +249,41 @@ pub(super) enum MachineMode {
 #[derive(Clone)]
 pub(super) enum HeapPtr {
     HeapCell(usize),
-    PStrLocation(usize, usize),
-    String(usize, Rc<String>),
+    PStrChar(usize, usize),
+    PStrTail(usize, usize),
+    StringChar(usize, Rc<String>),
+    StringTail(usize, Rc<String>),
 }
 
 impl HeapPtr {
     #[inline]
     pub(super)
-    fn as_addr(&self) -> Addr {
+    fn read(&self, heap: &Heap) -> 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())),
+            &HeapPtr::HeapCell(h) =>
+                Addr::HeapCell(h),
+            &HeapPtr::PStrChar(h, n) =>
+                if let HeapCellValue::PartialString(ref pstr) = &heap[h] {
+                    let s = pstr.block_as_str();
+
+                    if let Some(c) = s[n ..].chars().next() {
+                        Addr::Con(Constant::Char(c))
+                    } else {
+                        Addr::PStrTail(h, n)
+                    }
+                } else {
+                    unreachable!()
+                },
+            &HeapPtr::PStrTail(h, n) =>
+                Addr::PStrTail(h, n),
+            &HeapPtr::StringChar(n, ref s) =>
+                if let Some(c) = s[n ..].chars().next() {
+                    Addr::Con(Constant::Char(c))
+                } else {
+                    Addr::Con(Constant::EmptyList)
+                },
+            &HeapPtr::StringTail(n, ref s) =>
+                Addr::Con(Constant::String(n, s.clone())),
         }
     }
 }
index fb36d8cbab93135795ad377a7cbe680f1ac515f1..9ac09ca93ca0f56223fbac734f42ea7078ec24e5 100644 (file)
@@ -650,7 +650,7 @@ impl MachineState {
             HeapPtr::HeapCell(ref mut h) => {
                 *h += rhs;
             }
-            HeapPtr::PStrLocation(h, n) => {
+            HeapPtr::PStrChar(h, n) | HeapPtr::PStrTail(h, n) => {
                 match &self.heap[*h] {
                     HeapCellValue::PartialString(ref pstr) => {
                         let s = pstr.block_as_str();
@@ -658,16 +658,20 @@ impl MachineState {
                         for c in s[*n ..].chars().take(rhs) {
                             *n += c.len_utf8();
                         }
+
+                        self.s = HeapPtr::PStrTail(*h, *n);
                     }
                     _ => {
                         unreachable!()
                     }
                 }
             }
-            HeapPtr::String(ref mut n, ref s) => {
+            HeapPtr::StringChar(n, s) | HeapPtr::StringTail(n, s) => {
                 for c in s[*n ..].chars().take(rhs) {
                     *n += c.len_utf8();
                 }
+
+                self.s = HeapPtr::StringTail(*n, s.clone());
             }
         }
     }
@@ -1606,7 +1610,7 @@ impl MachineState {
                         match self.flags.double_quotes {
                             DoubleQuotes::Chars | DoubleQuotes::Codes
                                 if s.len() > n => {
-                                    self.s = HeapPtr::String(n, s);
+                                    self.s = HeapPtr::StringChar(n, s);
                                     self.mode = MachineMode::Read;
                                 }
                             _ => {
@@ -1614,7 +1618,7 @@ impl MachineState {
                             }
                         },
                     Addr::PStrLocation(h, n) => {
-                        self.s = HeapPtr::PStrLocation(h, n);
+                        self.s = HeapPtr::PStrChar(h, n);
                         self.mode = MachineMode::Read;
                     }
                     addr @ Addr::AttrVar(_)
@@ -1675,7 +1679,7 @@ impl MachineState {
             &FactInstruction::UnifyConstant(ref c) => {
                 match self.mode {
                     MachineMode::Read => {
-                        let addr = self.s.as_addr();
+                        let addr = self.s.read(&self.heap);
                         self.write_constant_to_var(addr, c.clone());
                     }
                     MachineMode::Write => {
@@ -1687,7 +1691,7 @@ impl MachineState {
             }
             &FactInstruction::UnifyVariable(reg) => {
                 match self.mode {
-                    MachineMode::Read => self[reg] = self.s.as_addr(),
+                    MachineMode::Read => self[reg] = self.s.read(&self.heap),
                     MachineMode::Write => {
                         let h = self.heap.h();
 
@@ -1702,7 +1706,7 @@ impl MachineState {
                 match self.mode {
                     MachineMode::Read => {
                         let reg_addr = self[reg].clone();
-                        self.unify(reg_addr, self.s.as_addr());
+                        self.unify(reg_addr, self.s.read(&self.heap));
                     }
                     MachineMode::Write => {
                         let addr = self.deref(self[reg].clone());
@@ -1730,7 +1734,7 @@ impl MachineState {
                 match self.mode {
                     MachineMode::Read => {
                         let reg_addr = self[reg].clone();
-                        self.unify(reg_addr, self.s.as_addr());
+                        self.unify(reg_addr, self.s.read(&self.heap));
                     }
                     MachineMode::Write => {
                         let heap_val = self.store(self[reg].clone());