]> Repositorios git - scryer-prolog.git/commitdiff
eliminate need for embedded, handwritten WAM code.
authorMark Thom <[email protected]>
Thu, 10 May 2018 04:58:23 +0000 (22:58 -0600)
committerMark Thom <[email protected]>
Thu, 10 May 2018 04:58:23 +0000 (22:58 -0600)
13 files changed:
src/prolog/and_stack.rs
src/prolog/ast.rs
src/prolog/builtins.rs
src/prolog/codegen.rs
src/prolog/io.rs
src/prolog/iterators.rs
src/prolog/lib/builtins.pl [new file with mode: 0644]
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/mod.rs
src/prolog/macros.rs
src/prolog/or_stack.rs
src/prolog/toplevel.rs

index 3e2e653dbeecb2ec53adbae72ed247d88873a782..fdf22c2968b732f30f206253eecd7426e2acc786 100644 (file)
@@ -7,12 +7,12 @@ use std::vec::Vec;
 pub struct Frame {
     pub global_index: usize,
     pub e: usize,
-    pub cp: CodePtr,
+    pub cp: LocalCodePtr,
     perms: Vec<Addr>
 }
 
 impl Frame {
-    fn new(global_index: usize, fr: usize, e: usize, cp: CodePtr, n: usize) -> Self {
+    fn new(global_index: usize, fr: usize, e: usize, cp: LocalCodePtr, n: usize) -> Self {
         Frame {
             global_index,
             e: e,
@@ -29,7 +29,7 @@ impl AndStack {
         AndStack(Vec::new())
     }
 
-    pub fn push(&mut self, global_index: usize, e: usize, cp: CodePtr, n: usize) {
+    pub fn push(&mut self, global_index: usize, e: usize, cp: LocalCodePtr, n: usize) {
         let len = self.0.len();
         self.0.push(Frame::new(global_index, len, e, cp, n));
     }
index 969c587d3b8d03c244b4178d9f0e524e853b4329..34623fee7128fd2233d1110b9c324cc37062a08c 100644 (file)
@@ -193,7 +193,7 @@ pub trait SubModuleUser {
     fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool {
         let name = name.defrock_brackets();
         let mut found_op = false;
-        
+
         {
             let mut insert_op_dir = |fix| {
                 if let Some(op_data) = submodule.op_dir.get(&(name.clone(), fix)) {
@@ -229,7 +229,7 @@ pub trait SubModuleUser {
                 return EvalSession::from(SessionError::ModuleDoesNotContainExport);
             }
         }
-        
+
         EvalSession::EntrySuccess
     }
 
@@ -561,59 +561,83 @@ pub enum Term {
     Var(Cell<VarReg>, Rc<Var>)
 }
 
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, PartialEq)]
 pub enum InlinedClauseType {
-    CompareNumber(CompareNumberQT),
-    IsAtom,
-    IsAtomic,
-    IsCompound,
-    IsInteger,
-    IsRational,
-    IsString,
-    IsFloat,
-    IsNonVar,
-    IsVar,
+    CompareNumber(CompareNumberQT, RegType, RegType),
+    IsAtom(RegType),
+    IsAtomic(RegType),
+    IsCompound(RegType),
+    IsInteger(RegType),
+    IsRational(RegType),
+    IsString(RegType),
+    IsFloat(RegType),
+    IsNonVar(RegType),
+    IsVar(RegType),
 }
 
 impl InlinedClauseType {
     pub fn name(&self) -> &'static str {
         match self {
-            &InlinedClauseType::CompareNumber(qt) => qt.name(),
-            &InlinedClauseType::IsAtom => "atom",
-            &InlinedClauseType::IsAtomic => "atomic",
-            &InlinedClauseType::IsCompound => "compound",
-            &InlinedClauseType::IsInteger  => "integer",
-            &InlinedClauseType::IsRational => "rational",
-            &InlinedClauseType::IsString => "string",
-            &InlinedClauseType::IsFloat  => "float",
-            &InlinedClauseType::IsNonVar => "nonvar",
-            &InlinedClauseType::IsVar => "var"
+            &InlinedClauseType::CompareNumber(qt, ..) => qt.name(),
+            &InlinedClauseType::IsAtom(..) => "atom",
+            &InlinedClauseType::IsAtomic(..) => "atomic",
+            &InlinedClauseType::IsCompound(..) => "compound",
+            &InlinedClauseType::IsInteger (..) => "integer",
+            &InlinedClauseType::IsRational(..) => "rational",
+            &InlinedClauseType::IsString(..) => "string",
+            &InlinedClauseType::IsFloat (..) => "float",
+            &InlinedClauseType::IsNonVar(..) => "nonvar",
+            &InlinedClauseType::IsVar(..) => "var"
         }
     }
 
+    pub fn arity(&self) -> usize {
+        match self {
+            &InlinedClauseType::CompareNumber(..) => 2,
+            &InlinedClauseType::IsAtom(..) => 1,
+            &InlinedClauseType::IsAtomic(..) => 1,
+            &InlinedClauseType::IsCompound(..) => 1,
+            &InlinedClauseType::IsInteger (..) => 1,
+            &InlinedClauseType::IsRational(..) => 1,
+            &InlinedClauseType::IsString(..) => 1,
+            &InlinedClauseType::IsFloat (..) => 1, 
+            &InlinedClauseType::IsNonVar(..) => 1,
+            &InlinedClauseType::IsVar(..) => 1
+        }
+    }
+    
     pub fn from(name: &str, arity: usize) -> Option<Self> {
+        let r1 = temp_v!(1);
+        let r2 = temp_v!(2);
+        
         match (name, arity) {
-            (">", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThan)),
-            ("<", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThan)),
-            (">=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThanOrEqual)),
-            ("=<", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual)),
-            ("=\\=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::NotEqual)),
-            ("=:=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::Equal)),
-            ("atom", 1) => Some(InlinedClauseType::IsAtom),
-            ("atomic", 1) => Some(InlinedClauseType::IsAtomic),
-            ("compound", 1) => Some(InlinedClauseType::IsCompound),
-            ("integer", 1) => Some(InlinedClauseType::IsInteger),
-            ("rational", 1) => Some(InlinedClauseType::IsRational),
-            ("string", 1) => Some(InlinedClauseType::IsString),
-            ("float", 1) => Some(InlinedClauseType::IsFloat),
-            ("nonvar", 1) => Some(InlinedClauseType::IsNonVar),
-            ("var", 1) => Some(InlinedClauseType::IsVar),
+            (">", 2) =>
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThan, r1, r2)),
+            ("<", 2) =>
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThan, r1, r2)),
+            (">=", 2) =>
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThanOrEqual,r1, r2)),
+            ("=<", 2) =>
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual, r1, r2)),
+            ("=\\=", 2) =>
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::NotEqual, r1, r2)),
+            ("=:=", 2) =>
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::Equal, r1, r2)),
+            ("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)),
             _ => None
         }
     }
 }
 
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, PartialEq)]
 pub enum CompareNumberQT {
     GreaterThan,
     LessThan,
@@ -636,7 +660,7 @@ impl CompareNumberQT {
     }
 }
 
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, PartialEq)]
 pub enum CompareTermQT {
     LessThan,
     LessThanOrEqual,
@@ -685,18 +709,28 @@ pub struct Rule {
     pub clauses: Vec<QueryTerm>
 }
 
-#[derive(Clone)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum SystemClauseType {
     SkipMaxList
 }
 
 impl SystemClauseType {
+    pub fn arity(&self) -> usize {
+        match self {
+            &SystemClauseType::SkipMaxList => 4
+        }
+    }
+    
+    pub fn fixity(&self) -> Option<Fixity> {
+        None
+    }
+    
     pub fn name(&self) -> ClauseName {
         match self {
             &SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
         }
     }
-    
+
     pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
         match (name, arity) {
             ("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList),
@@ -705,13 +739,9 @@ impl SystemClauseType {
     }
 }
 
-#[derive(Clone)]
-pub enum ClauseType {
-    AcyclicTerm,
-    Arg,
-    CallN,
-    CallWithInferenceLimit,
-    Catch,
+#[derive(Copy, Clone, PartialEq)]
+pub enum BuiltInClauseType {
+    AcyclicTerm,    
     Compare,
     CompareTerm(CompareTermQT),
     CyclicTerm,
@@ -720,16 +750,20 @@ pub enum ClauseType {
     Eq,
     Functor,
     Ground,
-    Inlined(InlinedClauseType),
     Is,
     KeySort,
     NotEq,
-    Op(ClauseName, Fixity, CodeIndex),
-    Named(ClauseName, CodeIndex),
-    SetupCallCleanup,
     Sort,
-    System(SystemClauseType),
-    Throw,
+    System(SystemClauseType)
+}
+
+#[derive(Clone)]
+pub enum ClauseType {    
+    BuiltIn(BuiltInClauseType),
+    CallN,
+    Inlined(InlinedClauseType),    
+    Op(ClauseName, Fixity, CodeIndex),
+    Named(ClauseName, CodeIndex)
 }
 
 #[derive(Clone)]
@@ -797,12 +831,84 @@ impl ClauseName {
     }
 }
 
+impl BuiltInClauseType {
+    fn fixity(&self) -> Option<Fixity> {
+        match self {
+            &BuiltInClauseType::Compare | &BuiltInClauseType::CompareTerm(_)
+          | &BuiltInClauseType::NotEq   | &BuiltInClauseType::Is | &BuiltInClauseType::Eq
+                => Some(Fixity::In),
+            _ => None
+        }
+    }
+
+    pub fn name(&self) -> ClauseName {
+        match self {
+            &BuiltInClauseType::AcyclicTerm => clause_name!("acyclic_term"),            
+            &BuiltInClauseType::Compare => clause_name!("compare"),
+            &BuiltInClauseType::CompareTerm(qt) => clause_name!(qt.name()),
+            &BuiltInClauseType::CyclicTerm => clause_name!("cyclic_term"),
+            &BuiltInClauseType::Display => clause_name!("display"),
+            &BuiltInClauseType::DuplicateTerm => clause_name!("duplicate_term"),
+            &BuiltInClauseType::Eq => clause_name!("=="),
+            &BuiltInClauseType::Functor => clause_name!("functor"),
+            &BuiltInClauseType::Ground  => clause_name!("ground"),
+            &BuiltInClauseType::Is => clause_name!("is"),
+            &BuiltInClauseType::KeySort => clause_name!("keysort"),
+            &BuiltInClauseType::NotEq => clause_name!("\\=="),            
+            &BuiltInClauseType::Sort => clause_name!("sort"),
+            &BuiltInClauseType::System(system) => system.name()
+        }
+    }    
+
+    pub fn arity(&self) -> usize {
+        match self {
+            &BuiltInClauseType::AcyclicTerm => 1,        
+            &BuiltInClauseType::Compare => 2,
+            &BuiltInClauseType::CompareTerm(_) => 2,
+            &BuiltInClauseType::CyclicTerm => 1,
+            &BuiltInClauseType::Display => 1,
+            &BuiltInClauseType::DuplicateTerm => 2,
+            &BuiltInClauseType::Eq => 2,
+            &BuiltInClauseType::Functor => 3,
+            &BuiltInClauseType::Ground  => 1,
+            &BuiltInClauseType::Is => 2,
+            &BuiltInClauseType::KeySort => 2,
+            &BuiltInClauseType::NotEq => 2,
+            &BuiltInClauseType::Sort => 2,
+            &BuiltInClauseType::System(system) => system.arity()                
+        }
+    }
+    
+    pub fn from(name: &str, arity: usize) -> Option<Self> {
+        match (name, arity) {
+            ("acyclic_term", 1) => Some(BuiltInClauseType::AcyclicTerm),
+            ("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)),
+            ("display", 1) => Some(BuiltInClauseType::Display),
+            ("duplicate_term", 2) => Some(BuiltInClauseType::DuplicateTerm),
+            ("==", 2) => Some(BuiltInClauseType::Eq),
+            ("functor", 3) => Some(BuiltInClauseType::Functor),
+            ("ground", 1) => Some(BuiltInClauseType::Ground),
+            ("is", 2) => Some(BuiltInClauseType::Is),
+            ("keysort", 2) => Some(BuiltInClauseType::KeySort),
+            ("\\==", 2) => Some(BuiltInClauseType::NotEq),
+            ("sort", 2) => Some(BuiltInClauseType::Sort),
+            _ => SystemClauseType::from(name, arity).map(BuiltInClauseType::System)
+        }
+    }
+}
+
 impl ClauseType {
     pub fn fixity(&self) -> Option<Fixity> {
         match self {
-            &ClauseType::Compare | &ClauseType::CompareTerm(_)
-          | &ClauseType::Inlined(InlinedClauseType::CompareNumber(_))
-          | &ClauseType::NotEq | &ClauseType::Is | &ClauseType::Eq => Some(Fixity::In),
+            &ClauseType::BuiltIn(ref built_in) => built_in.fixity(),
+            &ClauseType::Inlined(InlinedClauseType::CompareNumber(..)) => Some(Fixity::In),
             &ClauseType::Op(_, fixity, _) => Some(fixity),
             _ => None
         }
@@ -810,68 +916,30 @@ impl ClauseType {
 
     pub fn name(&self) -> ClauseName {
         match self {
-            &ClauseType::AcyclicTerm => clause_name!("acyclic_term"),
-            &ClauseType::Arg => clause_name!("arg"),
-            &ClauseType::CallN => clause_name!("call"),
-            &ClauseType::CallWithInferenceLimit => clause_name!("call_with_inference_limit"),
-            &ClauseType::Catch => clause_name!("catch"),
-            &ClauseType::Compare => clause_name!("compare"),
-            &ClauseType::CompareTerm(qt) => clause_name!(qt.name()),
-            &ClauseType::CyclicTerm => clause_name!("cyclic_term"),
-            &ClauseType::Display => clause_name!("display"),
-            &ClauseType::DuplicateTerm => clause_name!("duplicate_term"),
-            &ClauseType::Eq => clause_name!("=="),
-            &ClauseType::Functor => clause_name!("functor"),
-            &ClauseType::Ground  => clause_name!("ground"),
+            &ClauseType::CallN => clause_name!("call"),            
+            &ClauseType::BuiltIn(built_in) => built_in.name(),
             &ClauseType::Inlined(inlined) => clause_name!(inlined.name()),
-            &ClauseType::Is => clause_name!("is"),
-            &ClauseType::KeySort => clause_name!("keysort"),
-            &ClauseType::NotEq => clause_name!("\\=="),
             &ClauseType::Op(ref name, ..) => name.clone(),
             &ClauseType::Named(ref name, ..) => name.clone(),
-            &ClauseType::SetupCallCleanup => clause_name!("setup_call_cleanup"),
-            &ClauseType::System(ref system) => system.name(),
-            &ClauseType::Sort => clause_name!("sort"),
-            &ClauseType::Throw => clause_name!("throw")
         }
     }
 
     pub fn from(name: ClauseName, arity: usize, fixity: Option<Fixity>) -> Self {
-        if let Some(inlined_ct) = InlinedClauseType::from(name.as_str(), arity) {
-            return ClauseType::Inlined(inlined_ct);
-        }
-        
-        match (name.as_str(), arity) {
-            ("acyclic_term", 1) => ClauseType::AcyclicTerm,
-            ("arg", 3)   => ClauseType::Arg,
-            ("call", _)  => ClauseType::CallN,
-            ("call_with_inference_limit", 3) => ClauseType::CallWithInferenceLimit,
-            ("catch", 3) => ClauseType::Catch,
-            ("compare", 3) => ClauseType::Compare,
-            ("cyclic_term", 1) => ClauseType::CyclicTerm,
-            ("@>", 2) => ClauseType::CompareTerm(CompareTermQT::GreaterThan),
-            ("@<", 2) => ClauseType::CompareTerm(CompareTermQT::LessThan),
-            ("@>=", 2) => ClauseType::CompareTerm(CompareTermQT::GreaterThanOrEqual),
-            ("@<=", 2) => ClauseType::CompareTerm(CompareTermQT::LessThanOrEqual),
-            ("\\=@=", 2) => ClauseType::CompareTerm(CompareTermQT::NotEqual),
-            ("=@=", 2) => ClauseType::CompareTerm(CompareTermQT::Equal),
-            ("display", 1) => ClauseType::Display,
-            ("duplicate_term", 2) => ClauseType::DuplicateTerm,
-            ("==", 2) => ClauseType::Eq,
-            ("functor", 3) => ClauseType::Functor,
-            ("ground", 1) => ClauseType::Ground,
-            ("is", 2) => ClauseType::Is,
-            ("keysort", 2) => ClauseType::KeySort,
-            ("\\==", 2) => ClauseType::NotEq,
-            ("setup_call_cleanup", 3) => ClauseType::SetupCallCleanup,            
-            ("sort", 2) => ClauseType::Sort,
-            ("throw", 1) => ClauseType::Throw,
-            _ => if let Some(fixity) = fixity {
-                ClauseType::Op(name, fixity, CodeIndex::default())
-            } else {
-                ClauseType::Named(name, CodeIndex::default())
-            }
-        }
+        InlinedClauseType::from(name.as_str(), arity)
+            .map(ClauseType::Inlined)
+            .unwrap_or_else(|| {
+                BuiltInClauseType::from(name.as_str(), arity)
+                    .map(ClauseType::BuiltIn)
+                    .unwrap_or_else(|| {
+                        if let Some(fixity) = fixity {
+                            ClauseType::Op(name, fixity, CodeIndex::default())
+                        } else if name.as_str() == "call" {
+                            ClauseType::CallN
+                        } else {
+                            ClauseType::Named(name, CodeIndex::default())
+                        }
+                    })
+            })            
     }
 }
 
@@ -902,18 +970,21 @@ impl<'a> TermRef<'a> {
     }
 }
 
+#[derive(Clone)]
 pub enum ChoiceInstruction {
     RetryMeElse(usize),
     TrustMe,
     TryMeElse(usize)
 }
 
+#[derive(Clone)]
 pub enum CutInstruction {
     Cut(RegType),
     GetLevel(RegType),
     NeckCut
 }
 
+#[derive(Clone)]
 pub enum IndexedChoiceInstruction {
     Retry(usize),
     Trust(usize),
@@ -1219,6 +1290,7 @@ impl ArithmeticTerm {
     }
 }
 
+#[derive(Clone)]
 pub enum ArithmeticInstruction {
     Add(ArithmeticTerm, ArithmeticTerm, usize),
     Sub(ArithmeticTerm, ArithmeticTerm, usize),
@@ -1237,8 +1309,8 @@ pub enum ArithmeticInstruction {
     Neg(ArithmeticTerm, usize)
 }
 
+#[derive(Clone)]
 pub enum BuiltInInstruction {
-    CallInlined(InlinedClauseType, Vec<RegType>),
     CleanUpBlock,
     CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm),
     DefaultRetryMeElse(usize),
@@ -1254,13 +1326,12 @@ pub enum BuiltInInstruction {
     InstallCleaner,
     InstallInferenceCounter(RegType, RegType, RegType),
     InstallNewBlock,
-    InternalCallN,
     RemoveCallPolicyCheck,
     RemoveInferenceCounter(RegType, RegType),
     ResetBlock,
     RestoreCutPolicy,
     SetBall,
-    SetCutPoint(RegType),    
+    SetCutPoint(RegType),
     Succeed,
     Unify,
     UnwindStack
@@ -1292,6 +1363,7 @@ impl ControlInstruction {
     }
 }
 
+#[derive(Clone)]
 pub enum IndexingInstruction {
     SwitchOnTerm(usize, usize, usize, usize),
     SwitchOnConstant(usize, HashMap<Constant, usize>),
@@ -1304,6 +1376,7 @@ impl From<IndexingInstruction> for Line {
     }
 }
 
+#[derive(Clone)]
 pub enum FactInstruction {
     GetConstant(Level, Constant, RegType),
     GetList(Level, RegType),
@@ -1317,6 +1390,7 @@ pub enum FactInstruction {
     UnifyVoid(usize)
 }
 
+#[derive(Clone)]
 pub enum QueryInstruction {
     GetVariable(RegType, usize),
     PutConstant(Level, Constant, RegType),
@@ -1336,6 +1410,7 @@ pub type CompiledFact = Vec<FactInstruction>;
 
 pub type CompiledQuery = Vec<QueryInstruction>;
 
+#[derive(Clone)]
 pub enum Line {
     Arithmetic(ArithmeticInstruction),
     BuiltIn(BuiltInInstruction),
@@ -1474,27 +1549,60 @@ impl From<(usize, ClauseName)> for CodeIndex {
 
 #[derive(Clone, PartialEq)]
 pub enum CodePtr {
+    BuiltInClause(BuiltInClauseType, LocalCodePtr), // local is the successor call.
+    CallN(usize, LocalCodePtr), // the arity of the call, successor call.
+    Local(LocalCodePtr)
+}
+
+impl CodePtr {
+    pub fn local(&self) -> LocalCodePtr {
+        match self {
+            &CodePtr::BuiltInClause(_, ref local)
+          | &CodePtr::CallN(_, ref local)
+          | &CodePtr::Local(ref local) => local.clone()
+        }
+    }
+}
+
+#[derive(Clone, PartialEq)]
+pub enum LocalCodePtr {
     DirEntry(usize, ClauseName), // offset, resident module name.
     TopLevel(usize, usize) // chunk_num, offset.
 }
 
-impl CodePtr {
+impl LocalCodePtr {
     pub fn module_name(&self) -> ClauseName {
         match self {
-            &CodePtr::DirEntry(_, ref name) => name.clone(),
+            &LocalCodePtr::DirEntry(_, ref name) => name.clone(),
             _ => ClauseName::BuiltIn("user")
         }
     }
+
+    pub fn assign_if_local(&mut self, cp: CodePtr) {
+        match cp {
+            CodePtr::Local(local) => *self = local,            
+            _ => {}
+        }
+    }
 }
 
 impl PartialOrd<CodePtr> for CodePtr {
     fn partial_cmp(&self, other: &CodePtr) -> Option<Ordering> {
         match (self, other) {
-            (&CodePtr::DirEntry(p1, _), &CodePtr::DirEntry(p2, _)) =>
+            (&CodePtr::Local(ref l1), &CodePtr::Local(ref l2)) => l1.partial_cmp(l2),            
+            _ => Some(Ordering::Greater)
+        }
+    }
+}
+
+impl PartialOrd<LocalCodePtr> for LocalCodePtr {
+    fn partial_cmp(&self, other: &LocalCodePtr) -> Option<Ordering> {
+        match (self, other) {
+            (&LocalCodePtr::DirEntry(p1, _), &LocalCodePtr::DirEntry(p2, _)) =>
                 p1.partial_cmp(&p2),
-            (&CodePtr::DirEntry(..), &CodePtr::TopLevel(_, _)) =>
+            (&LocalCodePtr::DirEntry(..), &LocalCodePtr::TopLevel(_, _)) =>
                 Some(Ordering::Less),
-            (&CodePtr::TopLevel(_, p1), &CodePtr::TopLevel(_, ref p2)) =>
+            (&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) =>
                 p1.partial_cmp(p2),
             _ => Some(Ordering::Greater)
         }
@@ -1503,7 +1611,33 @@ impl PartialOrd<CodePtr> for CodePtr {
 
 impl Default for CodePtr {
     fn default() -> Self {
-        CodePtr::TopLevel(0, 0)
+        CodePtr::Local(LocalCodePtr::default())
+    }
+}
+
+impl Default for LocalCodePtr {
+    fn default() -> Self {
+        LocalCodePtr::TopLevel(0, 0)
+    }
+}
+
+impl Add<usize> for LocalCodePtr {
+    type Output = LocalCodePtr;
+
+    fn add(self, rhs: usize) -> Self::Output {
+        match self {
+            LocalCodePtr::DirEntry(p, name) => LocalCodePtr::DirEntry(p + rhs, name),
+            LocalCodePtr::TopLevel(cn, p) => LocalCodePtr::TopLevel(cn, p + rhs)
+        }
+    }
+}
+
+impl AddAssign<usize> for LocalCodePtr {
+    fn add_assign(&mut self, rhs: usize) {
+        match self {
+            &mut LocalCodePtr::DirEntry(ref mut p, _) |
+            &mut LocalCodePtr::TopLevel(_, ref mut p) => *p += rhs
+        }
     }
 }
 
@@ -1512,8 +1646,9 @@ impl Add<usize> for CodePtr {
 
     fn add(self, rhs: usize) -> Self::Output {
         match self {
-            CodePtr::DirEntry(p, name) => CodePtr::DirEntry(p + rhs, name),
-            CodePtr::TopLevel(cn, p) => CodePtr::TopLevel(cn, p + rhs)
+            CodePtr::Local(local) => CodePtr::Local(local + rhs),
+            CodePtr::BuiltInClause(_, local) => CodePtr::Local(local + rhs),
+            CodePtr::CallN(_, local) => CodePtr::Local(local + rhs),
         }
     }
 }
@@ -1521,8 +1656,8 @@ impl Add<usize> for CodePtr {
 impl AddAssign<usize> for CodePtr {
     fn add_assign(&mut self, rhs: usize) {
         match self {
-            &mut CodePtr::DirEntry(ref mut p, _) |
-            &mut CodePtr::TopLevel(_, ref mut p) => *p += rhs
+            &mut CodePtr::Local(ref mut local) => *local += rhs,
+            _ => *self = CodePtr::Local(self.local() + rhs)
         }
     }
 }
index 0222ecf72a9992e2d6215951a0255668e886749a..ab9d49039aa57678a092b9d54a5cdb03da86aecd 100644 (file)
@@ -1,8 +1,6 @@
 use prolog::ast::*;
-use prolog::num::bigint::{BigInt};
 
 use std::collections::HashMap;
-use std::rc::Rc;
 
 // from 7.12.2 b) of 13211-1:1995
 #[derive(Clone, Copy)]
@@ -92,7 +90,8 @@ impl EvalError {
     }
 }
 
-fn get_builtins() -> Code {
+/*
+fn get_builtins() -> Code {    
     vec![internal_call_n!(), // callN/N, 0.
          is_atomic!(temp_v!(1)), // atomic/1, 1.
          proceed!(),
@@ -737,7 +736,7 @@ fn get_builtins() -> Code {
          acyclic_term_execute!(), // acyclic_term/1, 485.
          cyclic_term_execute!(), // cyclic_term/1, 486.
     ]
-}
+} */
 
 pub fn default_op_dir() -> OpDir
 {
index 521fbf06d25a5f61305d32b6683add856322adac..4e6d9ed35cd4ea916f1a39a4df63e77c0669abea 100644 (file)
@@ -254,18 +254,18 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                        -> Result<(), ParserError>
     {
         match ct {
-            InlinedClauseType::CompareNumber(cmp) => {
+            InlinedClauseType::CompareNumber(cmp, ..) => {
                 let (mut lcode, at_1) = self.call_arith_eval(terms[0].as_ref(), 1)?;
                 let (mut rcode, at_2) = self.call_arith_eval(terms[1].as_ref(), 2)?;
 
                 code.append(&mut lcode);
                 code.append(&mut rcode);
-
+                
                 code.push(compare_number_instr!(cmp,
                                                 at_1.unwrap_or(interm!(1)),
                                                 at_2.unwrap_or(interm!(2))));
             },
-            InlinedClauseType::IsAtom =>
+            InlinedClauseType::IsAtom(..) =>
                 match terms[0].as_ref() {
                     &Term::Constant(_, Constant::Atom(_)) => {
                         code.push(succeed!());
@@ -278,7 +278,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                         code.push(fail!());
                     }
                 },
-            InlinedClauseType::IsAtomic =>
+            InlinedClauseType::IsAtomic(..) =>
                 match terms[0].as_ref() {
                     &Term::AnonVar | &Term::Clause(..) | &Term::Cons(..) => {
                         code.push(fail!());
@@ -291,7 +291,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                         code.push(is_atomic!(r));
                     }
                 },
-            InlinedClauseType::IsCompound =>
+            InlinedClauseType::IsCompound(..) =>
                 match terms[0].as_ref() {
                     &Term::Clause(..) | &Term::Cons(..) => {
                         code.push(succeed!());
@@ -304,7 +304,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                         code.push(fail!());
                     }
                 },
-            InlinedClauseType::IsRational =>
+            InlinedClauseType::IsRational(..) =>
                 match terms[0].as_ref() {
                     &Term::Constant(_, Constant::Number(Number::Rational(_))) => {
                         code.push(succeed!());
@@ -317,7 +317,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                         code.push(fail!());
                     }
                 },
-            InlinedClauseType::IsFloat =>
+            InlinedClauseType::IsFloat(..) =>
                 match terms[0].as_ref() {
                     &Term::Constant(_, Constant::Number(Number::Float(_))) => {
                         code.push(succeed!());
@@ -330,7 +330,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                         code.push(fail!());
                     }
                 },
-            InlinedClauseType::IsString =>
+            InlinedClauseType::IsString(..) =>
                 match terms[0].as_ref() {
                     &Term::Constant(_, Constant::String(_)) => {
                         code.push(succeed!());
@@ -343,7 +343,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                         code.push(fail!());
                     }
                 },
-            InlinedClauseType::IsNonVar =>
+            InlinedClauseType::IsNonVar(..) =>
                 match terms[0].as_ref() {
                     &Term::AnonVar => {
                         code.push(fail!());
@@ -356,7 +356,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                         code.push(succeed!());
                     }
                 },
-            InlinedClauseType::IsInteger =>
+            InlinedClauseType::IsInteger(..) =>
                 match terms[0].as_ref() {
                     &Term::Constant(_, Constant::Number(Number::Integer(_))) => {
                         code.push(succeed!());
@@ -369,7 +369,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                         code.push(fail!());
                     },
                 },
-            InlinedClauseType::IsVar =>
+            InlinedClauseType::IsVar(..) =>
                 match terms[0].as_ref() {
                     &Term::Constant(..) | &Term::Clause(..) | &Term::Cons(..) => {
                         code.push(fail!());
@@ -416,7 +416,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                         } else {
                             Line::Cut(CutInstruction::Cut(perm_v!(1)))
                         }),
-                    &QueryTerm::Clause(_, ClauseType::Is, ref terms) => {
+                    &QueryTerm::Clause(_, ClauseType::BuiltIn(BuiltInClauseType::Is), ref terms) =>
+                    {
                         let (mut acode, at) = self.call_arith_eval(terms[1].as_ref(), 1)?;
                         code.append(&mut acode);
 
index eceacfa18d75b011f30336f469ac6bb34cb3b292..52876615f3b6397a512bc39a1b12fe1b683ed601 100644 (file)
@@ -173,10 +173,6 @@ impl fmt::Display for IndexedChoiceInstruction {
 impl fmt::Display for BuiltInInstruction {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
-            &BuiltInInstruction::CallInlined(InlinedClauseType::CompareNumber(cmp), ref rs) =>
-                write!(f, "number_test {}, {}, {}", cmp, &rs[0], &rs[1]),
-            &BuiltInInstruction::CallInlined(ict, ref rs) =>
-                write!(f, "call_inlined_{}, {}", ict.name(), &rs[0]),
             &BuiltInInstruction::CleanUpBlock =>
                 write!(f, "clean_up_block"),
             &BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) =>
@@ -209,8 +205,6 @@ impl fmt::Display for BuiltInInstruction {
                 write!(f, "install_cleaner"),
             &BuiltInInstruction::InstallNewBlock =>
                 write!(f, "install_new_block"),
-            &BuiltInInstruction::InternalCallN =>
-                write!(f, "internal_call_N"),
             &BuiltInInstruction::RemoveCallPolicyCheck =>
                 write!(f, "remove_call_policy_check"),
             &BuiltInInstruction::RemoveInferenceCounter(r1, r2) =>
index 23c5aad4344a7e2d0496246eb309cb5946b94bc2..5ce7f36e98470da68408cfe73fad3adcc57f9d42 100644 (file)
@@ -341,7 +341,8 @@ impl<'a> ChunkedIterator<'a>
                     result.push(term),
                 ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), _)) =>
                     result.push(term),
-                ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::CallN, ref subterms)) => {
+                ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::CallN, ref subterms)) =>
+                {
                     result.push(term);
                     arity = subterms.len() + 1;
                     break;
diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl
new file mode 100644 (file)
index 0000000..7a46bf8
--- /dev/null
@@ -0,0 +1,29 @@
+:- op(400, yfx, /).
+
+:- module(builtins, [(+)/2, (*)/2, (-)/2, (/)/2, (/\)/2, (\/)/2, (is)/2,
+       (xor)/2, (div)/2, (//)/2, (rdiv)/2, (<<)/2, (>>)/2, (mod)/2,
+       (rem)/2, (>)/2, (<)/2, (=\=)/2, (=:=)/2, (>=)/2, (=<)/2]).
+
+% arithmetic operators.
+:- op(700, xfx, is).
+:- op(500, yfx, +).
+:- op(500, yfx, -).
+:- op(400, yfx, *).
+:- op(500, yfx, /\).
+:- op(500, yfx, \/).
+:- op(500, yfx, xor).
+:- op(400, yfx, div).
+:- op(400, yfx, //).
+:- op(400, yfx, rdiv).
+:- op(400, yfx, <<).
+:- op(400, yfx, >>).
+:- op(400, yfx, mod).
+:- op(400, yfx, rem).
+
+% arithmetic comparison operators.
+:- op(700, xfx, >).
+:- op(700, xfx, <).
+:- op(700, xfx, =\=).
+:- op(700, xfx, =:=).
+:- op(700, xfx, >=).
+:- op(700, xfx, =<).
index f9dad13e7109306edd8ca0c4ec97783fa7e8a290..7913137abff62a0c0a410e91b0a52d223cfaca8e 100644 (file)
@@ -209,7 +209,7 @@ pub struct MachineState {
     pub(super) b0: usize,
     pub(super) e: usize,
     pub(super) num_of_args: usize,
-    pub(super) cp: CodePtr,
+    pub(super) cp: LocalCodePtr,
     pub(super) fail: bool,
     pub(crate) heap: Heap,
     pub(super) mode: MachineMode,
@@ -248,10 +248,10 @@ pub(crate) trait CallPolicy: Any {
             IndexPtr::Index(compiled_tl_index) => {
                 let module_name = idx.0.borrow().1.clone();
 
-                machine_st.cp = machine_st.p.clone() + 1;
+                machine_st.cp.assign_if_local(machine_st.p.clone() + 1);
                 machine_st.num_of_args = arity;
                 machine_st.b0 = machine_st.b;
-                machine_st.p  = CodePtr::DirEntry(compiled_tl_index, module_name);
+                machine_st.p  = dir_entry!(compiled_tl_index, module_name);
             }
         }
 
@@ -270,7 +270,7 @@ pub(crate) trait CallPolicy: Any {
 
                 machine_st.num_of_args = arity;
                 machine_st.b0 = machine_st.b;
-                machine_st.p  = CodePtr::DirEntry(compiled_tl_index, module_name);
+                machine_st.p  = dir_entry!(compiled_tl_index, module_name);
             }
         }
 
@@ -400,55 +400,66 @@ pub(crate) trait CallPolicy: Any {
         Ok(())
     }
 
-    fn try_call_clause<'a>(&mut self, machine_st: &mut MachineState, code_dirs: CodeDirs<'a>,
-                           ct: &ClauseType, arity: usize, lco: bool)
-                           -> CallResult
+    fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize,
+                  code_dirs: CodeDirs<'a>, lco: bool)
+                  -> CallResult
     {
-        match ct {
-            &ClauseType::AcyclicTerm => {
-                let addr = machine_st[temp_v!(1)].clone();
-                machine_st.fail = machine_st.is_cyclic_term(addr);
-                return_from_clause!(lco, machine_st)
-            },
-            &ClauseType::Arg => {
-                if !lco {
-                    machine_st.cp = machine_st.p.clone() + 1;
+        loop {
+            if let Some((name, mut arity)) = machine_st.setup_call_n(arity) {
+                let user = clause_name!("user");
+
+                if machine_st.fail {
+                    return Ok(());
                 }
+                
+                match ClauseType::from(name.clone(), arity, None) {
+                    ClauseType::CallN => {                        
+                        machine_st.num_of_args = arity;
+                        machine_st.handle_internal_call_n();
+                                                
+                        continue;
+                    },
+                    ClauseType::BuiltIn(built_in) =>
+                        machine_st.setup_built_in_call(built_in, lco),
+                    ClauseType::Inlined(inlined) =>
+                        machine_st.execute_inlined(&inlined),
+                    ClauseType::Op(..) | ClauseType::Named(..) =>
+                        if let Some(idx) = code_dirs.get(name.clone(), arity, user) {
+                            self.context_call(machine_st, name, arity, idx, lco)?;
+                        } else {
+                            return Err(machine_st.existence_error(name, arity));
+                        }
+                };
+            }
 
-                machine_st.num_of_args = 3;
-                machine_st.b0 = machine_st.b;
-                machine_st.p  = CodePtr::DirEntry(166, clause_name!("builtin"));
+            break;
+        }
 
-                Ok(())
-            },
-            &ClauseType::Catch => {
-                if !lco {
-                    machine_st.cp = machine_st.p.clone() + 1;
-                }
+        Ok(())
+    }
 
-                machine_st.num_of_args = 3;
-                machine_st.b0 = machine_st.b;
-                machine_st.p  = CodePtr::DirEntry(5, clause_name!("builtin"));
+    fn system_call(&mut self, machine_st: &mut MachineState, ct: &SystemClauseType) -> CallResult
+    {
+        match ct {
+            &SystemClauseType::SkipMaxList => {
+                machine_st.skip_max_list()?;
+                machine_st.p += 1;
 
                 Ok(())
+            }
+        }
+    }
+
+    fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType, lco: bool)
+                        -> CallResult
+    {
+        match ct {
+            &BuiltInClauseType::AcyclicTerm => {
+                let addr = machine_st[temp_v!(1)].clone();
+                machine_st.fail = machine_st.is_cyclic_term(addr);
+                return_from_clause!(lco, machine_st)
             },
-            &ClauseType::CallN =>
-                if let Some((name, arity)) = machine_st.setup_call_n(arity) {
-                    let user = clause_name!("user");
-                    
-                    match ClauseType::from(name.clone(), arity, None) {
-                        ClauseType::Op(..) | ClauseType::Named(..) =>
-                            if let Some(idx) = code_dirs.get(name.clone(), arity, user) {
-                                self.context_call(machine_st, name, arity, idx, lco)
-                            } else {
-                                Err(machine_st.existence_error(name, arity))
-                            },
-                        ct => self.try_call_clause(machine_st, code_dirs, &ct, arity, lco),
-                    }
-                } else {
-                    Ok(())
-                },
-            &ClauseType::Compare => {
+            &BuiltInClauseType::Compare => {
                 let a1 = machine_st[temp_v!(1)].clone();
                 let a2 = machine_st[temp_v!(2)].clone();
                 let a3 = machine_st[temp_v!(3)].clone();
@@ -462,7 +473,7 @@ pub(crate) trait CallPolicy: Any {
                 machine_st.unify(a1, c);
                 return_from_clause!(lco, machine_st)
             },
-            &ClauseType::CompareTerm(qt) => {
+            &BuiltInClauseType::CompareTerm(qt) => {
                 match qt {
                     CompareTermQT::Equal =>
                         machine_st.fail = machine_st.structural_eq_test(),
@@ -473,12 +484,12 @@ pub(crate) trait CallPolicy: Any {
 
                 return_from_clause!(lco, machine_st)
             },
-            &ClauseType::CyclicTerm => {
+            &BuiltInClauseType::CyclicTerm => {
                 let addr = machine_st[temp_v!(1)].clone();
                 machine_st.fail = !machine_st.is_cyclic_term(addr);
                 return_from_clause!(lco, machine_st)
             },
-            &ClauseType::Display => {
+            &BuiltInClauseType::Display => {
                 let output = machine_st.print_term(machine_st[temp_v!(1)].clone(),
                                                    DisplayFormatter {},
                                                    PrinterOutputter::new());
@@ -486,27 +497,27 @@ pub(crate) trait CallPolicy: Any {
                 println!("{}", output.result());
                 return_from_clause!(lco, machine_st)
             },
-            &ClauseType::DuplicateTerm => {
+            &BuiltInClauseType::DuplicateTerm => {
                 machine_st.duplicate_term();
                 return_from_clause!(lco, machine_st)
             },
-            &ClauseType::Eq => {
+            &BuiltInClauseType::Eq => {
                 machine_st.fail = machine_st.eq_test();
                 return_from_clause!(lco, machine_st)
             },
-            &ClauseType::Ground => {
+            &BuiltInClauseType::Ground => {
                 machine_st.fail = machine_st.ground_test();
                 return_from_clause!(lco, machine_st)
             },
-            &ClauseType::Functor => {
+            &BuiltInClauseType::Functor => {
                 machine_st.try_functor()?;
                 return_from_clause!(lco, machine_st)
             },
-            &ClauseType::NotEq => {
+            &BuiltInClauseType::NotEq => {
                 machine_st.fail = !machine_st.eq_test();
                 return_from_clause!(lco, machine_st)
             },
-            &ClauseType::Sort => {
+            &BuiltInClauseType::Sort => {
                 machine_st.check_sort_errors()?;
 
                 let stub = machine_st.functor_stub(clause_name!("sort"), 2);
@@ -522,7 +533,7 @@ pub(crate) trait CallPolicy: Any {
 
                 return_from_clause!(lco, machine_st)
             },
-            &ClauseType::KeySort => {
+            &BuiltInClauseType::KeySort => {
                 machine_st.check_keysort_errors()?;
 
                 let stub = machine_st.functor_stub(clause_name!("keysort"), 2);
@@ -544,25 +555,7 @@ pub(crate) trait CallPolicy: Any {
 
                 return_from_clause!(lco, machine_st)
             },
-            &ClauseType::Throw => {
-                if !lco {
-                    machine_st.cp = machine_st.p.clone() + 1;
-                }
-
-                machine_st.goto_throw();
-                Ok(())
-            },
-            &ClauseType::Named(ref name, ref idx) | &ClauseType::Op(ref name, _, ref idx) =>
-                self.context_call(machine_st, name.clone(), arity, idx.clone(), lco),
-            &ClauseType::CallWithInferenceLimit => {
-                machine_st.goto_ptr(CodePtr::DirEntry(409, clause_name!("builtin")), 3, lco);
-                Ok(())
-            },
-            &ClauseType::SetupCallCleanup => {
-                machine_st.goto_ptr(CodePtr::DirEntry(310, clause_name!("builtin")), 3, lco);
-                Ok(())
-            },
-            &ClauseType::Is => {
+            &BuiltInClauseType::Is => {
                 let a = machine_st[temp_v!(1)].clone();
                 let result = machine_st.arith_eval_by_metacall(temp_v!(2))?;
 
@@ -571,14 +564,8 @@ pub(crate) trait CallPolicy: Any {
 
                 Ok(())
             },
-            &ClauseType::Inlined(ref inlined) => {
-                machine_st.execute_inlined(inlined, &vec![temp_v!(1), temp_v!(2)]);
-                Ok(())
-            },
-            &ClauseType::System(ref system) => {
-                machine_st.execute_system(system)?;
-                return_from_clause!(lco, machine_st)
-            }
+            &BuiltInClauseType::System(ref ct) =>
+                self.system_call(machine_st, ct),
         }
     }
 }
@@ -680,11 +667,10 @@ impl CallPolicy for CallWithInferenceLimitCallPolicy {
         self.increment()
     }
 
-    fn try_call_clause<'a>(&mut self, machine_st: &mut MachineState, code_dirs: CodeDirs<'a>,
-                           ct: &ClauseType, arity: usize, lco: bool)
-                           -> CallResult
+    fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType, lco: bool)
+                        -> CallResult
     {
-        self.prev_policy.try_call_clause(machine_st, code_dirs, ct, arity, lco)?;
+        self.prev_policy.call_builtin(machine_st, ct, lco)?;
         self.increment()
     }
 }
@@ -757,11 +743,11 @@ impl CutPolicy for SetupCallCleanupCutPolicy {
         machine_st.p += 1;
 
         if !self.out_of_cont_pts() {
-            machine_st.cp = machine_st.p.clone();
+            machine_st.cp.assign_if_local(machine_st.p.clone());
             machine_st.num_of_args = 0;
             machine_st.b0 = machine_st.b;
             // goto_call run_cleaners_without_handling/0, 370.
-            machine_st.p = CodePtr::DirEntry(370, clause_name!("builtin"));
+            machine_st.p = dir_entry!(370, clause_name!("builtin"));
         }
     }
 }
index 5665eea29b0332f04c7d4f18fbcccf44d26f9cce..bc12c399b30f1e66ae8109a6e6d3edaabfa944d2 100644 (file)
@@ -38,7 +38,7 @@ impl MachineState {
             b0: 0,
             e: 0,
             num_of_args: 0,
-            cp: CodePtr::default(),
+            cp: LocalCodePtr::default(),
             fail: false,
             heap: Heap::with_capacity(256),
             mode: MachineMode::Write,
@@ -670,7 +670,7 @@ impl MachineState {
             &ArithmeticInstruction::Xor(ref a1, ref a2, t) => {
                 let n1 = try_or_fail!(self, self.get_number(a1));
                 let n2 = try_or_fail!(self, self.get_number(a2));
-
+                
                 self.interms[t - 1] = Number::Integer(try_or_fail!(self, self.xor(n1, n2)));
                 self.p += 1;
             },
@@ -1011,8 +1011,7 @@ impl MachineState {
         }
     }
 
-    fn handle_internal_call_n<'a>(&mut self, call_policy: &mut Box<CallPolicy>,
-                                  code_dirs: CodeDirs<'a>)
+    pub(super) fn handle_internal_call_n(&mut self)
     {
         let arity = self.num_of_args + 1;
         let pred  = self.registers[1].clone();
@@ -1023,32 +1022,20 @@ impl MachineState {
 
         if arity > 1 {
             self.registers[arity - 1] = pred;
-
-            if let Some((name, arity)) = self.setup_call_n(arity - 1) {
-                if let Some(idx) = code_dirs.get(name.clone(), arity, self.p.module_name()) {
-                    try_or_fail!(self, call_policy.try_execute(self, name, arity, idx));
-                    return;
-                }
-            }
+            return;
         }
 
         self.fail = true;
     }
 
-    pub(super) fn goto_throw(&mut self) {
-        self.num_of_args = 1;
-        self.b0 = self.b;
-        self.p  = CodePtr::DirEntry(59, clause_name!("builtin"));
-    }
-
     pub(super) fn set_ball(&mut self) {
         let addr = self[temp_v!(1)].clone();
         self.ball.boundary = self.heap.h;
-             
+
         let mut duplicator = DuplicateBallTerm::new(self);
-        duplicator.duplicate_term(addr);        
+        duplicator.duplicate_term(addr);
     }
-    
+
     pub(super) fn unwind_stack(&mut self) {
         self.b = self.block;
         self.or_stack.truncate(self.b);
@@ -1071,7 +1058,6 @@ impl MachineState {
                             self.error_form(self.representation_error(RepFlag::MaxArity), stub);
 
                         self.throw_exception(representation_error);
-
                         return None;
                     }
 
@@ -1334,20 +1320,15 @@ impl MachineState {
         };
     }
 
-    pub(super) fn execute_inlined(&mut self, inlined: &InlinedClauseType, rs: &Vec<RegType>)
-    {
-        let r1 = rs[0].clone();
-
+    pub(super) fn execute_inlined(&mut self, inlined: &InlinedClauseType) {
         match inlined {
-            &InlinedClauseType::CompareNumber(cmp) => {
-                let r2 = rs[1].clone();
-
+            &InlinedClauseType::CompareNumber(cmp, r1, r2) => {
                 let n1 = try_or_fail!(self, self.arith_eval_by_metacall(r1));
                 let n2 = try_or_fail!(self, self.arith_eval_by_metacall(r2));
 
                 self.compare_numbers(cmp, n1, n2);
             },
-            &InlinedClauseType::IsAtom => {
+            &InlinedClauseType::IsAtom(r1) => {
                 let d = self.store(self.deref(self[r1].clone()));
 
                 match d {
@@ -1355,7 +1336,7 @@ impl MachineState {
                     _ => self.fail = true
                 };
             },
-            &InlinedClauseType::IsAtomic => {
+            &InlinedClauseType::IsAtomic(r1) => {
                 let d = self.store(self.deref(self[r1].clone()));
 
                 match d {
@@ -1363,7 +1344,7 @@ impl MachineState {
                     _ => self.fail = true
                 };
             },
-            &InlinedClauseType::IsInteger => {
+            &InlinedClauseType::IsInteger(r1) => {
                 let d = self.store(self.deref(self[r1].clone()));
 
                 match d {
@@ -1371,7 +1352,7 @@ impl MachineState {
                     _ => self.fail = true
                 };
             },
-            &InlinedClauseType::IsCompound => {
+            &InlinedClauseType::IsCompound(r1) => {
                 let d = self.store(self.deref(self[r1].clone()));
 
                 match d {
@@ -1379,7 +1360,7 @@ impl MachineState {
                     _ => self.fail = true
                 };
             },
-            &InlinedClauseType::IsFloat => {
+            &InlinedClauseType::IsFloat(r1) => {
                 let d = self.store(self.deref(self[r1].clone()));
 
                 match d {
@@ -1387,7 +1368,7 @@ impl MachineState {
                     _ => self.fail = true
                 };
             },
-            &InlinedClauseType::IsRational => {
+            &InlinedClauseType::IsRational(r1) => {
                 let d = self.store(self.deref(self[r1].clone()));
 
                 match d {
@@ -1395,7 +1376,7 @@ impl MachineState {
                     _ => self.fail = true
                 };
             },
-            &InlinedClauseType::IsString => {
+            &InlinedClauseType::IsString(r1) => {
                 let d = self.store(self.deref(self[r1].clone()));
 
                 match d {
@@ -1403,7 +1384,7 @@ impl MachineState {
                     _ => self.fail = true
                 };
             },
-            &InlinedClauseType::IsNonVar => {
+            &InlinedClauseType::IsNonVar(r1) => {
                 let d = self.store(self.deref(self[r1].clone()));
 
                 match d {
@@ -1411,7 +1392,7 @@ impl MachineState {
                     _ => self.p += 1
                 };
             },
-            &InlinedClauseType::IsVar => {
+            &InlinedClauseType::IsVar(r1) => {
                 let d = self.store(self.deref(self[r1].clone()));
 
                 match d {
@@ -1428,8 +1409,6 @@ impl MachineState {
                                              instr: &BuiltInInstruction)
     {
         match instr {
-            &BuiltInInstruction::CallInlined(ref inlined, ref rs) =>
-                self.execute_inlined(inlined, rs),
             &BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) => {
                 let n1 = try_or_fail!(self, self.get_number(at_1));
                 let n2 = try_or_fail!(self, self.get_number(at_2));
@@ -1457,7 +1436,7 @@ impl MachineState {
                     let val = self.try_get_arg();
 
                     if lco {
-                        self.p = self.cp.clone();
+                        self.p = CodePtr::Local(self.cp.clone());
                     } else {
                         self.p += 1;
                     }
@@ -1658,8 +1637,6 @@ impl MachineState {
             },
             &BuiltInInstruction::UnwindStack =>
                 self.unwind_stack(),
-            &BuiltInInstruction::InternalCallN =>
-                self.handle_internal_call_n(call_policy, code_dirs),
             &BuiltInInstruction::Fail => {
                 self.fail = true;
                 self.p += 1;
@@ -1946,66 +1923,86 @@ impl MachineState {
         false
     }
 
-    pub(super) fn execute_ctrl_instr<'a>(&mut self, code_dirs: CodeDirs<'a>,
-                                         call_policy: &mut Box<CallPolicy>,
-                                         cut_policy:  &mut Box<CutPolicy>,
-                                         instr: &ControlInstruction)
-    {
-        match instr {
-            &ControlInstruction::Allocate(num_cells) => {
-                let gi = self.next_global_index();
+    pub(super) fn setup_built_in_call(&mut self, ct: BuiltInClauseType, lco: bool)
+    {        
+        self.num_of_args = ct.arity();
+        self.b0 = self.b;
 
-                self.p += 1;
+        self.p = CodePtr::BuiltInClause(ct, self.p.local());
+    }
 
-                if self.e + 1 < self.and_stack.len() {
-                    let and_gi = self.and_stack[self.e].global_index;
-                    let or_gi = self.or_stack.top()
-                        .map(|or_fr| or_fr.global_index)
-                        .unwrap_or(0);
+    pub(super) fn allocate(&mut self, num_cells: usize) {
+        let gi = self.next_global_index();
 
-                    if and_gi > or_gi {
-                        let index = self.e + 1;
+        self.p += 1;
 
-                        self.and_stack[index].e  = self.e;
-                        self.and_stack[index].cp = self.cp.clone();
-                        self.and_stack[index].global_index = gi;
+        if self.e + 1 < self.and_stack.len() {
+            let and_gi = self.and_stack[self.e].global_index;
+            let or_gi = self.or_stack.top()
+                .map(|or_fr| or_fr.global_index)
+                .unwrap_or(0);
 
-                        self.and_stack.resize(index, num_cells);
+            if and_gi > or_gi {
+                let index = self.e + 1;
 
-                        self.e = index;
+                self.and_stack[index].e  = self.e;
+                self.and_stack[index].cp = self.cp.clone();
+                self.and_stack[index].global_index = gi;
 
-                        return;
-                    }
-                }
+                self.and_stack.resize(index, num_cells);
+                self.e = index;
 
-                self.and_stack.push(gi, self.e, self.cp.clone(), num_cells);
-                self.e = self.and_stack.len() - 1;
-            },
-            &ControlInstruction::CallClause(ref ct, arity, _, lco) =>
-                try_or_fail!(self, call_policy.try_call_clause(self, code_dirs, ct, arity, lco)),
+                return;
+            }
+        }
+
+        self.and_stack.push(gi, self.e, self.cp.clone(), num_cells);
+        self.e = self.and_stack.len() - 1;
+    }
+
+    fn deallocate(&mut self) {
+        let e = self.e;
+
+        self.cp = self.and_stack[e].cp.clone();
+        self.e  = self.and_stack[e].e;
+
+        self.p += 1;
+    }
+
+    pub(super) fn execute_ctrl_instr<'a>(&mut self, code_dirs: CodeDirs<'a>,
+                                         call_policy: &mut Box<CallPolicy>,
+                                         cut_policy:  &mut Box<CutPolicy>,
+                                         instr: &ControlInstruction)
+    {
+        match instr {
+            &ControlInstruction::Allocate(num_cells) =>
+                self.allocate(num_cells),
+            &ControlInstruction::CallClause(ClauseType::CallN, arity, _, lco) =>
+                try_or_fail!(self, call_policy.call_n(self, arity, code_dirs, lco)),
+            &ControlInstruction::CallClause(ClauseType::BuiltIn(ref ct), _, _, lco) =>
+                try_or_fail!(self, call_policy.call_builtin(self, ct, lco)),
+            &ControlInstruction::CallClause(ClauseType::Inlined(ref ct), _, _, lco) =>
+                self.execute_inlined(ct),
+            &ControlInstruction::CallClause(ClauseType::Named(ref name, ref idx), arity, _, lco)
+          | &ControlInstruction::CallClause(ClauseType::Op(ref name, _, ref idx), arity, _, lco) =>
+                try_or_fail!(self, call_policy.context_call(self, name.clone(), arity, idx.clone(),
+                                                            lco)),
             &ControlInstruction::CheckCpExecute => {
                 let a = self.store(self.deref(self[temp_v!(2)].clone()));
 
                 match a {
                     Addr::Con(Constant::Usize(old_b)) if self.b > old_b + 1 => {
-                        self.p = self.cp.clone();
+                        self.p = CodePtr::Local(self.cp.clone());
                     },
                     _ => {
                         self.num_of_args = 2;
                         self.b0 = self.b;
                         // goto sgc_on_success/2, 382.
-                        self.p = CodePtr::DirEntry(382, clause_name!("builtin"));
+                        self.p = dir_entry!(382, clause_name!("builtin"));
                     }
                 };
             },
-            &ControlInstruction::Deallocate => {
-                let e = self.e;
-
-                self.cp = self.and_stack[e].cp.clone();
-                self.e  = self.and_stack[e].e;
-
-                self.p += 1;
-            },
+            &ControlInstruction::Deallocate => self.deallocate(),
             &ControlInstruction::GetCleanerCall => {
                 let dest = self[temp_v!(1)].clone();
 
@@ -2032,7 +2029,7 @@ impl MachineState {
                 self.fail = true;
             },
             &ControlInstruction::Goto(p, arity, lco) =>
-                self.goto_ptr(CodePtr::DirEntry(p, clause_name!("builtin")), arity, lco),
+                self.goto_ptr(dir_entry!(p, clause_name!("builtin")), arity, lco),
             &ControlInstruction::IsClause(lco, r, ref at) => {
                 let a1 = self[r].clone();
                 let a2 = try_or_fail!(self, self.get_number(at));
@@ -2042,7 +2039,7 @@ impl MachineState {
             },
             &ControlInstruction::JmpBy(arity, offset, _, lco) => {
                 if !lco {
-                    self.cp = self.p.clone() + 1;
+                    self.cp.assign_if_local(self.p.clone() + 1);
                 }
 
                 self.num_of_args = arity;
@@ -2050,13 +2047,13 @@ impl MachineState {
                 self.p += offset;
             },
             &ControlInstruction::Proceed =>
-                self.p = self.cp.clone(),
+                self.p = CodePtr::Local(self.cp.clone())
         };
     }
 
     pub(super) fn goto_ptr(&mut self, p: CodePtr, arity: usize, lco:bool) {
         if !lco {
-            self.cp = self.p.clone() + 1;
+            self.cp.assign_if_local(self.p.clone() + 1);
         }
 
         self.num_of_args = arity;
@@ -2169,7 +2166,7 @@ impl MachineState {
         self.s = 0;
         self.tr = 0;
         self.p = CodePtr::default();
-        self.cp = CodePtr::default();
+        self.cp = LocalCodePtr::default();
         self.num_of_args = 0;
 
         self.fail = false;
index 5377949e57d9bd05eb7031365bb55bafad8b130c..163c0b16e43283f52242716a29a7f329e031e687 100644 (file)
@@ -34,18 +34,18 @@ pub struct Machine {
     cached_query: Option<Code>
 }
 
-impl Index<CodePtr> for Machine {
+impl Index<LocalCodePtr> for Machine {
     type Output = Line;
 
-    fn index(&self, ptr: CodePtr) -> &Self::Output {
+    fn index(&self, ptr: LocalCodePtr) -> &Self::Output {
         match ptr {
-            CodePtr::TopLevel(_, p) => {
+            LocalCodePtr::TopLevel(_, p) => {
                 match &self.cached_query {
                     &Some(ref cq) => &cq[p],
                     &None => panic!("Out-of-bounds top level index.")
                 }
             },
-            CodePtr::DirEntry(p, _) => &self.code[p]
+            LocalCodePtr::DirEntry(p, _) => &self.code[p]
         }
     }
 }
@@ -223,36 +223,47 @@ impl Machine {
         }
     }
 
+    fn lookup_instr(&self, p: CodePtr) -> Option<Line> {
+        match p {
+            CodePtr::Local(LocalCodePtr::TopLevel(_, p)) =>
+                match &self.cached_query {
+                    &Some(ref cq) => Some(cq[p].clone()),
+                    &None => None
+                },
+            CodePtr::Local(LocalCodePtr::DirEntry(p, _)) =>
+                Some(self.code[p].clone()),
+            CodePtr::BuiltInClause(built_in, _) =>
+                Some(call_clause!(ClauseType::BuiltIn(built_in), built_in.arity(), 0)),
+            CodePtr::CallN(arity, _) =>
+                Some(call_clause!(ClauseType::CallN, arity, 0))
+        }
+    }
+
     fn execute_instr(&mut self)
     {
-        let instr = match self.ms.p {
-            CodePtr::TopLevel(_, p) => {
-                match &self.cached_query {
-                    &Some(ref cq) => &cq[p],
-                    &None => return
-                }
-            },
-            CodePtr::DirEntry(p, _) => &self.code[p]
+        let instr = match self.lookup_instr(self.ms.p.clone()) {
+            Some(instr) => instr,
+            None => return
         };
 
         match instr {
-            &Line::Arithmetic(ref arith_instr) =>
+            Line::Arithmetic(ref arith_instr) =>
                 self.ms.execute_arith_instr(arith_instr),
-            &Line::BuiltIn(ref built_in_instr) => {
+            Line::BuiltIn(ref built_in_instr) => {
                 let code_dirs = CodeDirs::new(&self.code_dir, &self.modules);
                 self.ms.execute_built_in_instr(code_dirs, &mut self.call_policy,
                                                &mut self.cut_policy, built_in_instr);
             },
-            &Line::Choice(ref choice_instr) =>
+            Line::Choice(ref choice_instr) =>
                 self.ms.execute_choice_instr(choice_instr, &mut self.call_policy),
-            &Line::Cut(ref cut_instr) =>
+            Line::Cut(ref cut_instr) =>
                 self.ms.execute_cut_instr(cut_instr, &mut self.cut_policy),
-            &Line::Control(ref control_instr) => {
+            Line::Control(ref control_instr) => {
                 let code_dirs = CodeDirs::new(&self.code_dir, &self.modules);
                 self.ms.execute_ctrl_instr(code_dirs, &mut self.call_policy,
                                            &mut self.cut_policy, control_instr)
             },
-            &Line::Fact(ref fact) => {
+            Line::Fact(ref fact) => {
                 for fact_instr in fact {
                     if self.failed() {
                         break;
@@ -263,11 +274,11 @@ impl Machine {
 
                 self.ms.p += 1;
             },
-            &Line::Indexing(ref indexing_instr) =>
+            Line::Indexing(ref indexing_instr) =>
                 self.ms.execute_indexing_instr(&indexing_instr),
-            &Line::IndexedChoice(ref choice_instr) =>
+            Line::IndexedChoice(ref choice_instr) =>
                 self.ms.execute_indexed_choice_instr(choice_instr, &mut self.call_policy),
-            &Line::Query(ref query) => {
+            Line::Query(ref query) => {
                 for query_instr in query {
                     if self.failed() {
                         break;
@@ -289,13 +300,13 @@ impl Machine {
             self.ms.b0 = self.ms.or_stack[b].b0;
             self.ms.p  = self.ms.or_stack[b].bp.clone();
 
-            if let CodePtr::TopLevel(_, p) = self.ms.p {
+            if let CodePtr::Local(LocalCodePtr::TopLevel(_, p)) = self.ms.p {
                 self.ms.fail = p == 0;
             } else {
                 self.ms.fail = false;
             }
         } else {
-            self.ms.p = CodePtr::TopLevel(0, 0);
+            self.ms.p = CodePtr::Local(LocalCodePtr::TopLevel(0, 0));
         }
     }
 
@@ -309,8 +320,9 @@ impl Machine {
             }
 
             match self.ms.p {
-                CodePtr::DirEntry(p, _) if p < self.code.len() => {},
-                _ => break
+                CodePtr::Local(LocalCodePtr::DirEntry(p, _)) if p < self.code.len() => {},
+                CodePtr::Local(_) => break,
+                _ => {}
             };
         }
     }
@@ -342,11 +354,11 @@ impl Machine {
 
     fn run_query(&mut self, alloc_locs: &AllocVarDict, heap_locs: &mut HeapVarDict)
     {
-        let end_ptr = CodePtr::TopLevel(0, self.cached_query_size());
+        let end_ptr = top_level_code_ptr!(0, self.cached_query_size());
 
         while self.ms.p < end_ptr {
-            if let CodePtr::TopLevel(mut cn, p) = self.ms.p {
-                match &self[CodePtr::TopLevel(cn, p)] {
+            if let CodePtr::Local(LocalCodePtr::TopLevel(mut cn, p)) = self.ms.p {
+                match &self[LocalCodePtr::TopLevel(cn, p)] {
                     &Line::Control(ref ctrl_instr) if ctrl_instr.is_jump_instr() => {
                         self.record_var_places(cn, alloc_locs, heap_locs);
                         cn += 1;
@@ -354,13 +366,13 @@ impl Machine {
                     _ => {}
                 }
 
-                self.ms.p = CodePtr::TopLevel(cn, p);
+                self.ms.p = top_level_code_ptr!(cn, p);
             }
 
             self.query_stepper();
 
             match self.ms.p {
-                CodePtr::TopLevel(_, p) if p > 0 => {},
+                CodePtr::Local(LocalCodePtr::TopLevel(_, p)) if p > 0 => {},
                 _ => {
                     if heap_locs.is_empty() {
                         self.record_var_places(0, alloc_locs, heap_locs);
@@ -377,7 +389,7 @@ impl Machine {
         if self.ms.ball.stub.len() > 0 {
             let h = self.ms.heap.h;
             self.ms.copy_and_align_ball_to_heap();
-            
+
             let error_str = self.ms.print_exception(Addr::HeapCell(h),
                                                     &heap_locs,
                                                     TermFormatter {},
@@ -410,7 +422,7 @@ impl Machine {
             let b = self.ms.b - 1;
             self.ms.p = self.ms.or_stack[b].bp.clone();
 
-            if let CodePtr::TopLevel(_, 0) = self.ms.p {
+            if let CodePtr::Local(LocalCodePtr::TopLevel(_, 0)) = self.ms.p {
                 return EvalSession::from(SessionError::QueryFailure);
             }
 
index 140791f9f24168298697643bae576965c612adc1..a665add265dfcb4447d2b37976f62bcb3770e8fc 100644 (file)
@@ -19,24 +19,6 @@ macro_rules! atom {
     )
 }
 
-macro_rules! internal_call_n {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::InternalCallN)
-    )
-}
-
-macro_rules! allocate {
-    ($cells:expr) => (
-        Line::Control(ControlInstruction::Allocate($cells))
-    )
-}
-
-macro_rules! deallocate {
-    () => (
-        Line::Control(ControlInstruction::Deallocate)
-    )
-}
-
 macro_rules! compare_number_instr {
     ($cmp: expr, $at_1: expr, $at_2: expr) => (
         Line::BuiltIn(BuiltInInstruction::CompareNumber($cmp, $at_1, $at_2))
@@ -88,12 +70,6 @@ macro_rules! functor {
     )
 }
 
-macro_rules! fact {
-    [$($x:expr),+] => (
-        Line::Fact(vec![$($x),+])
-    )
-}
-
 macro_rules! temp_v {
     ($x:expr) => (
         RegType::Temp($x)
@@ -106,150 +82,58 @@ macro_rules! perm_v {
     )
 }
 
-macro_rules! get_var_in_query {
-    ($r:expr, $arg:expr) => (
-        QueryInstruction::GetVariable($r, $arg)
-    )
-}
-
-
-macro_rules! get_value {
-    ($r:expr, $arg:expr) => (
-        FactInstruction::GetValue($r, $arg)
-    )
-}
-
-macro_rules! set_void {
-    ($n:expr) => (
-        QueryInstruction::SetVoid($n)
-    )
-}
-
-macro_rules! set_value {
-    ($r:expr) => (
-        QueryInstruction::SetValue($r)
-    )
-}
-
-macro_rules! get_var_in_fact {
-    ($r:expr, $arg:expr) => (
-        FactInstruction::GetVariable($r, $arg)
-    )
-}
-
-macro_rules! put_var {
-    ($r:expr, $arg:expr) => (
-        QueryInstruction::PutVariable($r, $arg)
-    )
-}
-
-macro_rules! put_structure {
-    ($atom:expr, $arity:expr, $r:expr, Some($fix:expr)) => (
-        QueryInstruction::PutStructure(ClauseType::Op(clause_name!($atom), $fix, CodeIndex::default()),
-                                       $arity,
-                                       $r)
-    );
-    ($atom:expr, $arity:expr, $r:expr, None) => (
-        QueryInstruction::PutStructure(ClauseType::Named(clause_name!($atom), CodeIndex::default()),
-                                       $arity,
-                                       $r)
-    )
-}
-
-macro_rules! put_constant {
-    ($lvl:expr, $cons:expr, $r:expr) => (
-        QueryInstruction::PutConstant($lvl, $cons, $r)
-    )
-}
-
-macro_rules! set_constant {
-    ($cons:expr) => (
-        QueryInstruction::SetConstant($cons)
-    )
-}
-
-macro_rules! put_value {
-    ($r:expr, $arg:expr) => (
-        QueryInstruction::PutValue($r, $arg)
-    )
-}
-
-macro_rules! put_unsafe_value {
-    ($r:expr, $arg:expr) => (
-        QueryInstruction::PutUnsafeValue($r, $arg)
-    )
-}
-
-macro_rules! try_me_else {
-    ($o:expr) => (
-        Line::Choice(ChoiceInstruction::TryMeElse($o))
-    )
-}
-
-macro_rules! retry_me_else {
-    ($o:expr) => (
-        Line::Choice(ChoiceInstruction::RetryMeElse($o))
-    )
-}
-
 macro_rules! is_atom {
     ($r:expr) => (
-        Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsAtom, vec![$r]))
+        call_clause!(ClauseType::Inlined(InlinedClauseType::IsAtom($r)), 1, 0)
     )
 }
 
 macro_rules! is_atomic {
     ($r:expr) => (
-        Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsAtomic, vec![$r]))
+        call_clause!(ClauseType::Inlined(InlinedClauseType::IsAtomic($r)), 1, 0)
     )
 }
 
 macro_rules! is_integer {
     ($r:expr) => (
-        Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsInteger, vec![$r]))
+        call_clause!(ClauseType::Inlined(InlinedClauseType::IsInteger($r)), 1, 0)
     )
 }
 
 macro_rules! is_compound {
     ($r:expr) => (
-        Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsCompound, vec![$r]))
+        call_clause!(ClauseType::Inlined(InlinedClauseType::IsCompound($r)), 1, 0)
     )
 }
 
 macro_rules! is_float {
     ($r:expr) => (
-        Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsFloat, vec![$r]))
+        call_clause!(ClauseType::Inlined(InlinedClauseType::IsFloat($r)), 1, 0)
     )
 }
 
 macro_rules! is_rational {
     ($r:expr) => (
-        Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsRational, vec![$r]))
+        call_clause!(ClauseType::Inlined(InlinedClauseType::IsRational($r)), 1, 0)
     )
 }
 
 
 macro_rules! is_nonvar {
     ($r:expr) => (
-        Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsNonVar, vec![$r]))
+        call_clause!(ClauseType::Inlined(InlinedClauseType::IsNonVar($r)), 1, 0)
     )
 }
 
 macro_rules! is_string {
     ($r:expr) => (
-        Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsString, vec![$r]))
+        call_clause!(ClauseType::Inlined(InlinedClauseType::IsString($r)), 1, 0)
     )
 }
 
 macro_rules! is_var {
     ($r:expr) => (
-        Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::IsVar, vec![$r]))
-    )
-}
-
-macro_rules! trust_me {
-    () => (
-        Line::Choice(ChoiceInstruction::TrustMe)
+        call_clause!(ClauseType::Inlined(InlinedClauseType::IsVar($r)), 1, 0)
     )
 }
 
@@ -259,84 +143,12 @@ macro_rules! call_clause {
     )
 }
 
-macro_rules! call_n {
-    ($arity:expr) => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::CallN, $arity, 0, false))
-    )
-}
-
-macro_rules! execute_n {
-    ($arity:expr) => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::CallN, $arity, 0, true))
-    )
-}
-
 macro_rules! proceed {
     () => (
         Line::Control(ControlInstruction::Proceed)
     )
 }
 
-macro_rules! cut {
-    ($r:expr) => (
-        Line::Cut(CutInstruction::Cut($r))
-    )
-}
-
-macro_rules! neck_cut {
-    () => (
-        Line::Cut(CutInstruction::NeckCut)
-    )
-}
-
-macro_rules! get_current_block {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::GetCurrentBlock)
-    )
-}
-
-macro_rules! install_new_block {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::InstallNewBlock)
-    )
-}
-
-macro_rules! goto_call {
-    ($line:expr, $arity:expr) => (
-        Line::Control(ControlInstruction::Goto($line, $arity, false))
-    )
-}
-
-macro_rules! goto_execute {
-    ($line:expr, $arity:expr) => (
-        Line::Control(ControlInstruction::Goto($line, $arity, true))
-    )
-}
-
-macro_rules! reset_block {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::ResetBlock)
-    )
-}
-
-macro_rules! get_ball {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::GetBall)
-    )
-}
-
-macro_rules! erase_ball {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::EraseBall)
-    )
-}
-
-macro_rules! unify {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::Unify)
-    )
-}
-
 macro_rules! is_call {
     ($r:expr, $at:expr) => (
         Line::Control(ControlInstruction::IsClause(false, $r, $at))
@@ -344,24 +156,6 @@ macro_rules! is_call {
     )
 }
 
-macro_rules! unwind_stack {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::UnwindStack)
-    )
-}
-
-macro_rules! clean_up_block {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::CleanUpBlock)
-    )
-}
-
-macro_rules! set_ball {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::SetBall)
-    )
-}
-
 macro_rules! fail {
     () => (
         Line::BuiltIn(BuiltInInstruction::Fail)
@@ -374,133 +168,18 @@ macro_rules! succeed {
     )
 }
 
-macro_rules! duplicate_term {
-    () => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::DuplicateTerm, 2, 0, false))
-    )
-}
-
-macro_rules! get_level {
-    ($r:expr) => (
-        Line::Cut(CutInstruction::GetLevel($r))
-    )
-}
-
-macro_rules! switch_on_term {
-    ($v:expr, $c:expr, $l:expr, $s:expr) => (
-        Line::Indexing(IndexingInstruction::SwitchOnTerm($v, $c, $l, $s))
-    )
-}
-
-macro_rules! indexed_try {
-    ($i:expr) => (
-        Line::IndexedChoice(IndexedChoiceInstruction::Try($i))
-    )
-}
-
-macro_rules! retry {
-    ($i:expr) => (
-        Line::IndexedChoice(IndexedChoiceInstruction::Retry($i))
-    )
-}
-
-macro_rules! trust {
-    ($i:expr) => (
-        Line::IndexedChoice(IndexedChoiceInstruction::Trust($i))
-    )
-}
-
-macro_rules! get_constant {
-    ($c:expr, $r:expr) => (
-        FactInstruction::GetConstant(Level::Shallow, $c, $r)
-    )
-}
-
-macro_rules! get_structure {
-    ($atom:expr, $arity:expr, $r:expr, Some($fix:expr)) => (
-        FactInstruction::GetStructure(ClauseType::Op(clause_name!($atom), $fix, CodeIndex::default()),
-                                      $arity,
-                                      $r)
-    );
-    ($atom:expr, $arity:expr, $r:expr, None) => (
-        FactInstruction::GetStructure(ClauseType::Named(clause_name!($atom), CodeIndex::default()),
-                                      $arity,
-                                      $r)
-    )
-}
-
-macro_rules! functor_call {
-    () => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::Functor, 3, 0, false))
-    )
-}
-
-macro_rules! functor_execute {
-    () => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::Functor, 3, 0, true))
-    )
-}
-
-macro_rules! unify_value {
-    ($r:expr) => (
-        FactInstruction::UnifyValue($r)
-    )
-}
-
-macro_rules! unify_variable {
-    ($r:expr) => (
-        FactInstruction::UnifyVariable($r)
-    )
-}
-
-macro_rules! unify_void {
-    ($n:expr) => (
-        FactInstruction::UnifyVoid($n)
-    )
-}
-
 macro_rules! set_cp {
     ($r:expr) => (
         Line::BuiltIn(BuiltInInstruction::SetCutPoint($r))
     )
 }
 
-macro_rules! get_cp {
-    ($r:expr) => (
-        Line::BuiltIn(BuiltInInstruction::GetCutPoint($r))
-    )
-}
-
 macro_rules! integer {
     ($i:expr) => (
         Constant::Number(Number::Integer(Rc::new(BigInt::from($i))))
     )
 }
 
-macro_rules! add {
-    ($at_1:expr, $at_2:expr, $o:expr) => (
-        Line::Arithmetic(ArithmeticInstruction::Add($at_1, $at_2, $o))
-    )
-}
-
-macro_rules! sub {
-    ($at_1:expr, $at_2:expr, $o:expr) => (
-        Line::Arithmetic(ArithmeticInstruction::Sub($at_1, $at_2, $o))
-    )
-}
-
-macro_rules! get_arg_call {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::GetArg(false))
-    )
-}
-
-macro_rules! get_arg_execute {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::GetArg(true))
-    )
-}
-
 macro_rules! rc_integer {
     ($e:expr) => (
         Number::Integer(Rc::new(BigInt::from($e)))
@@ -513,229 +192,12 @@ macro_rules! rc_atom {
     )
 }
 
-macro_rules! infix {
-    () => (
-        Fixity::In
-    )
-}
-
-macro_rules! display {
-    () => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::Display, 1, 0, false))
-    )
-}
-
-macro_rules! dynamic_is {
-    () => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::Is, 2, 0, false))
-    )
-}
-
-macro_rules! dynamic_num_test {
-    ($cmp:expr) => (
-        Line::BuiltIn(BuiltInInstruction::CallInlined(InlinedClauseType::CompareNumber($cmp),
-                                                      vec![temp_v!(1), temp_v!(2)]))
-    )
-}
-
-macro_rules! cmp_gt {
-    () => (
-        CompareNumberQT::GreaterThan
-    )
-}
-
-macro_rules! cmp_lt {
-    () => (
-        CompareNumberQT::LessThan
-    )
-}
-
-macro_rules! cmp_gte {
-    () => (
-        CompareNumberQT::GreaterThanOrEqual
-    )
-}
-
-macro_rules! cmp_lte {
-    () => (
-        CompareNumberQT::LessThanOrEqual
-    )
-}
-
-macro_rules! cmp_ne {
-    () => (
-        CompareNumberQT::NotEqual
-    )
-}
-
-macro_rules! cmp_eq {
-    () => (
-        CompareNumberQT::Equal
-    )
-}
-
 macro_rules! jmp_call {
     ($arity:expr, $offset:expr, $pvs:expr) => (
         Line::Control(ControlInstruction::JmpBy($arity, $offset, $pvs, false))
     )
 }
 
-macro_rules! jmp_execute {
-    ($arity:expr, $offset:expr, $pvs:expr) => (
-        Line::Control(ControlInstruction::JmpBy($arity, $offset, $pvs, true))
-    )
-}
-
-macro_rules! get_list {
-    ($lvl:expr, $r:expr) => (
-        FactInstruction::GetList($lvl, $r)
-    )
-}
-
-macro_rules! unify_constant {
-    ($c:expr) => (
-        FactInstruction::UnifyConstant($c)
-    )
-}
-
-macro_rules! install_cleaner {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::InstallCleaner)
-    )
-}
-
-macro_rules! check_cp_execute {
-    () => (
-        Line::Control(ControlInstruction::CheckCpExecute)
-    )
-}
-
-macro_rules! get_cleaner_call {
-    () => (
-        Line::Control(ControlInstruction::GetCleanerCall)
-    )
-}
-
-macro_rules! restore_cut_policy {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::RestoreCutPolicy)
-    )
-}
-
-macro_rules! ground_execute {
-    () => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::Ground, 1, 0, true))
-    )
-}
-
-macro_rules! eq_execute {
-    () => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::Eq, 2, 0, true))
-    )
-}
-
-macro_rules! not_eq_execute {
-    () => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::NotEq, 2, 0, true))
-    )
-}
-
-macro_rules! compare_term_execute {
-    ($qt:expr) => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::CompareTerm($qt), 2, 0, true))
-    )
-}
-
-macro_rules! term_cmp_gt {
-    () => (
-        CompareTermQT::GreaterThan
-    )
-}
-
-macro_rules! term_cmp_lt {
-    () => (
-        CompareTermQT::LessThan
-    )
-}
-
-macro_rules! term_cmp_gte {
-    () => (
-        CompareTermQT::GreaterThanOrEqual
-    )
-}
-
-macro_rules! term_cmp_lte {
-    () => (
-        CompareTermQT::LessThanOrEqual
-    )
-}
-
-macro_rules! term_cmp_ne {
-    () => (
-        CompareTermQT::NotEqual
-    )
-}
-
-macro_rules! term_cmp_eq {
-    () => (
-        CompareTermQT::Equal
-    )
-}
-
-macro_rules! install_inference_counter {
-    ($r1:expr, $r2:expr, $r3:expr) => (
-        Line::BuiltIn(BuiltInInstruction::InstallInferenceCounter($r1, $r2, $r3))
-    )
-}
-
-macro_rules! remove_inference_counter {
-    ($r1:expr, $r2:expr) => (
-        Line::BuiltIn(BuiltInInstruction::RemoveInferenceCounter($r1, $r2))
-    )
-}
-
-macro_rules! inference_level {
-    ($r1:expr, $r2:expr) => (
-        Line::BuiltIn(BuiltInInstruction::InferenceLevel($r1, $r2))
-    )
-}
-
-macro_rules! default_set_cp {
-    ($r:expr) => (
-        Line::BuiltIn(BuiltInInstruction::DefaultSetCutPoint($r))
-    )
-}
-
-macro_rules! default_retry_me_else {
-    ($o:expr) => (
-        Line::BuiltIn(BuiltInInstruction::DefaultRetryMeElse($o))
-    )
-}
-
-macro_rules! default_trust_me {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::DefaultTrustMe)
-    )
-}
-
-macro_rules! remove_call_policy_check {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::RemoveCallPolicyCheck)
-    )
-}
-
-macro_rules! compare_execute {
-    () => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::Compare, 2, 0, true))
-    )
-}
-
-macro_rules! module_decl {
-    ($name:expr, $decls:expr) => (
-        ModuleDecl { name: $name, exports: $decls }
-    )
-}
-
 macro_rules! try_eval_session {
     ($e:expr) => (
         match $e {
@@ -744,35 +206,10 @@ macro_rules! try_eval_session {
         }
     )
 }
-
-macro_rules! sort_execute {
-    () => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::Sort, 2, 0, true))
-    )
-}
-
-macro_rules! keysort_execute {
-    () => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::KeySort, 2, 0, true))
-    )
-}
-
-macro_rules! acyclic_term_execute {
-    () => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::AcyclicTerm, 1, 0, true))
-    )
-}
-
-macro_rules! cyclic_term_execute {
-    () => (
-        Line::Control(ControlInstruction::CallClause(ClauseType::CyclicTerm, 1, 0, true))
-    )
-}
-
 macro_rules! return_from_clause {
     ($lco:expr, $machine_st:expr) => {{
         if $lco {
-            $machine_st.p = $machine_st.cp.clone();
+            $machine_st.p = CodePtr::Local($machine_st.cp.clone());
         } else {
             $machine_st.p += 1;
         }
@@ -781,6 +218,12 @@ macro_rules! return_from_clause {
     }}
 }
 
+macro_rules! dir_entry {
+    ($idx:expr, $module_name:expr) => (
+        CodePtr::Local(LocalCodePtr::DirEntry($idx, $module_name))
+    )
+}
+
 macro_rules! set_code_index {
     ($idx:expr, $ip:expr, $mod_name:expr) => {{
         let mut idx = $idx.0.borrow_mut();
@@ -795,3 +238,15 @@ macro_rules! machine_code_index {
         MachineCodeIndex { code_dir: $code_dir, op_dir: $op_dir }
     )
 }
+
+macro_rules! put_constant {
+    ($lvl:expr, $cons:expr, $r:expr) => (
+        QueryInstruction::PutConstant($lvl, $cons, $r)
+    )
+}
+
+macro_rules! top_level_code_ptr {
+    ($p:expr, $q_sz:expr) => (
+        CodePtr::Local(LocalCodePtr::TopLevel($p, $q_sz))
+    )
+}
index 07041ed350d7d382b973ef95867fd45103fb2d20..d32c490f51d75049ef93270225eaf7a016afd45d 100644 (file)
@@ -6,7 +6,7 @@ use std::vec::Vec;
 pub struct Frame {
     pub global_index: usize,
     pub e: usize,
-    pub cp: CodePtr,
+    pub cp: LocalCodePtr,
     pub b: usize,    
     pub bp: CodePtr,
     pub tr: usize,
@@ -18,7 +18,7 @@ pub struct Frame {
 impl Frame {
     fn new(global_index: usize,
            e: usize,
-           cp: CodePtr,
+           cp: LocalCodePtr,
            b: usize,
            bp: CodePtr,
            tr: usize,
@@ -55,7 +55,7 @@ impl OrStack {
     pub fn push(&mut self,
                 global_index: usize,
                 e: usize,
-                cp: CodePtr,
+                cp: LocalCodePtr,
                 b: usize,
                 bp: CodePtr,
                 tr: usize,
index 3c122dfc744dea77358c71131f11cdd4f99d0bac..addb26e92b38ce4948f4342891b66a2388cfc60b 100644 (file)
@@ -233,7 +233,7 @@ fn unfold_by_str(mut term: Term, s: &str) -> Vec<Term>
         terms.push(fst);
         term = snd;
     }
-
+    
     terms.push(term);
     terms
 }
@@ -397,10 +397,8 @@ impl RelationWorker {
                 },
             Term::Var(_, ref v) if v.as_str() == "!" =>
                 Ok(QueryTerm::UnblockedCut(Cell::default())),
-            Term::Clause(r, name, mut terms, fixity) =>
-                if let Some(system_ct) = SystemClauseType::from(name.as_str(), terms.len()) {
-                    Ok(QueryTerm::Clause(r, ClauseType::System(system_ct), terms))
-                } else if name.as_str() == ";" {
+            Term::Clause(r, name, mut terms, fixity) =>                
+                if name.as_str() == ";" {
                     if terms.len() == 2 {
                         let term = Term::Clause(r, name.clone(), terms, fixity);
                         let (stub, clauses) = self.fabricate_disjunct(term);