]> Repositorios git - scryer-prolog.git/commitdiff
refactor ControlInstruction
authorMark Thom <[email protected]>
Sat, 17 Mar 2018 07:26:50 +0000 (01:26 -0600)
committerMark Thom <[email protected]>
Sat, 17 Mar 2018 07:26:50 +0000 (01:26 -0600)
src/prolog/ast.rs
src/prolog/builtins.rs
src/prolog/codegen.rs
src/prolog/debray_allocator.rs
src/prolog/io.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/macros.rs
src/tests.rs

index e090828ef3898c5eef33baf8f2d2de880562a344..80456e2bd86366bbfb097a8e547e0f4fb8e25632 100644 (file)
@@ -165,7 +165,7 @@ impl SubModuleUser for Module {
 
     fn code_dir(&mut self) -> &mut CodeDir {
         &mut self.code_dir
-    }    
+    }
 }
 
 pub trait SubModuleUser {
@@ -175,7 +175,7 @@ pub trait SubModuleUser {
     // returns true on successful import.
     fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool {
         let name = name.defrock_brackets();
-            
+
         if arity == 1 {
             if let Some(op_data) = submodule.op_dir.get(&(name.clone(), Fixity::Pre)) {
                 self.op_dir().insert((name.clone(), Fixity::Pre), op_data.clone());
@@ -201,14 +201,14 @@ pub trait SubModuleUser {
             false
         }
     }
-    
+
     fn use_qualified_module(&mut self, submodule: &Module, exports: Vec<PredicateKey>) -> EvalSession
     {
         for (name, arity) in exports {
             if !submodule.module_decl.exports.contains(&(name.clone(), arity)) {
                 continue;
             }
-            
+
             if !self.import_decl(name, arity, submodule) {
                 return EvalSession::from(EvalError::ModuleDoesNotContainExport);
             }
@@ -216,14 +216,14 @@ pub trait SubModuleUser {
 
         EvalSession::EntrySuccess
     }
-    
+
     fn use_module(&mut self, submodule: &Module) -> EvalSession {
         for (name, arity) in submodule.module_decl.exports.iter().cloned() {
             if !self.import_decl(name, arity, submodule) {
                 return EvalSession::from(EvalError::ModuleDoesNotContainExport);
             }
         }
-        
+
         EvalSession::EntrySuccess
     }
 }
@@ -695,18 +695,6 @@ pub enum ClauseType {
     Throw,
 }
 
-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::Op(_, fixity) => Some(fixity),
-            _ => None
-        }
-    }
-}
-
 #[derive(Clone)]
 pub enum ClauseName {
     BuiltIn(&'static str),
@@ -761,7 +749,7 @@ impl ClauseName {
                 s
             }
         }
-        
+
         match self {
             ClauseName::BuiltIn(s) =>
                 ClauseName::BuiltIn(defrock_brackets(s)),
@@ -773,6 +761,16 @@ impl ClauseName {
 }
 
 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::Op(_, fixity) => Some(fixity),
+            _ => None
+        }
+    }
+
     pub fn name(&self) -> ClauseName {
         match self {
             &ClauseType::Arg => clause_name!("arg"),
@@ -1235,90 +1233,26 @@ pub enum BuiltInInstruction {
 #[derive(Clone)]
 pub enum ControlInstruction {
     Allocate(usize), // num_frames.
-    ArgCall,
-    ArgExecute,
-    Call(ClauseName, usize, usize), // name, arity, perm_vars after threshold.
-    CallN(usize), // arity.
-    CatchCall,
-    CatchExecute,
+    CallClause(ClauseType, usize, usize, bool), // name, arity, perm_vars after threshold, last call.
     CheckCpExecute,
-    CompareCall,
-    CompareExecute,
-    CompareTermCall(CompareTermQT),
-    CompareTermExecute(CompareTermQT),
-    DisplayCall,
-    DisplayExecute,
     Deallocate,
-    DuplicateTermCall,
-    DuplicateTermExecute,
-    DynamicIs,
-    EqCall,
-    EqExecute,
-    Execute(ClauseName, usize),
-    ExecuteN(usize),
-    FunctorCall,
-    FunctorExecute,
+    DynamicIs,    
     GetCleanerCall,
-    GotoCall(usize, usize),    // p, arity.
-    GotoExecute(usize, usize), // p, arity.
-    GroundCall,
-    GroundExecute,
-    IsCall(RegType, ArithmeticTerm),
-    IsExecute(RegType, ArithmeticTerm),
-    JmpByCall(usize, usize),    // arity, global_offset.
-    JmpByExecute(usize, usize),
-    KeySortCall,
-    KeySortExecute,
-    NotEqCall,
-    NotEqExecute,
-    Proceed,
-    SortCall,
-    SortExecute,
-    ThrowCall,
-    ThrowExecute,
+    Goto(usize, usize, bool),  // p, arity, last call.
+    IsClause(bool, RegType, ArithmeticTerm), // last call, register of var, term.
+    JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call.
+    Proceed
 }
 
 impl ControlInstruction {
     pub fn is_jump_instr(&self) -> bool {
         match self {
-            &ControlInstruction::ArgCall => true,
-            &ControlInstruction::ArgExecute => true,
-            &ControlInstruction::Call(_, _, _)  => true,
-            &ControlInstruction::CatchCall => true,
-            &ControlInstruction::CatchExecute => true,
-            &ControlInstruction::CompareTermCall(..) => true,
-            &ControlInstruction::CompareTermExecute(..) => true,
-            &ControlInstruction::DisplayCall => true,
-            &ControlInstruction::DisplayExecute => true,
-            &ControlInstruction::DuplicateTermCall => true,
-            &ControlInstruction::DuplicateTermExecute => true,
+            &ControlInstruction::CallClause(..)  => true,
             &ControlInstruction::DynamicIs => true,
-            &ControlInstruction::EqCall => true,
-            &ControlInstruction::EqExecute => true,
-            &ControlInstruction::Execute(_, _)  => true,
-            &ControlInstruction::CallN(_) => true,
-            &ControlInstruction::ExecuteN(_) => true,
-            &ControlInstruction::FunctorCall => true,
-            &ControlInstruction::FunctorExecute => true,
-            &ControlInstruction::NotEqCall => true,
-            &ControlInstruction::NotEqExecute => true,
-            &ControlInstruction::ThrowCall => true,
-            &ControlInstruction::ThrowExecute => true,
             &ControlInstruction::GetCleanerCall => true,
-            &ControlInstruction::GotoCall(..) => true,
-            &ControlInstruction::GotoExecute(..) => true,
-            &ControlInstruction::GroundCall => true,
-            &ControlInstruction::GroundExecute => true,
-            &ControlInstruction::IsCall(..) => true,
-            &ControlInstruction::IsExecute(..) => true,
-            &ControlInstruction::JmpByCall(..) => true,
-            &ControlInstruction::JmpByExecute(..) => true,
-            &ControlInstruction::CompareCall => true,
-            &ControlInstruction::CompareExecute => true,
-            &ControlInstruction::SortCall => true,
-            &ControlInstruction::SortExecute => true,
-            &ControlInstruction::KeySortCall => true,
-            &ControlInstruction::KeySortExecute => true,
+            &ControlInstruction::Goto(..) => true,
+            &ControlInstruction::IsClause(..) => true,
+            &ControlInstruction::JmpBy(..) => true,
             _ => false
         }
     }
@@ -1455,7 +1389,7 @@ pub enum CodePtr {
     TopLevel(usize, usize) // chunk_num, offset.
 }
 
-impl CodePtr {    
+impl CodePtr {
     pub fn module_name(&self) -> ClauseName {
         match self {
             &CodePtr::DirEntry(_, ref name) => name.clone(),
index 535db0937f3d93355cff32d13548e70aaaf78fff..9484a786bde59d4fdc7c82d9cff0e8f0e0cf4254 100644 (file)
@@ -424,7 +424,7 @@ fn get_builtins() -> Code {
                 put_unsafe_value!(4, 2),
                 put_value!(perm_v!(2), 3)],
          deallocate!(),
-         jmp_execute!(3, 1),
+         jmp_execute!(3, 1, 0),
          try_me_else!(5), // 304.
          is_var!(temp_v!(1)),
          neck_cut!(),
@@ -581,7 +581,7 @@ fn get_builtins() -> Code {
          remove_inference_counter!(perm_v!(3), temp_v!(2)),
          query![put_value!(perm_v!(3), 1),
                 put_var!(perm_v!(2), 2)],
-         jmp_call!(2, 5),
+         jmp_call!(2, 5, 0),
          erase_ball!(),
          query![put_value!(perm_v!(3), 1),
                 put_unsafe_value!(2, 2),
index 3ca845d8628f3f9828f44adf8cf758942c20448e..84a9ac6a0b0b0a04f40d4bd5c956214c9940c6f1 100644 (file)
@@ -24,8 +24,7 @@ pub struct ConjunctInfo<'a> {
 
 impl<'a> ConjunctInfo<'a>
 {
-    fn new(perm_vs: VariableFixtures<'a>, num_of_chunks: usize, has_deep_cut: bool) -> Self
-    {
+    fn new(perm_vs: VariableFixtures<'a>, num_of_chunks: usize, has_deep_cut: bool) -> Self {
         ConjunctInfo { perm_vs, num_of_chunks, has_deep_cut }
     }
 
@@ -205,55 +204,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
     fn add_conditional_call(code: &mut Code, qt: &QueryTerm, pvs: usize)
     {
         match qt {
-            &QueryTerm::Jump(ref vars) => {
-                code.push(jmp_call!(vars.len(), 0));
-            },
+            &QueryTerm::Jump(ref vars) =>
+                code.push(jmp_call!(vars.len(), 0, pvs)),
             &QueryTerm::Clause(_, ref ct, ref terms) =>
-                match ct {
-                    &ClauseType::CallWithInferenceLimit =>
-                        code.push(goto_call!(393, 3)),
-                    &ClauseType::SetupCallCleanup =>
-                        code.push(goto_call!(294, 3)),
-                    &ClauseType::Arg => {
-                        let call = ControlInstruction::ArgCall;
-                        code.push(Line::Control(call));
-                    },
-                    &ClauseType::CallN => {
-                        let call = ControlInstruction::CallN(terms.len());
-                        code.push(Line::Control(call));
-                    },
-                    &ClauseType::Catch =>
-                        code.push(Line::Control(ControlInstruction::CatchCall)),
-                    &ClauseType::Compare =>
-                        code.push(Line::Control(ControlInstruction::CompareCall)),
-                    &ClauseType::CompareTerm(qt) =>
-                        code.push(Line::Control(ControlInstruction::CompareTermCall(qt))),
-                    &ClauseType::Display =>
-                        code.push(Line::Control(ControlInstruction::DisplayCall)),
-                    &ClauseType::DuplicateTerm =>
-                        code.push(Line::Control(ControlInstruction::DuplicateTermCall)),
-                    &ClauseType::Eq =>
-                        code.push(Line::Control(ControlInstruction::EqCall)),
-                    &ClauseType::Ground =>
-                        code.push(Line::Control(ControlInstruction::GroundCall)),
-                    &ClauseType::Functor =>
-                        code.push(Line::Control(ControlInstruction::FunctorCall)),
-                    &ClauseType::Inlined(_) =>
-                        code.push(proceed!()),
-                    &ClauseType::KeySort =>
-                        code.push(keysort_call!()),
-                    &ClauseType::NotEq =>
-                        code.push(Line::Control(ControlInstruction::NotEqCall)),
-                    &ClauseType::Named(ref name) | &ClauseType::Op(ref name, _) => {
-                        let call = ControlInstruction::Call(name.clone(), terms.len(), pvs);
-                        code.push(Line::Control(call));
-                    },
-                    &ClauseType::Sort =>
-                        code.push(sort_call!()),                    
-                    &ClauseType::Throw =>
-                        code.push(Line::Control(ControlInstruction::ThrowCall)),
-                    _ => {}
-                },
+                code.push(call_clause!(ct.clone(), terms.len(), pvs)),
             _ => {}
         }
     }
@@ -265,42 +219,14 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
         match code.last_mut() {
             Some(&mut Line::Control(ref mut ctrl)) =>
                 match ctrl.clone() {
-                    ControlInstruction::GotoCall(p, arity) =>
-                        *ctrl = ControlInstruction::GotoExecute(p, arity),
-                    ControlInstruction::ArgCall =>
-                        *ctrl = ControlInstruction::ArgExecute,
-                    ControlInstruction::Call(name, arity, _) =>
-                        *ctrl = ControlInstruction::Execute(name, arity),
-                    ControlInstruction::CallN(arity) =>
-                        *ctrl = ControlInstruction::ExecuteN(arity),
-                    ControlInstruction::CompareCall =>
-                        *ctrl = ControlInstruction::CompareExecute,
-                    ControlInstruction::CompareTermCall(qt) =>
-                        *ctrl = ControlInstruction::CompareTermExecute(qt),
-                    ControlInstruction::DisplayCall =>
-                        *ctrl = ControlInstruction::DisplayExecute,
-                    ControlInstruction::DuplicateTermCall =>
-                        *ctrl = ControlInstruction::DuplicateTermExecute,
-                    ControlInstruction::EqCall =>
-                        *ctrl = ControlInstruction::EqExecute,
-                    ControlInstruction::GroundCall =>
-                        *ctrl = ControlInstruction::GroundExecute,
-                    ControlInstruction::FunctorCall =>
-                        *ctrl = ControlInstruction::FunctorExecute,
-                    ControlInstruction::JmpByCall(arity, offset) =>
-                        *ctrl = ControlInstruction::JmpByExecute(arity, offset),
-                    ControlInstruction::NotEqCall =>
-                        *ctrl = ControlInstruction::NotEqExecute,
-                    ControlInstruction::CatchCall =>
-                        *ctrl = ControlInstruction::CatchExecute,
-                    ControlInstruction::KeySortCall =>
-                        *ctrl = ControlInstruction::KeySortExecute,
-                    ControlInstruction::SortCall =>
-                        *ctrl = ControlInstruction::SortExecute,
-                    ControlInstruction::ThrowCall =>
-                        *ctrl = ControlInstruction::ThrowExecute,
-                    ControlInstruction::IsCall(r, at) =>
-                        *ctrl = ControlInstruction::IsExecute(r, at),
+                    ControlInstruction::CallClause(ct, arity, pvs, false) =>
+                        *ctrl = ControlInstruction::CallClause(ct, arity, pvs, true),
+                    ControlInstruction::Goto(p, arity, false) =>
+                        *ctrl = ControlInstruction::Goto(p, arity, true),
+                    ControlInstruction::JmpBy(arity, offset, pvs, false) =>
+                        *ctrl = ControlInstruction::JmpBy(arity, offset, pvs, true),
+                    ControlInstruction::IsClause(false, r, at) =>
+                        *ctrl = ControlInstruction::IsClause(true, r, at),
                     ControlInstruction::Proceed => {},
                     _ => dealloc_index += 1 // = code.len()
                 },
index b53a5878e2daa887e7d72cbbc322eee369c5c4f1..00aa1ed2554841dccd2a548b4389bde232ecb304 100644 (file)
@@ -34,7 +34,7 @@ impl DebrayAllocator {
 
     fn is_in_use(&self, r: usize) -> bool {
         let in_use_range = r <= self.arity && r >= self.arg_c;
-        self.in_use.contains(&r) || in_use_range
+        in_use_range || self.in_use.contains(&r)
     }
 
     fn alloc_with_cr(&self, var: &Var) -> usize
index f9db8fc7c6ef0eca8f5117028e7f5766ff3f9cf3..3b4824c4fcf5f35dcc8b0a8f420d4686431ec8c5 100644 (file)
@@ -109,88 +109,32 @@ impl fmt::Display for ControlInstruction {
         match self {
             &ControlInstruction::Allocate(num_cells) =>
                 write!(f, "allocate {}", num_cells),
-            &ControlInstruction::ArgCall =>
-                write!(f, "arg_call"),
-            &ControlInstruction::ArgExecute =>
-                write!(f, "arg_execute"),
-            &ControlInstruction::Call(ref name, arity, pvs) =>
-                write!(f, "call {}/{}, {}", name, arity, pvs),
-            &ControlInstruction::CallN(arity) =>
-                write!(f, "call_N {}", arity),
-            &ControlInstruction::CatchCall =>
-                write!(f, "catch_call"),
-            &ControlInstruction::CatchExecute =>
-                write!(f, "catch_execute"),
+            &ControlInstruction::CallClause(ref ct, arity, pvs, true) =>
+                write!(f, "execute {}/{}, {}", ct.name(), arity, pvs),
+            &ControlInstruction::CallClause(ref ct, arity, pvs, false) =>
+                write!(f, "call {}/{}, {}", ct.name(), arity, pvs),
             &ControlInstruction::CheckCpExecute =>
                 write!(f, "check_cp_execute"),
-            &ControlInstruction::CompareCall =>
-                write!(f, "compare_call"),
-            &ControlInstruction::CompareExecute =>
-                write!(f, "compare_execute"),
-            &ControlInstruction::CompareTermCall(qt) =>
-                write!(f, "compare_term_call {}", qt),
-            &ControlInstruction::CompareTermExecute(qt) =>
-                write!(f, "compare_term_execute {}", qt),
-            &ControlInstruction::DisplayCall =>
-                write!(f, "display_call"),
-            &ControlInstruction::DisplayExecute =>
-                write!(f, "display_execute"),
-            &ControlInstruction::DuplicateTermCall =>
-                write!(f, "call_duplicate_term"),
-            &ControlInstruction::DuplicateTermExecute =>
-                write!(f, "execute_duplicate_term"),
-            &ControlInstruction::EqCall =>
-                write!(f, "eq_call"),
-            &ControlInstruction::EqExecute =>
-                write!(f, "eq_execute"),
-            &ControlInstruction::ExecuteN(arity) =>
-                write!(f, "execute_N {}", arity),
-            &ControlInstruction::FunctorCall =>
-                write!(f, "functor_call"),
-            &ControlInstruction::FunctorExecute =>
-                write!(f, "functor_execute"),
             &ControlInstruction::Deallocate =>
                 write!(f, "deallocate"),
-            &ControlInstruction::GroundCall =>
-                write!(f, "ground_call"),
-            &ControlInstruction::GroundExecute =>
-                write!(f, "ground_execute"),
-            &ControlInstruction::Execute(ref name, arity) =>
-                write!(f, "execute {}/{}", name, arity),
             &ControlInstruction::GetCleanerCall =>
                 write!(f, "get_cleaner_call"),
-            &ControlInstruction::GotoCall(p, arity) =>
+            &ControlInstruction::Goto(p, arity, false) =>
                 write!(f, "goto_call {}/{}", p, arity),
-            &ControlInstruction::GotoExecute(p, arity) =>
+            &ControlInstruction::Goto(p, arity, true) =>
                 write!(f, "goto_execute {}/{}", p, arity),
-            &ControlInstruction::IsCall(r, ref at) =>
+            &ControlInstruction::IsClause(false, r, ref at) =>
                 write!(f, "is_call {}, {}", r, at),
-            &ControlInstruction::IsExecute(r, ref at) =>
+            &ControlInstruction::IsClause(true, r, ref at) =>
                 write!(f, "is_execute {}, {}", r, at),
             &ControlInstruction::DynamicIs =>
                 write!(f, "call_is"),
-            &ControlInstruction::JmpByCall(arity, offset) =>
-                write!(f, "jmp_by_call {}/{}", offset, arity),
-            &ControlInstruction::JmpByExecute(arity, offset) =>
-                write!(f, "jmp_by_execute {}/{}", offset, arity),
-            &ControlInstruction::KeySortCall =>
-                write!(f, "keysort_call"),
-            &ControlInstruction::KeySortExecute =>
-                write!(f, "keysort_execute"),
-            &ControlInstruction::NotEqCall =>
-                write!(f, "neq_call"),
-            &ControlInstruction::NotEqExecute =>
-                write!(f, "neq_execute"),
+            &ControlInstruction::JmpBy(arity, offset, pvs, false) =>
+                write!(f, "jmp_by_call {}/{}, {}", offset, arity, pvs),
+            &ControlInstruction::JmpBy(arity, offset, pvs, true) =>
+                write!(f, "jmp_by_execute {}/{}, {}", offset, arity, pvs),
             &ControlInstruction::Proceed =>
                 write!(f, "proceed"),
-            &ControlInstruction::SortCall =>
-                write!(f, "call_sort"),
-            &ControlInstruction::SortExecute =>
-                write!(f, "execute_sort"),
-            &ControlInstruction::ThrowCall =>
-                write!(f, "call_throw"),
-            &ControlInstruction::ThrowExecute =>
-                write!(f, "execute_throw"),
         }
     }
 }
@@ -521,10 +465,9 @@ fn set_first_index(code: &mut Code)
 
     for (idx, line) in code.iter_mut().enumerate() {
         match line {
-            &mut Line::Control(ControlInstruction::JmpByExecute(_, ref mut offset))
-          | &mut Line::Control(ControlInstruction::JmpByCall(_, ref mut offset)) if *offset == 0 => {
-              *offset = code_len - idx;
-              break;
+            &mut Line::Control(ControlInstruction::JmpBy(_, ref mut offset, ..)) if *offset == 0 => {
+                *offset = code_len - idx;
+                break;
             },
             _ => {}
         };
index b52565aca3263882f5c518e9954da64f39048b9b..dbc34905530bed43e74fbe1ec14ef2165b725656 100644 (file)
@@ -3,10 +3,12 @@ use prolog::ast::*;
 use prolog::copier::*;
 use prolog::num::{BigInt, BigUint, Zero, One};
 use prolog::or_stack::*;
+use prolog::heap_print::*;
 use prolog::tabled_rc::*;
 
 use downcast::Any;
 
+use std::cmp::Ordering;
 use std::collections::HashMap;
 use std::mem::swap;
 use std::ops::{Index, IndexMut};
@@ -36,7 +38,7 @@ impl<'a> CodeDirs<'a> {
     pub(crate) fn get(&self, name: ClauseName, arity: usize, p: &CodePtr)
                       -> Option<(usize, ClauseName)>
     {
-        let code_dir = self.get_current_code_dir(p);        
+        let code_dir = self.get_current_code_dir(p);
         code_dir.get(&(name, arity)).cloned()
     }
 }
@@ -230,7 +232,7 @@ pub(crate) trait CallPolicy: Any {
             },
             None => machine_st.fail = true
         };
-        
+
         Ok(())
     }
 
@@ -376,6 +378,154 @@ 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
+    {
+        match ct {
+            &ClauseType::Arg => {
+                if !lco {
+                    machine_st.cp = machine_st.p.clone() + 1;
+                }
+
+                machine_st.num_of_args = 3;
+                machine_st.b0 = machine_st.b;
+                machine_st.p  = CodePtr::DirEntry(150, clause_name!("builtin"));
+
+                Ok(())
+            },
+            &ClauseType::Catch => {
+                if !lco {
+                    machine_st.cp = machine_st.p.clone() + 1;
+                }
+
+                machine_st.num_of_args = 3;
+                machine_st.b0 = machine_st.b;
+                machine_st.p  = CodePtr::DirEntry(5, clause_name!("builtin"));
+
+                Ok(())
+            },
+            &ClauseType::CallN =>
+                if let Some((name, arity)) = machine_st.setup_call_n(arity) {
+                    if lco {
+                        self.try_execute(machine_st, code_dirs, name, arity)
+                    } else {
+                        self.try_call(machine_st, code_dirs, name, arity)
+                    }
+                } else {
+                    Ok(())
+                },
+            &ClauseType::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();
+
+                let c = Addr::Con(match machine_st.compare_term_test(&a2, &a3) {
+                    Ordering::Greater => atom!(">", machine_st.atom_tbl),
+                    Ordering::Equal   => atom!("=", machine_st.atom_tbl),
+                    Ordering::Less    => atom!("<", machine_st.atom_tbl)
+                });
+
+                machine_st.unify(a1, c);
+                return_from_clause!(lco, machine_st)
+            },
+            &ClauseType::CompareTerm(qt) => {
+                match qt {
+                    CompareTermQT::Equal =>
+                        machine_st.fail = machine_st.structural_eq_test(),
+                    CompareTermQT::NotEqual =>
+                        machine_st.fail = !machine_st.structural_eq_test(),
+                    _ => machine_st.compare_term(qt)
+                };
+
+                return_from_clause!(lco, machine_st)
+            },
+            &ClauseType::Display => {
+                let output = machine_st.print_term(machine_st[temp_v!(1)].clone(),
+                                                   DisplayFormatter {},
+                                                   PrinterOutputter::new());
+
+                println!("{}", output.result());
+                return_from_clause!(lco, machine_st)
+            },
+            &ClauseType::DuplicateTerm => {
+                machine_st.duplicate_term();
+                return_from_clause!(lco, machine_st)
+            },
+            &ClauseType::Eq => {
+                machine_st.fail = machine_st.eq_test();
+                return_from_clause!(lco, machine_st)
+            },
+            &ClauseType::Ground => {
+                machine_st.fail = machine_st.ground_test();
+                return_from_clause!(lco, machine_st)
+            },
+            &ClauseType::Functor => {
+                machine_st.try_functor()?;
+                return_from_clause!(lco, machine_st)
+            },
+            &ClauseType::NotEq => {
+                machine_st.fail = !machine_st.eq_test();
+                return_from_clause!(lco, machine_st)
+            },
+            &ClauseType::Sort => {
+                let mut list = machine_st.try_from_list(temp_v!(1))?;
+
+                list.sort_unstable_by(|a1, a2| machine_st.compare_term_test(a1, a2));
+                machine_st.term_dedup(&mut list);
+
+                let heap_addr = Addr::HeapCell(machine_st.to_list(list.into_iter()));
+
+                let r2 = machine_st[temp_v!(2)].clone();
+                machine_st.unify(r2, heap_addr);
+
+                return_from_clause!(lco, machine_st)
+            },
+            &ClauseType::KeySort => {
+                let mut list = machine_st.try_from_list(temp_v!(1))?;
+                let mut key_pairs = Vec::new();
+
+                for val in list {
+                    let key = machine_st.project_onto_key(val.clone())?;
+                    key_pairs.push((key, val.clone()));
+                }
+
+                key_pairs.sort_by(|a1, a2| machine_st.compare_term_test(&a1.0, &a2.0));
+
+                let key_pairs = key_pairs.into_iter().map(|kp| kp.1);
+                let heap_addr = Addr::HeapCell(machine_st.to_list(key_pairs));
+
+                let r2 = machine_st[temp_v!(2)].clone();
+                machine_st.unify(r2, heap_addr);
+
+                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) | &ClauseType::Op(ref name, _) =>
+                if lco {
+                    self.try_execute(machine_st, code_dirs, name.clone(), arity)
+                } else {
+                    self.try_call(machine_st, code_dirs, name.clone(), arity)
+                },
+            &ClauseType::CallWithInferenceLimit => {
+                machine_st.goto_ptr(CodePtr::DirEntry(393, clause_name!("builtin")), 3, lco);
+                Ok(())
+            },
+            &ClauseType::SetupCallCleanup => {
+                machine_st.goto_ptr(CodePtr::DirEntry(294, clause_name!("builtin")), 3, lco);
+                Ok(())
+            },
+            _ => panic!("(is)/2 or an inlined command: should have been superseded by previous clause.")
+        }
+    }
 }
 
 downcast!(CallPolicy);
@@ -490,6 +640,14 @@ impl CallPolicy for CallWithInferenceLimitCallPolicy {
         self.prev_policy.trust(machine_st, offset)?;
         self.increment()
     }
+
+    fn try_call_clause<'a>(&mut self, machine_st: &mut MachineState, code_dirs: CodeDirs<'a>,
+                           ct: &ClauseType, arity: usize, lco: bool)
+                           -> CallResult
+    {
+        self.prev_policy.try_call_clause(machine_st, code_dirs, ct, arity, lco)?;
+        self.increment()
+    }
 }
 
 pub(crate) trait CutPolicy: Any {
index 97adb11d7944af3ede5e53dd368b966fb2ae9f12..1d72446e0551c9015d13b98a0034a2c502b314cc 100644 (file)
@@ -91,8 +91,7 @@ impl MachineState {
         self.trail(r1);
     }
 
-    pub(super) fn print_term<Fmt, Outputter>(&self, a: Addr, fmt: Fmt, output: Outputter)
-                                             -> Outputter
+    pub(super) fn print_term<Fmt, Outputter>(&self, a: Addr, fmt: Fmt, output: Outputter) -> Outputter
       where Fmt: HeapCellValueFormatter, Outputter: HeapCellValueOutputter
     {
         let iter    = HeapCellPreOrderIterator::new(&self, a);
@@ -101,7 +100,7 @@ impl MachineState {
         printer.print()
     }
 
-    fn unify(&mut self, a1: Addr, a2: Addr) {
+    pub(super) fn unify(&mut self, a1: Addr, a2: Addr) {
         let mut pdl = vec![a1, a2];
 
         self.fail = false;
@@ -929,7 +928,7 @@ impl MachineState {
         }
     }
 
-    fn goto_throw(&mut self) {
+    pub(super) fn goto_throw(&mut self) {
         self.num_of_args = 1;
         self.b0 = self.b;
         self.p  = CodePtr::DirEntry(59, clause_name!("builtin"));
@@ -947,7 +946,7 @@ impl MachineState {
         self.goto_throw();
     }
 
-    fn setup_call_n(&mut self, arity: usize) -> Option<PredicateKey>
+    pub(super) fn setup_call_n(&mut self, arity: usize) -> Option<PredicateKey>
     {
         let addr = self.store(self.deref(self.registers[arity].clone()));
 
@@ -1057,7 +1056,7 @@ impl MachineState {
         self.p += 1;
     }
 
-    fn compare_term(&mut self, qt: CompareTermQT) {
+    pub(super) fn compare_term(&mut self, qt: CompareTermQT) {
         let a1 = self[temp_v!(1)].clone();
         let a2 = self[temp_v!(2)].clone();
 
@@ -1080,7 +1079,7 @@ impl MachineState {
         };
     }
 
-    fn compare_term_test(&self, a1: &Addr, a2: &Addr) -> Ordering {
+    pub(super) fn compare_term_test(&self, a1: &Addr, a2: &Addr) -> Ordering {
         let iter = self.zipped_acyclic_pre_order_iter(a1.clone(), a2.clone());
 
         for (v1, v2) in iter {
@@ -1564,7 +1563,7 @@ impl MachineState {
         };
     }
 
-    fn try_functor(&mut self) -> Result<(), Vec<HeapCellValue>> {
+    pub(super) fn try_functor(&mut self) -> Result<(), Vec<HeapCellValue>> {
         let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
 
         match a1.clone() {
@@ -1633,7 +1632,7 @@ impl MachineState {
         Ok(())
     }
 
-    fn term_dedup(&self, list: &mut Vec<Addr>) {
+    pub(super) fn term_dedup(&self, list: &mut Vec<Addr>) {
         let mut result = vec![];
 
         for a2 in list.iter().cloned() {
@@ -1645,11 +1644,11 @@ impl MachineState {
 
             result.push(a2);
         }
-        
+
         *list = result;
     }
-    
-    fn to_list<Iter: Iterator<Item=Addr>>(&mut self, values: Iter) -> usize {
+
+    pub(super) fn to_list<Iter: Iterator<Item=Addr>>(&mut self, values: Iter) -> usize {
         let head_addr = self.heap.h;
 
         for value in values {
@@ -1663,7 +1662,7 @@ impl MachineState {
         head_addr
     }
 
-    fn try_from_list(&self, r: RegType) -> Result<Vec<Addr>, Vec<HeapCellValue>>
+    pub(super) fn try_from_list(&self, r: RegType) -> Result<Vec<Addr>, Vec<HeapCellValue>>
     {
         let a1 = self.store(self.deref(self[r].clone()));
 
@@ -1673,7 +1672,7 @@ impl MachineState {
 
                 result.push(self.heap[l].as_addr(l));
                 l += 1;
-                
+
                 loop {
                     match self.heap[l].clone() {
                         HeapCellValue::Addr(Addr::Lis(hcp)) => {
@@ -1696,7 +1695,7 @@ impl MachineState {
         }
     }
 
-    fn project_onto_key(&self, a: Addr) -> Result<Addr, Vec<HeapCellValue>> {
+    pub(super) fn project_onto_key(&self, a: Addr) -> Result<Addr, Vec<HeapCellValue>> {
         match self.store(self.deref(a)) {
             Addr::Str(s) =>
                 match self.heap[s].clone() {
@@ -1709,8 +1708,8 @@ impl MachineState {
             a => Err(functor!("type_error", 2, [heap_atom!("callable"), HeapCellValue::Addr(a)]))
         }
     }
-    
-    fn duplicate_term(&mut self) {
+
+    pub(super) fn duplicate_term(&mut self) {
         let old_h = self.heap.h;
 
         let a1 = self[temp_v!(1)].clone();
@@ -1727,7 +1726,7 @@ impl MachineState {
     }
 
     // returns true on failure.
-    fn eq_test(&self) -> bool
+    pub(super) fn eq_test(&self) -> bool
     {
         let a1 = self[temp_v!(1)].clone();
         let a2 = self[temp_v!(2)].clone();
@@ -1754,7 +1753,7 @@ impl MachineState {
     }
 
     // returns true on failure.
-    fn structural_eq_test(&self) -> bool
+    pub(super) fn structural_eq_test(&self) -> bool
     {
         let a1 = self[temp_v!(1)].clone();
         let a2 = self[temp_v!(2)].clone();
@@ -1797,7 +1796,7 @@ impl MachineState {
     }
 
     // returns true on failure.
-    fn ground_test(&self) -> bool
+    pub(super) fn ground_test(&self) -> bool
     {
         let a = self.store(self.deref(self[temp_v!(1)].clone()));
 
@@ -1849,34 +1848,8 @@ impl MachineState {
                 self.and_stack.push(gi, self.e, self.cp.clone(), num_cells);
                 self.e = self.and_stack.len() - 1;
             },
-            &ControlInstruction::ArgCall => {
-                self.cp = self.p.clone() + 1;
-                self.num_of_args = 3;
-                self.b0 = self.b;
-                self.p  = CodePtr::DirEntry(150, clause_name!("builtin"));
-            },
-            &ControlInstruction::ArgExecute => {
-                self.num_of_args = 3;
-                self.b0 = self.b;
-                self.p  = CodePtr::DirEntry(150, clause_name!("builtin"));
-            },
-            &ControlInstruction::Call(ref name, arity, _) =>
-                try_or_fail!(self, call_policy.try_call(self, code_dirs, name.clone(), arity)),
-            &ControlInstruction::CatchCall => {
-                self.cp = self.p.clone() + 1;
-                self.num_of_args = 3;
-                self.b0 = self.b;
-                self.p  = CodePtr::DirEntry(5, clause_name!("builtin"));
-            },
-            &ControlInstruction::CatchExecute => {
-                self.num_of_args = 3;
-                self.b0 = self.b;
-                self.p  = CodePtr::DirEntry(5, clause_name!("builtin"));
-            },
-            &ControlInstruction::CallN(arity) =>
-                if let Some((name, arity)) = self.setup_call_n(arity) {
-                    try_or_fail!(self, call_policy.try_call(self, code_dirs, name, arity))
-                },
+            &ControlInstruction::CallClause(ref ct, arity, _, lco) =>
+                try_or_fail!(self, call_policy.try_call_clause(self, code_dirs, ct, arity, lco)),
             &ControlInstruction::CheckCpExecute => {
                 let a = self.store(self.deref(self[temp_v!(2)].clone()));
 
@@ -1892,58 +1865,6 @@ impl MachineState {
                     }
                 };
             },
-            &ControlInstruction::CompareCall => {
-                let a1 = self[temp_v!(1)].clone();
-                let a2 = self[temp_v!(2)].clone();
-                let a3 = self[temp_v!(3)].clone();
-
-                let c = Addr::Con(match self.compare_term_test(&a2, &a3) {
-                    Ordering::Greater => atom!(">", self.atom_tbl),
-                    Ordering::Equal   => atom!("=", self.atom_tbl),
-                    Ordering::Less    => atom!("<", self.atom_tbl)
-                });
-
-                self.unify(a1, c);
-
-                self.p += 1;
-            },
-            &ControlInstruction::CompareExecute => {
-                let a1 = self[temp_v!(1)].clone();
-                let a2 = self[temp_v!(2)].clone();
-                let a3 = self[temp_v!(3)].clone();
-
-                let c = Addr::Con(match self.compare_term_test(&a2, &a3) {
-                    Ordering::Greater => atom!(">", self.atom_tbl),
-                    Ordering::Equal   => atom!("=", self.atom_tbl),
-                    Ordering::Less    => atom!("<", self.atom_tbl)
-                });
-
-                self.unify(a1, c);
-
-                self.p = self.cp.clone();
-            },
-            &ControlInstruction::CompareTermCall(qt) => {
-                match qt {
-                    CompareTermQT::Equal =>
-                        self.fail = self.structural_eq_test(),
-                    CompareTermQT::NotEqual =>
-                        self.fail = !self.structural_eq_test(),
-                    _ => self.compare_term(qt)
-                };
-
-                self.p += 1;
-            },
-            &ControlInstruction::CompareTermExecute(qt) => {
-                match qt {
-                    CompareTermQT::Equal =>
-                        self.fail = self.structural_eq_test(),
-                    CompareTermQT::NotEqual =>
-                        self.fail = !self.structural_eq_test(),
-                    _ => self.compare_term(qt)
-                };
-
-                self.p = self.cp.clone();
-            },
             &ControlInstruction::Deallocate => {
                 let e = self.e;
 
@@ -1952,32 +1873,6 @@ impl MachineState {
 
                 self.p += 1;
             },
-            &ControlInstruction::DisplayCall => {
-                let output = self.print_term(self[temp_v!(1)].clone(),
-                                             DisplayFormatter {},
-                                             PrinterOutputter::new());
-
-                println!("{}", output.result());
-
-                self.p += 1;
-            },
-            &ControlInstruction::DisplayExecute => {
-                let output = self.print_term(self[temp_v!(1)].clone(),
-                                             DisplayFormatter {},
-                                             PrinterOutputter::new());
-
-                println!("{}", output.result());
-
-                self.p = self.cp.clone();
-            },
-            &ControlInstruction::DuplicateTermCall => {
-                self.duplicate_term();
-                self.p += 1;
-            },
-            &ControlInstruction::DuplicateTermExecute => {
-                self.duplicate_term();
-                self.p = self.cp.clone();
-            },
             &ControlInstruction::DynamicIs => {
                 let a = self[temp_v!(1)].clone();
                 let result = try_or_fail!(self, self.arith_eval_by_metacall(temp_v!(2)));
@@ -1985,40 +1880,6 @@ impl MachineState {
                 self.unify(a, Addr::Con(Constant::Number(result)));
                 self.p += 1;
             },
-            &ControlInstruction::EqCall => {
-                self.fail = self.eq_test();
-                self.p += 1;
-            },
-            &ControlInstruction::EqExecute => {
-                self.fail = self.eq_test();
-                self.p = self.cp.clone();
-            },
-            &ControlInstruction::GroundCall => {
-                self.fail = self.ground_test();
-                self.p += 1;
-            },
-            &ControlInstruction::GroundExecute => {
-                self.fail = self.ground_test();
-                self.p = self.cp.clone();
-            },
-            &ControlInstruction::Execute(ref name, arity) =>
-                try_or_fail!(self, call_policy.try_execute(self, code_dirs, name.clone(), arity)),
-            &ControlInstruction::ExecuteN(arity) =>
-                if let Some((name, arity)) = self.setup_call_n(arity) {
-                    try_or_fail!(self, call_policy.try_execute(self, code_dirs, name, arity))
-                },
-            &ControlInstruction::FunctorCall =>
-                try_or_fail!(self, {
-                    let val = self.try_functor();
-                    self.p += 1;
-                    val
-                }),
-            &ControlInstruction::FunctorExecute =>
-                try_or_fail!(self, {
-                    let val = self.try_functor();
-                    self.p = self.cp.clone();
-                    val
-                }),
             &ControlInstruction::GetCleanerCall => {
                 let dest = self[temp_v!(1)].clone();
 
@@ -2044,136 +1905,39 @@ impl MachineState {
 
                 self.fail = true;
             },
-            &ControlInstruction::GotoCall(p, arity) => {
-                self.cp = self.p.clone() + 1;
-                self.num_of_args = arity;
-                self.b0 = self.b;
-                self.p  = CodePtr::DirEntry(p, clause_name!("builtin"));
-            },
-            &ControlInstruction::GotoExecute(p, arity) => {
-                self.num_of_args = arity;
-                self.b0 = self.b;
-                self.p  = CodePtr::DirEntry(p, clause_name!("builtin"));
-            },
-            &ControlInstruction::IsCall(r, ref at) => {
+            &ControlInstruction::Goto(p, arity, lco) =>
+                self.goto_ptr(CodePtr::DirEntry(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));
 
                 self.unify(a1, Addr::Con(Constant::Number(a2)));
-                self.p += 1;
+                try_or_fail!(self, return_from_clause!(lco, self));
             },
-            &ControlInstruction::IsExecute(r, ref at) => {
-                let a1 = self[r].clone();
-                let a2 = try_or_fail!(self, self.get_number(at));
+            &ControlInstruction::JmpBy(arity, offset, _, lco) => {
+                if !lco {
+                    self.cp = self.p.clone() + 1;
+                }
 
-                self.unify(a1, Addr::Con(Constant::Number(a2)));
-                self.p = self.cp.clone();
-            },
-            &ControlInstruction::JmpByCall(arity, offset) => {
-                self.cp = self.p.clone() + 1;
                 self.num_of_args = arity;
                 self.b0 = self.b;
                 self.p += offset;
             },
-            &ControlInstruction::JmpByExecute(arity, offset) => {
-                self.num_of_args = arity;
-                self.b0 = self.b;
-                self.p += offset;
-            },
-            &ControlInstruction::NotEqCall => {
-                self.fail = !self.eq_test();
-                self.p += 1;
-            },
-            &ControlInstruction::NotEqExecute => {
-                self.fail = !self.eq_test();
-                self.p = self.cp.clone();
-            },
             &ControlInstruction::Proceed =>
                 self.p = self.cp.clone(),
-            &ControlInstruction::SortCall => {
-                let mut list = try_or_fail!(self, {
-                    let val = self.try_from_list(temp_v!(1));
-                    self.p += 1;
-                    val
-                });
-                                
-                list.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2));
-                self.term_dedup(&mut list);
-                
-                let heap_addr = Addr::HeapCell(self.to_list(list.into_iter()));
-                
-                let r2 = self[temp_v!(2)].clone();
-                self.unify(r2, heap_addr);
-            },
-            &ControlInstruction::SortExecute => {
-                let mut list = try_or_fail!(self, {
-                    let val = self.try_from_list(temp_v!(1));
-                    self.p = self.cp.clone();
-                    val
-                });
-                
-                list.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2));
-                self.term_dedup(&mut list);
-                
-                let heap_addr = Addr::HeapCell(self.to_list(list.into_iter()));
-                
-                let r2 = self[temp_v!(2)].clone();
-                self.unify(r2, heap_addr);
-            },
-            &ControlInstruction::KeySortCall => {
-                let mut list = try_or_fail!(self, {
-                    let val = self.try_from_list(temp_v!(1));                                        
-                    self.p += 1;
-                    val
-                });
-
-                let mut key_pairs = Vec::new();
-                
-                for val in list {
-                    let key = try_or_fail!(self, self.project_onto_key(val.clone()));
-                    key_pairs.push((key, val.clone()));
-                }
-                
-                key_pairs.sort_by(|a1, a2| self.compare_term_test(&a1.0, &a2.0));
-                
-                let key_pairs = key_pairs.into_iter().map(|kp| kp.1);
-                let heap_addr = Addr::HeapCell(self.to_list(key_pairs));
-                
-                let r2 = self[temp_v!(2)].clone();
-                self.unify(r2, heap_addr);
-            },
-            &ControlInstruction::KeySortExecute => {
-                let mut list = try_or_fail!(self, {
-                    let val = self.try_from_list(temp_v!(1));
-                    self.p = self.cp.clone();
-                    val
-                });
-                
-                let mut key_pairs = Vec::new();
-                
-                for val in list {
-                    let key = try_or_fail!(self, self.project_onto_key(val.clone()));
-                    key_pairs.push((key, val.clone()));
-                }
-                
-                key_pairs.sort_by(|a1, a2| self.compare_term_test(&a1.0, &a2.0));
-                
-                let key_pairs = key_pairs.into_iter().map(|kp| kp.1);
-                let heap_addr = Addr::HeapCell(self.to_list(key_pairs));
-                            
-                let r2 = self[temp_v!(2)].clone();
-                self.unify(r2, heap_addr);
-            },
-            &ControlInstruction::ThrowCall => {
-                self.cp = self.p.clone() + 1;
-                self.goto_throw();
-            },
-            &ControlInstruction::ThrowExecute => {
-                self.goto_throw();
-            },
         };
     }
 
+    pub(super) fn goto_ptr(&mut self, p: CodePtr, arity: usize, lco:bool) {
+        if !lco {
+            self.cp = self.p.clone() + 1;
+        }
+
+        self.num_of_args = arity;
+        self.b0 = self.b;
+        self.p  = p;
+    }
+
     pub(super) fn execute_indexed_choice_instr(&mut self, instr: &IndexedChoiceInstruction,
                                                call_policy: &mut Box<CallPolicy>)
     {
index c6fed893041006cc44818a18da5663ba9d5e7844..4c3a581617963a55b0e10cc00e3f748de1efbede 100644 (file)
@@ -228,15 +228,21 @@ macro_rules! trust_me {
     )
 }
 
+macro_rules! call_clause {
+    ($ct:expr, $arity:expr, $pvs:expr) => (
+        Line::Control(ControlInstruction::CallClause($ct, $arity, $pvs, false))
+    )
+}
+
 macro_rules! call_n {
     ($arity:expr) => (
-        Line::Control(ControlInstruction::CallN($arity))
+        Line::Control(ControlInstruction::CallClause(ClauseType::CallN, $arity, 0, false))
     )
 }
 
 macro_rules! execute_n {
     ($arity:expr) => (
-        Line::Control(ControlInstruction::ExecuteN($arity))
+        Line::Control(ControlInstruction::CallClause(ClauseType::CallN, $arity, 0, true))
     )
 }
 
@@ -272,13 +278,13 @@ macro_rules! install_new_block {
 
 macro_rules! goto_call {
     ($line:expr, $arity:expr) => (
-        Line::Control(ControlInstruction::GotoCall($line, $arity))
+        Line::Control(ControlInstruction::Goto($line, $arity, false))
     )
 }
 
 macro_rules! goto_execute {
     ($line:expr, $arity:expr) => (
-        Line::Control(ControlInstruction::GotoExecute($line, $arity))
+        Line::Control(ControlInstruction::Goto($line, $arity, true))
     )
 }
 
@@ -308,7 +314,8 @@ macro_rules! unify {
 
 macro_rules! is_call {
     ($r:expr, $at:expr) => (
-        Line::Control(ControlInstruction::IsCall($r, $at))
+        Line::Control(ControlInstruction::IsClause(false, $r, $at))
+
     )
 }
 
@@ -344,7 +351,7 @@ macro_rules! succeed {
 
 macro_rules! duplicate_term {
     () => (
-        Line::Control(ControlInstruction::DuplicateTermCall)
+        Line::Control(ControlInstruction::CallClause(ClauseType::DuplicateTerm, 2, 0, false))
     )
 }
 
@@ -395,13 +402,13 @@ macro_rules! get_structure {
 
 macro_rules! functor_call {
     () => (
-        Line::Control(ControlInstruction::FunctorCall)
+        Line::Control(ControlInstruction::CallClause(ClauseType::Functor, 3, 0, false))
     )
 }
 
 macro_rules! functor_execute {
     () => (
-        Line::Control(ControlInstruction::FunctorExecute)
+        Line::Control(ControlInstruction::CallClause(ClauseType::Functor, 3, 0, true))
     )
 }
 
@@ -485,7 +492,7 @@ macro_rules! infix {
 
 macro_rules! display {
     () => (
-        Line::Control(ControlInstruction::DisplayCall)
+        Line::Control(ControlInstruction::CallClause(ClauseType::Display, 1, 0, false))
     )
 }
 
@@ -538,14 +545,14 @@ macro_rules! cmp_eq {
 }
 
 macro_rules! jmp_call {
-    ($arity:expr, $offset:expr) => (
-        Line::Control(ControlInstruction::JmpByCall($arity, $offset))
+    ($arity:expr, $offset:expr, $pvs:expr) => (
+        Line::Control(ControlInstruction::JmpBy($arity, $offset, $pvs, false))
     )
 }
 
 macro_rules! jmp_execute {
-    ($arity:expr, $offset:expr) => (
-        Line::Control(ControlInstruction::JmpByExecute($arity, $offset))
+    ($arity:expr, $offset:expr, $pvs:expr) => (
+        Line::Control(ControlInstruction::JmpBy($arity, $offset, $pvs, true))
     )
 }
 
@@ -587,25 +594,25 @@ macro_rules! restore_cut_policy {
 
 macro_rules! ground_execute {
     () => (
-        Line::Control(ControlInstruction::GroundExecute)
+        Line::Control(ControlInstruction::CallClause(ClauseType::Ground, 1, 0, true))
     )
 }
 
 macro_rules! eq_execute {
     () => (
-        Line::Control(ControlInstruction::EqExecute)
+        Line::Control(ControlInstruction::CallClause(ClauseType::Eq, 2, 0, true))
     )
 }
 
 macro_rules! not_eq_execute {
     () => (
-        Line::Control(ControlInstruction::NotEqExecute)
+        Line::Control(ControlInstruction::CallClause(ClauseType::NotEq, 2, 0, true))
     )
 }
 
 macro_rules! compare_term_execute {
     ($qt:expr) => (
-        Line::Control(ControlInstruction::CompareTermExecute($qt))
+        Line::Control(ControlInstruction::CallClause(ClauseType::CompareTerm($qt), 2, 0, true))
     )
 }
 
@@ -689,7 +696,7 @@ macro_rules! remove_call_policy_check {
 
 macro_rules! compare_execute {
     () => (
-        Line::Control(ControlInstruction::CompareExecute)
+        Line::Control(ControlInstruction::CallClause(ClauseType::Compare, 2, 0, true))
     )
 }
 
@@ -708,26 +715,26 @@ macro_rules! try_eval_session {
     )
 }
 
-macro_rules! sort_call {
+macro_rules! sort_execute {
     () => (
-        Line::Control(ControlInstruction::SortCall)
+        Line::Control(ControlInstruction::CallClause(ClauseType::Sort, 2, 0, true))
     )
 }
 
-macro_rules! keysort_call {
+macro_rules! keysort_execute {
     () => (
-        Line::Control(ControlInstruction::KeySortCall)
+        Line::Control(ControlInstruction::CallClause(ClauseType::KeySort, 2, 0, true))
     )
 }
 
-macro_rules! sort_execute {
-    () => (
-        Line::Control(ControlInstruction::SortExecute)
-    )
-}
+macro_rules! return_from_clause {
+    ($lco:expr, $machine_st:expr) => {{
+        if $lco {
+            $machine_st.p = $machine_st.cp.clone();
+        } else {
+            $machine_st.p += 1;
+        }
 
-macro_rules! keysort_execute {
-    () => (
-        Line::Control(ControlInstruction::KeySortExecute)
-    )
+        Ok(())
+    }}
 }
index 6640fd1bb2fadea87bc769c7f8d5f76f0df6867c..b144c74814416f789d69c0db463906959512f5cd 100644 (file)
@@ -1694,59 +1694,59 @@ fn test_queries_on_call_with_inference_limit()
 
     submit(&mut wam, "f(X) :- call_with_inference_limit(g(X), 5, _).");
 
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X), 6, R).",
+    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X), 7, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = true", "X = 3"],
                             ["R = true", "X = 4"],
                             ["R = !", "X = 5"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X), 5, R).",
+    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X), 6, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = true", "X = 3"],
                             ["R = true", "X = 4"],
                             ["R = inference_limit_exceeded", "X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X), 3, R).",
+    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X), 4, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = inference_limit_exceeded", "X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X), 2, R).",
+    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X), 3, R).",
                            [["R = true", "X = 1"],
                             ["R = inference_limit_exceeded", "X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X), 1, R).",
+    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X), 2, R).",
                            [["R = inference_limit_exceeded", "X = _1"]]);
 
     submit(&mut wam, "e(X) :- call_with_inference_limit(f(X), 10, _).");
 
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(e(X), 7, R).",
+    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(e(X), 10, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = true", "X = 3"],
                             ["R = true", "X = 4"],
                             ["R = !", "X = 5"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(e(X), 6, R).",
+    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(e(X), 8, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = true", "X = 3"],
                             ["R = true", "X = 4"],
                             ["R = inference_limit_exceeded", "X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(e(X), 4, R).",
+    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(e(X), 6, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = inference_limit_exceeded", "X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(e(X), 3, R).",
+    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(e(X), 5, R).",
                            [["R = true", "X = 1"],
                             ["R = inference_limit_exceeded", "X = _1"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(e(X), 2, R).",
+    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(e(X), 4, R).",
                            [["R = inference_limit_exceeded", "X = _1"]]);
 
     submit(&mut wam, "f(X, R) :- call_with_inference_limit(g(X), 5, R).");
 
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X, R), 3, S).",
+    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X, R), 4, S).",
                            [["S = true", "X = 1", "R = true"],
                             ["S = true", "X = 2", "R = true"],
                             ["S = inference_limit_exceeded", "X = _1", "R = _2"]]);
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X, R), 7, R).",
+    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X, R), 8, R).",
                            [["R = true", "X = 1"],
                             ["R = true", "X = 2"],
                             ["R = true", "X = 3"],
@@ -1755,7 +1755,7 @@ fn test_queries_on_call_with_inference_limit()
 
     submit(&mut wam, "g(1). g(2). g(3). g(4). g(5). g(6).");
 
-    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X, R), 7, S).",
+    assert_prolog_success!(&mut wam, "?- call_with_inference_limit(f(X, R), 8, S).",
                            [["R = true", "X = 1", "S = true"],
                             ["R = true", "X = 2", "S = true"],
                             ["R = true", "X = 3", "S = true"],