]> Repositorios git - scryer-prolog.git/commitdiff
correct the copier's mishandling of cyclic lists
authorMark Thom <[email protected]>
Fri, 4 May 2018 21:44:11 +0000 (15:44 -0600)
committerMark Thom <[email protected]>
Fri, 4 May 2018 21:44:11 +0000 (15:44 -0600)
src/prolog/copier.rs
src/tests.rs

index e3e268739f7ac37fe3abc73790429d18fa0b6b1c..5ca2d08ef5d6e4553529a96182f485cb15f8502a 100644 (file)
@@ -1,6 +1,7 @@
 use prolog::and_stack::*;
 use prolog::ast::*;
 
+use std::collections::HashMap;
 use std::ops::IndexMut;
 
 pub trait CopierTarget
@@ -21,6 +22,11 @@ pub trait CopierTarget
         let mut scan = self.source();
         let old_h = self.threshold();
 
+        // Lists have a flattened representation as structures,
+        // removing the need for a NamedStr variant, so we use a
+        // redirection table for reconstructing lists.
+        let mut list_redirect = HashMap::new();
+        
         self.push(HeapCellValue::Addr(a));
 
         while scan < self.threshold() {
@@ -30,6 +36,13 @@ pub trait CopierTarget
                 HeapCellValue::Addr(a) =>
                     match a.clone() {
                         Addr::Lis(a) => {
+                            if let Some(idx) = list_redirect.get(&a) {
+                                self[scan] = HeapCellValue::Addr(Addr::Lis(*idx));
+                                scan += 1;
+                                continue;
+                            }
+
+                            list_redirect.insert(a, self.threshold());                            
                             self[scan] = HeapCellValue::Addr(Addr::Lis(self.threshold()));
                             
                             let hcv = self[a].clone();
index 1bb6e8f650dcebf077381bf32878f0570f47ad9b..1b177d900152c9825a379f0c120bff6568a0b1f7 100644 (file)
@@ -1416,7 +1416,8 @@ fn test_queries_on_builtins()
                            [["Sorted = [1 - a, 1 - z, 1 - a, 2 - 99, 2 - 44, 3 - f(_7)]"]]);
     assert_prolog_success!(&mut wam, "?- keysort([X-1,1-1],[2-1,1-1]).",
                            [["X = 2"]]);
-    
+    //TODO: enable the printer to print cyclic terms. Then run this test.
+    //assert_prolog_failure!(&mut wam, "?- Pairs = [a-a|Pairs], keysort(Pairs, _).");
     assert_prolog_success!(&mut wam, "?- keysort([], L).",
                            [["L = []"]]);
     assert_prolog_success!(&mut wam, "?- catch(keysort([a|_], _), error(E, _), true).",