]> Repositorios git - scryer-prolog.git/commitdiff
add StringList internal datatype
authorMark Thom <[email protected]>
Tue, 21 Aug 2018 04:00:38 +0000 (22:00 -0600)
committerMark Thom <[email protected]>
Tue, 21 Aug 2018 04:00:38 +0000 (22:00 -0600)
src/prolog/ast.rs
src/prolog/mod.rs
src/prolog/string_list.rs [new file with mode: 0644]
src/prolog/tabled_rc.rs

index b67c33911c5cf12e98f1a9c74352d3f2bfcdd328..54eee85eb2d0380b22ff07da5028ee69ce1eca00 100644 (file)
@@ -897,8 +897,7 @@ impl ClauseName {
             ClauseName::BuiltIn(s) =>
                 ClauseName::BuiltIn(defrock_brackets(s)),
             ClauseName::User(s) =>
-                ClauseName::User(tabled_rc!(defrock_brackets(s.as_str()).to_owned(),
-                                            s.atom_tbl()))
+                ClauseName::User(tabled_rc!(defrock_brackets(s.as_str()).to_owned(), s.table()))
         }
     }
 }
index 6d16892d72ea814460bd70b1888bc88c5064851c..eb4e57f4c55a1d370f410ad4f75c41fd3eb46f71 100644 (file)
@@ -27,3 +27,4 @@ pub mod heap_print;
 pub mod targets;
 pub mod tabled_rc;
 pub mod read;
+pub mod string_list;
diff --git a/src/prolog/string_list.rs b/src/prolog/string_list.rs
new file mode 100644 (file)
index 0000000..3c1dc63
--- /dev/null
@@ -0,0 +1,82 @@
+use prolog::tabled_rc::*;
+
+use std::cell::{Ref, RefCell};
+use std::cmp::Ordering;
+use std::hash::{Hash, Hasher};
+use std::ops::{Index, RangeTo};
+
+#[derive(PartialOrd, PartialEq, Ord, Eq)]
+pub struct StringListWrapper(RefCell<String>);
+
+impl Hash for StringListWrapper {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.0.borrow().hash(state)
+    }
+}
+
+// cursor is ignored if the double_quotes flag is set to atom
+#[derive(Clone)]
+pub struct StringList {
+    body: TabledRc<StringListWrapper>,
+    cursor: usize, // use this to generate a chars() iterator on the fly,
+                   // and skip over the first cursor chars. 
+    expandable: bool
+}
+
+impl Hash for StringList {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.borrow().hash(state)
+    }
+}
+
+impl PartialOrd for StringList {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering>
+    {
+        Some(self.body.cmp(&other.body))
+    }
+}
+
+impl Ord for StringList {
+    fn cmp(&self, other: &Self) -> Ordering
+    {
+        self.body.cmp(&other.body)
+    }
+}
+
+impl PartialEq for StringList {
+    fn eq(&self, other: &Self) -> bool
+    {
+        self.body == other.body
+    }
+}
+
+impl Eq for StringList {}
+
+impl StringList {
+    #[inline]
+    pub fn new(s: String, expandable: bool, string_tbl: TabledData<StringListWrapper>) -> Self {
+        let body = TabledRc::new(StringListWrapper(RefCell::new(s)), string_tbl);
+
+        StringList {
+            cursor: 0,
+            body,
+            expandable
+        }
+    }
+
+    #[inline]
+    pub fn tail(&self) -> Self {
+        let mut new_string_list = self.clone();
+        
+        if let Some(c) = self.borrow()[self.cursor ..].chars().next() {        
+            new_string_list.cursor += c.len_utf8();
+        }
+        
+        new_string_list
+    }
+
+    #[inline]
+    pub fn borrow(&self) -> Ref<String> {
+        self.body.0.borrow()
+    }
+}
index 30824f91e385ffb09c39bf3ad87b2f6dd3030f82..a7a093fbfb35f1ce50cd9d3bcbbc8115d4d8ac9d 100644 (file)
@@ -8,12 +8,19 @@ use std::rc::Rc;
 
 pub type TabledData<T> = Rc<RefCell<HashSet<Rc<T>>>>;
 
-#[derive(Clone)]
 pub struct TabledRc<T: Hash + Eq> {
     atom: Rc<T>,
     table: TabledData<T>
 }
 
+// this Clone instance is manually defined to prevent the compiler
+// from complaining when deriving Clone for StringList.
+impl<T: Hash + Eq> Clone for TabledRc<T> {
+    fn clone(&self) -> Self {
+        TabledRc { atom: self.atom.clone(), table: self.table().clone() }
+    }
+}
+
 impl<T: Ord + Hash + Eq> PartialOrd for TabledRc<T> {
     fn partial_cmp(&self, other: &Self) -> Option<Ordering>
     {
@@ -55,7 +62,7 @@ impl<T: Hash + Eq> TabledRc<T> {
         TabledRc { atom, table }
     }
 
-    pub fn atom_tbl(&self) -> TabledData<T> {
+    pub fn table(&self) -> TabledData<T> {
         self.table.clone()
     }
 }