]> Repositorios git - scryer-prolog.git/commitdiff
index inlined and builtin clausetypes inside a BTreeMap
authorMark Thom <[email protected]>
Wed, 27 Mar 2019 03:59:50 +0000 (21:59 -0600)
committerMark Thom <[email protected]>
Wed, 27 Mar 2019 03:59:50 +0000 (21:59 -0600)
Cargo.toml
src/main.rs
src/prolog/clause_types.rs
src/prolog/forms.rs
src/prolog/machine/machine_indices.rs
src/prolog/macros.rs
src/prolog/mod.rs

index 3c06eb76c2715ccf4a09422840dbb406c8b5d302..ca7f135c61ccecd28bab3fd7d456dc4961f243f9 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "scryer-prolog"
-version = "0.8.20"
+version = "0.8.21"
 authors = ["Mark Thom <[email protected]>"]
 repository = "https://github.com/mthom/scryer-prolog"
 description = "A modern Prolog implementation written mostly in Rust."
@@ -14,8 +14,9 @@ cfg-if = "0.1.7"
 downcast = "0.9.1"
 num = "0.2"
 ordered-float = "0.5.0"
-prolog_parser = "0.8.1"
+prolog_parser = "0.8.2"
 readline_rs_compat = { version = "0.1.7", optional = true }
+ref_thread_local = "0.0.0"
 
 [dependencies.termion]
 version = "1.4.0"
\ No newline at end of file
index 71857b438bf5da4f51568121a9e18ba1e3d70bd5..ebfe87c22dda1d145128bc6d1bc343746faaa18f 100644 (file)
@@ -1,6 +1,7 @@
 #[macro_use] extern crate cfg_if;
 #[macro_use] extern crate downcast;
 #[macro_use] extern crate prolog_parser;
+#[macro_use] extern crate ref_thread_local;
 
 cfg_if! {
     if #[cfg(feature = "readline_rs_compat")] {
index dc5f78b57e82e5bf91faca9352bc943530364221..537605b4055a6d0a5461956d075a25aeffd89d25 100644 (file)
@@ -3,7 +3,11 @@ use prolog_parser::ast::*;
 use prolog::forms::OpDecl;
 use prolog::machine::machine_indices::*;
 
-#[derive(Clone, Copy, PartialEq)]
+use ref_thread_local::RefThreadLocal;
+
+use std::collections::BTreeMap;
+
+#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
 pub enum CompareNumberQT {
     GreaterThan,
     LessThan,
@@ -26,7 +30,7 @@ impl CompareNumberQT {
     }
 }
 
-#[derive(Clone, Copy, PartialEq)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub enum CompareTermQT {
     LessThan,
     LessThanOrEqual,
@@ -49,7 +53,7 @@ impl CompareTermQT {
     }
 }
 
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
 pub enum ArithmeticTerm {
     Reg(RegType),
     Interm(usize),
@@ -66,7 +70,7 @@ impl ArithmeticTerm {
     }
 }
 
-#[derive(Clone, PartialEq)]
+#[derive(Clone, Eq, Ord, PartialOrd, PartialEq)]
 pub enum InlinedClauseType {
     CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm),
     IsAtom(RegType),
@@ -81,6 +85,58 @@ pub enum InlinedClauseType {
     IsVar(RegType)
 }
 
+ref_thread_local! {
+    static managed CLAUSE_TYPE_FORMS: BTreeMap<(&'static str, usize), ClauseType> = {
+        let mut m = BTreeMap::new();
+
+        let r1 = temp_v!(1);
+        let r2 = temp_v!(2);
+
+        m.insert((">", 2),
+                 ClauseType::Inlined(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThan, ar_reg!(r1), ar_reg!(r2))));
+        m.insert(("<", 2),
+                 ClauseType::Inlined(InlinedClauseType::CompareNumber(CompareNumberQT::LessThan, ar_reg!(r1), ar_reg!(r2))));
+        m.insert((">=", 2), ClauseType::Inlined(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThanOrEqual, ar_reg!(r1), ar_reg!(r2))));
+        m.insert(("=<", 2), ClauseType::Inlined(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual, ar_reg!(r1), ar_reg!(r2))));
+        m.insert(("=:=", 2), ClauseType::Inlined(InlinedClauseType::CompareNumber(CompareNumberQT::Equal, ar_reg!(r1), ar_reg!(r2))));
+        m.insert(("=\\=", 2), ClauseType::Inlined(InlinedClauseType::CompareNumber(CompareNumberQT::NotEqual, ar_reg!(r1), ar_reg!(r2))));
+        m.insert(("atom", 1), ClauseType::Inlined(InlinedClauseType::IsAtom(r1)));
+        m.insert(("atomic", 1), ClauseType::Inlined(InlinedClauseType::IsAtomic(r1)));
+        m.insert(("compound", 1), ClauseType::Inlined(InlinedClauseType::IsCompound(r1)));
+        m.insert(("integer", 1), ClauseType::Inlined(InlinedClauseType::IsInteger(r1)));
+        m.insert(("rational", 1), ClauseType::Inlined(InlinedClauseType::IsRational(r1)));
+        m.insert(("string", 1), ClauseType::Inlined(InlinedClauseType::IsString(r1)));
+        m.insert(("float", 1), ClauseType::Inlined(InlinedClauseType::IsFloat(r1)));
+        m.insert(("nonvar", 1), ClauseType::Inlined(InlinedClauseType::IsNonVar(r1)));
+        m.insert(("is_partial_string", 1), ClauseType::Inlined(InlinedClauseType::IsPartialString(r1)));
+        m.insert(("var", 1), ClauseType::Inlined(InlinedClauseType::IsVar(r1)));
+        m.insert(("acyclic_term", 1), ClauseType::BuiltIn(BuiltInClauseType::AcyclicTerm));
+        m.insert(("arg", 3), ClauseType::BuiltIn(BuiltInClauseType::Arg));
+        m.insert(("compare", 3), ClauseType::BuiltIn(BuiltInClauseType::Compare));
+        m.insert(("@>", 2), ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(CompareTermQT::GreaterThan)));
+        m.insert(("@<", 2), ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(CompareTermQT::LessThan)));
+        m.insert(("@>=", 2), ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(CompareTermQT::GreaterThanOrEqual)));
+        m.insert(("@=<", 2), ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(CompareTermQT::LessThanOrEqual)));
+        m.insert(("\\=@=", 2), ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(CompareTermQT::NotEqual)));
+        m.insert(("=@=", 2), ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(CompareTermQT::Equal)));
+        m.insert(("copy_term", 2), ClauseType::BuiltIn(BuiltInClauseType::CopyTerm));
+        m.insert(("cyclic_term", 1), ClauseType::BuiltIn(BuiltInClauseType::CyclicTerm));
+        m.insert(("==", 2), ClauseType::BuiltIn(BuiltInClauseType::Eq));
+        m.insert(("functor", 3), ClauseType::BuiltIn(BuiltInClauseType::Functor));
+        m.insert(("ground", 1), ClauseType::BuiltIn(BuiltInClauseType::Ground));
+        m.insert(("is", 2), ClauseType::BuiltIn(BuiltInClauseType::Is(r1, ar_reg!(r2))));
+        m.insert(("keysort", 2), ClauseType::BuiltIn(BuiltInClauseType::KeySort));
+        m.insert(("nl", 0), ClauseType::BuiltIn(BuiltInClauseType::Nl));
+        m.insert(("\\==", 2), ClauseType::BuiltIn(BuiltInClauseType::NotEq));
+        m.insert(("partial_string", 2), ClauseType::BuiltIn(BuiltInClauseType::PartialString));
+        m.insert(("read", 1), ClauseType::BuiltIn(BuiltInClauseType::Read));
+        m.insert(("$reify_switch", 3), ClauseType::BuiltIn(BuiltInClauseType::ReifySwitch));
+        m.insert(("sort", 2), ClauseType::BuiltIn(BuiltInClauseType::Sort));
+
+        m
+    };
+}
+
 impl InlinedClauseType {
     pub fn name(&self) -> &'static str {
         match self {
@@ -97,43 +153,9 @@ impl InlinedClauseType {
             &InlinedClauseType::IsVar(..) => "var",
         }
     }
-
-    pub fn from(name: &str, arity: usize) -> Option<Self> {
-        let r1 = temp_v!(1);
-        let r2 = temp_v!(2);
-
-        let a1 = ArithmeticTerm::Reg(r1);
-        let a2 = ArithmeticTerm::Reg(r2);
-
-        match (name, arity) {
-            (">", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThan, a1, a2)),
-            ("<", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThan, a1, a2)),
-            (">=", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThanOrEqual,a1, a2)),
-            ("=<", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual, a1, a2)),
-            ("=\\=", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::NotEqual, a1, a2)),
-            ("=:=", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::Equal, a1, a2)),
-            ("atom", 1) => Some(InlinedClauseType::IsAtom(r1)),
-            ("atomic", 1) => Some(InlinedClauseType::IsAtomic(r1)),
-            ("compound", 1) => Some(InlinedClauseType::IsCompound(r1)),
-            ("integer", 1) => Some(InlinedClauseType::IsInteger(r1)),
-            ("rational", 1) => Some(InlinedClauseType::IsRational(r1)),
-            ("string", 1) => Some(InlinedClauseType::IsString(r1)),
-            ("float", 1) => Some(InlinedClauseType::IsFloat(r1)),
-            ("nonvar", 1) => Some(InlinedClauseType::IsNonVar(r1)),
-            ("var", 1) => Some(InlinedClauseType::IsVar(r1)),
-            ("is_partial_string", 1) => Some(InlinedClauseType::IsPartialString(r1)),
-            _ => None
-        }
-    }
 }
 
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
 pub enum SystemClauseType {
     AbolishClause,
     AbolishModuleClause,
@@ -274,7 +296,7 @@ impl SystemClauseType {
             &SystemClauseType::WriteTerm => clause_name!("$write_term"),
         }
     }
-    
+
     pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
         match (name, arity) {
             ("$abolish_clause", 2) => Some(SystemClauseType::AbolishClause),
@@ -347,7 +369,7 @@ impl SystemClauseType {
     }
 }
 
-#[derive(Clone, PartialEq)]
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd)]
 pub enum BuiltInClauseType {
     AcyclicTerm,
     Arg,
@@ -368,7 +390,7 @@ pub enum BuiltInClauseType {
     Sort,
 }
 
-#[derive(Clone)]
+#[derive(Clone, PartialEq, Eq, Ord, PartialOrd)]
 pub enum ClauseType {
     BuiltIn(BuiltInClauseType),
     CallN,
@@ -423,34 +445,6 @@ impl BuiltInClauseType {
             &BuiltInClauseType::Sort => 2,
         }
     }
-
-    pub fn from(name: &str, arity: usize) -> Option<Self> {
-        match (name, arity) {
-            ("acyclic_term", 1) => Some(BuiltInClauseType::AcyclicTerm),
-            ("arg", 3) => Some(BuiltInClauseType::Arg),
-            ("compare", 3) => Some(BuiltInClauseType::Compare),
-            ("cyclic_term", 1) => Some(BuiltInClauseType::CyclicTerm),
-            ("@>", 2) => Some(BuiltInClauseType::CompareTerm(CompareTermQT::GreaterThan)),
-            ("@<", 2) => Some(BuiltInClauseType::CompareTerm(CompareTermQT::LessThan)),
-            ("@>=", 2) => Some(BuiltInClauseType::CompareTerm(CompareTermQT::GreaterThanOrEqual)),
-            ("@=<", 2) => Some(BuiltInClauseType::CompareTerm(CompareTermQT::LessThanOrEqual)),
-            ("\\=@=", 2) => Some(BuiltInClauseType::CompareTerm(CompareTermQT::NotEqual)),
-            ("=@=", 2) => Some(BuiltInClauseType::CompareTerm(CompareTermQT::Equal)),
-            ("copy_term", 2) => Some(BuiltInClauseType::CopyTerm),
-            ("==", 2) => Some(BuiltInClauseType::Eq),
-            ("functor", 3) => Some(BuiltInClauseType::Functor),
-            ("ground", 1) => Some(BuiltInClauseType::Ground),
-            ("is", 2) => Some(BuiltInClauseType::Is(temp_v!(1), ArithmeticTerm::Reg(temp_v!(2)))),
-            ("keysort", 2) => Some(BuiltInClauseType::KeySort),
-            ("nl", 0) => Some(BuiltInClauseType::Nl),
-            ("\\==", 2) => Some(BuiltInClauseType::NotEq),
-            ("partial_string", 2) => Some(BuiltInClauseType::PartialString),
-            ("read", 1) => Some(BuiltInClauseType::Read),
-            ("$reify_switch", 3) => Some(BuiltInClauseType::ReifySwitch),
-            ("sort", 2) => Some(BuiltInClauseType::Sort),
-            _ => None
-        }
-    }
 }
 
 impl ClauseType {
@@ -481,26 +475,19 @@ impl ClauseType {
     }
 
     pub fn from(name: ClauseName, arity: usize, spec: Option<(usize, Specifier)>) -> Self {
-        InlinedClauseType::from(name.as_str(), arity)
-            .map(ClauseType::Inlined)
-            .unwrap_or_else(|| {
-                BuiltInClauseType::from(name.as_str(), arity)
-                    .map(ClauseType::BuiltIn)
-                    .unwrap_or_else(|| {
-                        SystemClauseType::from(name.as_str(), arity)
-                            .map(ClauseType::System)
-                            .unwrap_or_else(|| {
-                                if let Some(spec) = spec {
-                                    let op_decl = OpDecl(spec.0, spec.1, name);
-                                    ClauseType::Op(op_decl, CodeIndex::default())
-                                } else if name.as_str() == "call" {
-                                    ClauseType::CallN
-                                } else {
-                                    ClauseType::Named(name, arity, CodeIndex::default())
-                                }
-                            })
-                    })
-            })
+        CLAUSE_TYPE_FORMS.borrow().get(&(name.as_str(), arity)).cloned()
+            .unwrap_or_else(||
+                SystemClauseType::from(name.as_str(), arity)
+                    .map(ClauseType::System)
+                    .unwrap_or_else(||
+                        if let Some(spec) = spec {
+                            let op_decl = OpDecl(spec.0, spec.1, name);
+                            ClauseType::Op(op_decl, CodeIndex::default())
+                        } else if name.as_str() == "call" {
+                            ClauseType::CallN
+                        } else {
+                            ClauseType::Named(name, arity, CodeIndex::default())
+                        }))
     }
 }
 
index 62ed3a48bfaa2ba8d8082935334eea6102d144cc..324e31b05922e9d66da189f1d9739eacdbbcaa44 100644 (file)
@@ -167,7 +167,7 @@ impl Declaration {
     }
 }
 
-#[derive(Clone)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
 pub struct OpDecl(pub usize, pub Specifier, pub ClauseName);
 
 impl OpDecl {
index a540dde9a4e9aa1ac193a623f5af890b61f40f1b..d88090b1a4d07102131a285a66738d5efcaa3e94 100644 (file)
@@ -168,13 +168,13 @@ impl HeapCellValue {
     }
 }
 
-#[derive(Clone, Copy, PartialEq)]
+#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
 pub enum IndexPtr {
     Undefined,
     Index(usize),
 }
 
-#[derive(Clone)]
+#[derive(Clone, Ord, PartialOrd, Eq, PartialEq)]
 pub struct CodeIndex(pub Rc<RefCell<(IndexPtr, ClauseName)>>);
 
 impl CodeIndex {
@@ -505,7 +505,7 @@ impl IndexStore {
 pub type CodeDir = HashMap<PredicateKey, CodeIndex>;
 pub type TermDir = HashMap<PredicateKey, (Predicate, VecDeque<TopLevel>)>;
 
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
 pub enum CompileTimeHook {
     GoalExpansion,
     TermExpansion,
index e4fea309176c98b95dfd7fa0550eed9f8b18e6bf..3ce06c8920754f8227e61a97a7528a3b5f97d2b4 100644 (file)
@@ -261,3 +261,9 @@ macro_rules! discard_result {
         }
     )
 }
+
+macro_rules! ar_reg {
+    ($r: expr) => (
+        ArithmeticTerm::Reg($r)
+    )
+}
index 9ef14b8ac5e549d96c34ac6c376f00ff860e633b..4d41801cfa133c051d7d22a9120170ba2c0f4e19 100644 (file)
@@ -3,8 +3,8 @@ extern crate ordered_float;
 extern crate prolog_parser;
 
 pub mod instructions;
-mod clause_types;
 #[macro_use] mod macros;
+mod clause_types;
 #[macro_use] mod allocator;
 mod fixtures;
 pub mod machine;