]> Repositorios git - scryer-prolog.git/commitdiff
make system calls exempt from call policy.
authorMark Thom <[email protected]>
Fri, 11 May 2018 04:24:15 +0000 (22:24 -0600)
committerMark Thom <[email protected]>
Fri, 11 May 2018 04:24:15 +0000 (22:24 -0600)
src/prolog/ast.rs
src/prolog/codegen.rs
src/prolog/io.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/mod.rs
src/prolog/machine/system_calls.rs
src/prolog/macros.rs

index 09ef2c8ac81794d37576f90b2af6a8c9141fe864..2e50706aac4d9af6b1796dae5c5d9e95417c5bac 100644 (file)
@@ -561,9 +561,9 @@ pub enum Term {
     Var(Cell<VarReg>, Rc<Var>)
 }
 
-#[derive(Clone, Copy, PartialEq)]
+#[derive(Clone, PartialEq)]
 pub enum InlinedClauseType {
-    CompareNumber(CompareNumberQT, RegType, RegType),
+    CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm),
     IsAtom(RegType),
     IsAtomic(RegType),
     IsCompound(RegType),
@@ -609,20 +609,23 @@ impl InlinedClauseType {
     pub fn from(name: &str, arity: usize) -> Option<Self> {
         let r1 = temp_v!(1);
         let r2 = temp_v!(2);
+
+        let a1 = ArithmeticTerm::Reg(r1);
+        let a2 = ArithmeticTerm::Reg(r2);
         
         match (name, arity) {
             (">", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThan, r1, r2)),
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThan, a1, a2)),
             ("<", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThan, r1, r2)),
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThan, a1, a2)),
             (">=", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThanOrEqual,r1, r2)),
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThanOrEqual,a1, a2)),
             ("=<", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual, r1, r2)),
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual, a1, a2)),
             ("=\\=", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::NotEqual, r1, r2)),
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::NotEqual, a1, a2)),
             ("=:=", 2) =>
-                Some(InlinedClauseType::CompareNumber(CompareNumberQT::Equal, r1, r2)),
+                Some(InlinedClauseType::CompareNumber(CompareNumberQT::Equal, a1, a2)),
             ("atom", 1) => Some(InlinedClauseType::IsAtom(r1)),
             ("atomic", 1) => Some(InlinedClauseType::IsAtomic(r1)),
             ("compound", 1) => Some(InlinedClauseType::IsCompound(r1)),
@@ -716,10 +719,12 @@ pub enum SystemClauseType {
     Fail,
     GetBall,
     GetCurrentBlock,
+    GetCutPoint(RegType),
     InstallNewBlock,
     ResetBlock,
     SetBall,
     SkipMaxList,
+    Succeed,
     UnwindStack
 }
 
@@ -731,10 +736,12 @@ impl SystemClauseType {
             &SystemClauseType::Fail => 0,
             &SystemClauseType::GetBall => 1,
             &SystemClauseType::GetCurrentBlock => 1,
+            &SystemClauseType::GetCutPoint(_) => 1,
             &SystemClauseType::InstallNewBlock => 1,
             &SystemClauseType::ResetBlock => 1,
             &SystemClauseType::SetBall => 1,
             &SystemClauseType::SkipMaxList => 4,
+            &SystemClauseType::Succeed => 0,
             &SystemClauseType::UnwindStack => 0
         }
     }
@@ -749,11 +756,13 @@ impl SystemClauseType {
             &SystemClauseType::EraseBall => clause_name!("$erase_ball"),
             &SystemClauseType::Fail => clause_name!("$fail"),
             &SystemClauseType::GetBall => clause_name!("$get_ball"),
+            &SystemClauseType::GetCutPoint(_) => clause_name!("$get_cp"),
             &SystemClauseType::GetCurrentBlock => clause_name!("$get_current_block"),
             &SystemClauseType::InstallNewBlock => clause_name!("$install_new_block"),
             &SystemClauseType::ResetBlock => clause_name!("$reset_block"),
             &SystemClauseType::SetBall => clause_name!("$set_ball"),
             &SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
+            &SystemClauseType::Succeed => clause_name!("$succeed"),
             &SystemClauseType::UnwindStack => clause_name!("$unwind_stack"),
         }
     }
@@ -765,6 +774,7 @@ impl SystemClauseType {
             ("$fail", 0) => Some(SystemClauseType::Fail),
             ("$get_ball", 1) => Some(SystemClauseType::GetBall),
             ("$get_current_block", 1) => Some(SystemClauseType::GetCurrentBlock),
+            ("$get_cp", 1) => Some(SystemClauseType::GetCutPoint(temp_v!(0))),
             ("$install_new_block", 1) => Some(SystemClauseType::InstallNewBlock),
             ("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
             ("$set_ball", 1) => Some(SystemClauseType::SetBall),
@@ -790,7 +800,6 @@ pub enum BuiltInClauseType {
     KeySort,
     NotEq,
     Sort,
-    System(SystemClauseType)
 }
 
 #[derive(Clone)]
@@ -799,7 +808,8 @@ pub enum ClauseType {
     CallN,
     Inlined(InlinedClauseType),    
     Op(ClauseName, Fixity, CodeIndex),
-    Named(ClauseName, CodeIndex)
+    Named(ClauseName, CodeIndex),
+    System(SystemClauseType)
 }
 
 #[derive(Clone)]
@@ -891,8 +901,7 @@ impl BuiltInClauseType {
             &BuiltInClauseType::Is => clause_name!("is"),
             &BuiltInClauseType::KeySort => clause_name!("keysort"),
             &BuiltInClauseType::NotEq => clause_name!("\\=="),            
-            &BuiltInClauseType::Sort => clause_name!("sort"),
-            &BuiltInClauseType::System(system) => system.name()
+            &BuiltInClauseType::Sort => clause_name!("sort"),            
         }
     }    
 
@@ -911,7 +920,6 @@ impl BuiltInClauseType {
             &BuiltInClauseType::KeySort => 2,
             &BuiltInClauseType::NotEq => 2,
             &BuiltInClauseType::Sort => 2,
-            &BuiltInClauseType::System(system) => system.arity()                
         }
     }
     
@@ -935,7 +943,7 @@ impl BuiltInClauseType {
             ("keysort", 2) => Some(BuiltInClauseType::KeySort),
             ("\\==", 2) => Some(BuiltInClauseType::NotEq),
             ("sort", 2) => Some(BuiltInClauseType::Sort),
-            _ => SystemClauseType::from(name, arity).map(BuiltInClauseType::System)
+            _ => None
         }
     }
 }
@@ -946,6 +954,7 @@ impl ClauseType {
             &ClauseType::BuiltIn(ref built_in) => built_in.fixity(),
             &ClauseType::Inlined(InlinedClauseType::CompareNumber(..)) => Some(Fixity::In),
             &ClauseType::Op(_, fixity, _) => Some(fixity),
+            &ClauseType::System(ref system) => system.fixity(),
             _ => None
         }
     }
@@ -954,9 +963,10 @@ impl ClauseType {
         match self {
             &ClauseType::CallN => clause_name!("call"),            
             &ClauseType::BuiltIn(built_in) => built_in.name(),
-            &ClauseType::Inlined(inlined) => clause_name!(inlined.name()),
+            &ClauseType::Inlined(ref inlined) => clause_name!(inlined.name()),
             &ClauseType::Op(ref name, ..) => name.clone(),
             &ClauseType::Named(ref name, ..) => name.clone(),
+            &ClauseType::System(ref system) => system.name(),
         }
     }
 
@@ -967,15 +977,19 @@ impl ClauseType {
                 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())
-                        }
+                        SystemClauseType::from(name.as_str(), arity)
+                            .map(ClauseType::System)
+                            .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())
+                                }
+                            })
                     })
-            })            
+            })
     }
 }
 
@@ -1309,7 +1323,7 @@ impl Neg for Number {
     }
 }
 
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub enum ArithmeticTerm {
     Reg(RegType),
     Interm(usize),
@@ -1347,30 +1361,14 @@ pub enum ArithmeticInstruction {
 
 #[derive(Clone)]
 pub enum BuiltInInstruction {
-    CleanUpBlock,
-    CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm),
-    DefaultRetryMeElse(usize),
-    DefaultSetCutPoint(RegType),
-    DefaultTrustMe,
-    EraseBall,
-    Fail,
     GetArg(bool), // last call.
-    GetBall,
-    GetCurrentBlock,
-    GetCutPoint(RegType),
     InferenceLevel(RegType, RegType),
     InstallCleaner,
     InstallInferenceCounter(RegType, RegType, RegType),
-    InstallNewBlock,
     RemoveCallPolicyCheck,
     RemoveInferenceCounter(RegType, RegType),
-    ResetBlock,
     RestoreCutPolicy,
-    SetBall,
     SetCutPoint(RegType),
-    Succeed,
-    Unify,
-    UnwindStack
 }
 
 #[derive(Clone)]
@@ -1379,8 +1377,7 @@ pub enum ControlInstruction {
     CallClause(ClauseType, usize, usize, bool), // name, arity, perm_vars after threshold, last call.
     CheckCpExecute,
     Deallocate,
-    GetCleanerCall,
-    Goto(usize, usize, bool),  // p, arity, last call.
+    GetCleanerCall,    
     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
@@ -1391,7 +1388,6 @@ impl ControlInstruction {
         match self {
             &ControlInstruction::CallClause(..)  => true,
             &ControlInstruction::GetCleanerCall => true,
-            &ControlInstruction::Goto(..) => true,
             &ControlInstruction::IsClause(..) => true,
             &ControlInstruction::JmpBy(..) => true,
             _ => false
@@ -1586,7 +1582,6 @@ 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)
 }
 
@@ -1594,7 +1589,6 @@ impl CodePtr {
     pub fn local(&self) -> LocalCodePtr {
         match self {
             &CodePtr::BuiltInClause(_, ref local)
-          | &CodePtr::CallN(_, ref local)
           | &CodePtr::Local(ref local) => local.clone()
         }
     }
@@ -1684,7 +1678,6 @@ impl Add<usize> for CodePtr {
         match self {
             CodePtr::Local(local) => CodePtr::Local(local + rhs),
             CodePtr::BuiltInClause(_, local) => CodePtr::Local(local + rhs),
-            CodePtr::CallN(_, local) => CodePtr::Local(local + rhs),
         }
     }
 }
index 4e6d9ed35cd4ea916f1a39a4df63e77c0669abea..de0f801876ef36203a7eb1ec182b66fdba1ccd76 100644 (file)
@@ -232,14 +232,12 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                 match ctrl.clone() {
                     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()
+                    _ => dealloc_index += 1
                 },
             Some(&mut Line::Cut(CutInstruction::Cut(_))) =>
                 dealloc_index += 1,
@@ -249,12 +247,12 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
         dealloc_index
     }
 
-    fn compile_inlined(&mut self, ct: InlinedClauseType, terms: &'a Vec<Box<Term>>,
+    fn compile_inlined(&mut self, ct: &InlinedClauseType, terms: &'a Vec<Box<Term>>,
                        term_loc: GenContext, code: &mut Code)
                        -> 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)?;
 
@@ -265,7 +263,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                                                 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 +276,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 +289,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 +302,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 +315,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 +328,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 +341,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 +354,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 +367,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!());
@@ -446,7 +444,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
                             }
                         }
                     },
-                    &QueryTerm::Clause(_, ClauseType::Inlined(ct), ref terms) =>
+                    &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms) =>
                         try!(self.compile_inlined(ct, terms, term_loc, code)),
                     _ => {
                         let num_perm_vars = if chunk_num == 0 {
index 974876a8563a663b114e3a9c24cb98e38ae47046..576fa8001f4fd65cc2fffa2871fdf23cfd2d89cb 100644 (file)
@@ -139,10 +139,6 @@ impl fmt::Display for ControlInstruction {
                 write!(f, "deallocate"),
             &ControlInstruction::GetCleanerCall =>
                 write!(f, "get_cleaner_call"),
-            &ControlInstruction::Goto(p, arity, false) =>
-                write!(f, "goto_call {}/{}", p, arity),
-            &ControlInstruction::Goto(p, arity, true) =>
-                write!(f, "goto_execute {}/{}", p, arity),
             &ControlInstruction::IsClause(false, r, ref at) =>
                 write!(f, "is_call {}, {}", r, at),
             &ControlInstruction::IsClause(true, r, ref at) =>
@@ -173,56 +169,24 @@ impl fmt::Display for IndexedChoiceInstruction {
 impl fmt::Display for BuiltInInstruction {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
-            &BuiltInInstruction::CleanUpBlock =>
-                write!(f, "clean_up_block"),
-            &BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) =>
-                write!(f, "number_test {}, {}, {} ", cmp, at_1, at_2),
-            &BuiltInInstruction::DefaultRetryMeElse(o) =>
-                write!(f, "default_retry_me_else {}", o),
-            &BuiltInInstruction::DefaultSetCutPoint(r) =>
-                write!(f, "default_set_cp {}", r),
-            &BuiltInInstruction::DefaultTrustMe =>
-                write!(f, "default_trust_me"),
             &BuiltInInstruction::InstallInferenceCounter(r1, r2, r3) =>
                 write!(f, "install_inference_counter {}, {}, {}", r1, r2, r3),
-            &BuiltInInstruction::EraseBall =>
-                write!(f, "erase_ball"),
-            &BuiltInInstruction::Fail =>
-                write!(f, "false"),
             &BuiltInInstruction::GetArg(false) =>
                 write!(f, "get_arg_call X1, X2, X3"),
             &BuiltInInstruction::GetArg(true) =>
                 write!(f, "get_arg_execute X1, X2, X3"),
-            &BuiltInInstruction::GetBall =>
-                write!(f, "get_ball X1"),
-            &BuiltInInstruction::GetCurrentBlock =>
-                write!(f, "get_current_block X1"),
-            &BuiltInInstruction::GetCutPoint(r) =>
-                write!(f, "get_cp {}", r),
             &BuiltInInstruction::InferenceLevel(r1, r2) =>
                 write!(f, "inference_level {}, {}", r1, r2),
             &BuiltInInstruction::InstallCleaner =>
                 write!(f, "install_cleaner"),
-            &BuiltInInstruction::InstallNewBlock =>
-                write!(f, "install_new_block"),
             &BuiltInInstruction::RemoveCallPolicyCheck =>
                 write!(f, "remove_call_policy_check"),
             &BuiltInInstruction::RemoveInferenceCounter(r1, r2) =>
                 write!(f, "remove_inference_counter {}, {}", r1, r2),            
-            &BuiltInInstruction::ResetBlock =>
-                write!(f, "reset_block"),
             &BuiltInInstruction::RestoreCutPolicy =>
                 write!(f, "restore_cut_point"),
-            &BuiltInInstruction::SetBall =>
-                write!(f, "set_ball"),
             &BuiltInInstruction::SetCutPoint(r) =>
                 write!(f, "set_cp {}", r),
-            &BuiltInInstruction::Succeed =>
-                write!(f, "true"),
-            &BuiltInInstruction::UnwindStack =>
-                write!(f, "unwind_stack"),
-            &BuiltInInstruction::Unify =>
-                write!(f, "unify"),
         }
     }
 }
index 55d22ed975763d21c86911248e97970a3c793019..74ac779a3f1ae47496585a00bfd35b801626f4b6 100644 (file)
@@ -1,10 +1,10 @@
 use prolog::and_stack::*;
 use prolog::ast::*;
 use prolog::copier::*;
+use prolog::heap_print::*;
 use prolog::machine::machine_errors::MachineStub;
 use prolog::num::{BigInt, BigUint, Zero, One};
 use prolog::or_stack::*;
-use prolog::heap_print::*;
 use prolog::tabled_rc::*;
 
 use downcast::Any;
@@ -227,56 +227,6 @@ pub struct MachineState {
 pub(crate) type CallResult = Result<(), Vec<HeapCellValue>>;
 
 pub(crate) trait CallPolicy: Any {
-    fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName,
-                    arity: usize, idx: CodeIndex, lco: bool)
-                    -> CallResult
-    {
-        if lco {
-            self.try_execute(machine_st, name, arity, idx)
-        } else {
-            self.try_call(machine_st, name, arity, idx)
-        }
-    }
-
-    fn try_call(&mut self, machine_st: &mut MachineState, name: ClauseName,
-                arity: usize, idx: CodeIndex)
-                -> CallResult
-    {
-        match idx.0.borrow().0 {
-            IndexPtr::Undefined =>
-                return Err(machine_st.existence_error(name, arity)),
-            IndexPtr::Index(compiled_tl_index) => {
-                let module_name = idx.0.borrow().1.clone();
-
-                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  = dir_entry!(compiled_tl_index, module_name);
-            }
-        }
-
-        Ok(())
-    }
-
-    fn try_execute<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName,
-                       arity: usize, idx: CodeIndex)
-                       -> CallResult
-    {
-        match idx.0.borrow().0 {
-            IndexPtr::Undefined =>
-                return Err(machine_st.existence_error(name, arity)),
-            IndexPtr::Index(compiled_tl_index) => {
-                let module_name = idx.0.borrow().1.clone();
-
-                machine_st.num_of_args = arity;
-                machine_st.b0 = machine_st.b;
-                machine_st.p  = dir_entry!(compiled_tl_index, module_name);
-            }
-        }
-
-        Ok(())
-    }
-
     fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
     {
         let b = machine_st.b - 1;
@@ -400,124 +350,54 @@ pub(crate) trait CallPolicy: Any {
         Ok(())
     }
 
-    fn call_n<'a>(&mut self, machine_st: &mut MachineState, mut arity: usize,
-                  code_dirs: CodeDirs<'a>, lco: bool)
-                  -> CallResult
+    fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName, arity: usize,
+                    idx: CodeIndex, lco: bool)
+                    -> CallResult
     {
-        while let Some((name, inner_arity)) = machine_st.setup_call_n(arity) {
-            let user = clause_name!("user");
+        if lco {
+            self.try_execute(machine_st, name, arity, idx)
+        } else {
+            self.try_call(machine_st, name, arity, idx)
+        }
+    }
 
-            match ClauseType::from(name.clone(), inner_arity, None) {
-                ClauseType::CallN => {
-                    machine_st.handle_internal_call_n(inner_arity);
-                    
-                    if machine_st.fail {
-                        return Ok(());
-                    }
-                    
-                    arity = inner_arity;
-                    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(), inner_arity, user) {
-                        self.context_call(machine_st, name, inner_arity, idx, lco)?;
-                    } else {
-                        return Err(machine_st.existence_error(name, inner_arity));
-                    }
-            };
+    fn try_call(&mut self, machine_st: &mut MachineState, name: ClauseName,
+                arity: usize, idx: CodeIndex)
+                -> CallResult
+    {
+        match idx.0.borrow().0 {
+            IndexPtr::Undefined =>
+                return Err(machine_st.existence_error(name, arity)),
+            IndexPtr::Index(compiled_tl_index) => {
+                let module_name = idx.0.borrow().1.clone();
 
-            break;
+                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  = dir_entry!(compiled_tl_index, module_name);
+            }
         }
 
         Ok(())
     }
 
-    fn system_call(&mut self, machine_st: &mut MachineState, ct: &SystemClauseType) -> CallResult
+    fn try_execute<'a>(&mut self, machine_st: &mut MachineState, name: ClauseName,
+                       arity: usize, idx: CodeIndex)
+                       -> CallResult
     {
-        match ct {
-            &SystemClauseType::CleanUpBlock => {
-                let nb = machine_st.store(machine_st.deref(machine_st[temp_v!(1)].clone()));
-
-                match nb {
-                    Addr::Con(Constant::Usize(nb)) => {
-                        let b = machine_st.b - 1;
-
-                        if nb > 0 && machine_st.or_stack[b].b == nb {
-                            machine_st.b = machine_st.or_stack[nb - 1].b;
-                            machine_st.or_stack.truncate(machine_st.b);
-                        }                        
-                    },
-                    _ => machine_st.fail = true
-                };
-
-                Ok(())
-            },
-            &SystemClauseType::EraseBall => {
-                machine_st.ball.reset();
-                Ok(())
-            },
-            &SystemClauseType::Fail => {
-                machine_st.fail = true;
-                Ok(())
-            },
-            &SystemClauseType::GetBall => {
-                let addr = machine_st.store(machine_st.deref(machine_st[temp_v!(1)].clone()));
-                let h = machine_st.heap.h;
-
-                if machine_st.ball.stub.len() > 0 {
-                    machine_st.copy_and_align_ball_to_heap();
-                } else {
-                    machine_st.fail = true;
-                    return Ok(());
-                }
-
-                let ball = machine_st.heap[h].as_addr(h);
-
-                match addr.as_var() {
-                    Some(r) => machine_st.bind(r, ball),                    
-                    _ => machine_st.fail = true
-                };
-
-                Ok(())
-            },
-            &SystemClauseType::GetCurrentBlock => {
-                let c = Constant::Usize(machine_st.block);
-                let addr = machine_st[temp_v!(1)].clone();
-
-                machine_st.write_constant_to_var(addr, c);
-                Ok(())
-            },
-            &SystemClauseType::InstallNewBlock => {
-                machine_st.block = machine_st.b;
-                
-                let c = Constant::Usize(machine_st.block);
-                let addr = machine_st[temp_v!(1)].clone();
+        match idx.0.borrow().0 {
+            IndexPtr::Undefined =>
+                return Err(machine_st.existence_error(name, arity)),
+            IndexPtr::Index(compiled_tl_index) => {
+                let module_name = idx.0.borrow().1.clone();
 
-                machine_st.write_constant_to_var(addr, c);
-                Ok(())
-            },
-            &SystemClauseType::ResetBlock => {
-                let addr = machine_st.deref(machine_st[temp_v!(1)].clone());
-                machine_st.reset_block(addr);
-                Ok(())
-            },
-            &SystemClauseType::SetBall => {
-                machine_st.set_ball();
-                Ok(())
-            },
-            &SystemClauseType::SkipMaxList => {
-                machine_st.skip_max_list()?;
-                Ok(())
-            },
-            &SystemClauseType::UnwindStack => {
-                machine_st.unwind_stack();
-                Ok(())
+                machine_st.num_of_args = arity;
+                machine_st.b0 = machine_st.b;
+                machine_st.p  = dir_entry!(compiled_tl_index, module_name);
             }
         }
+
+        Ok(())
     }
 
     fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType, lco: bool)
@@ -619,7 +499,7 @@ pub(crate) trait CallPolicy: Any {
 
                 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);
 
@@ -634,12 +514,95 @@ pub(crate) trait CallPolicy: Any {
 
                 Ok(())
             },
-            &BuiltInClauseType::System(ref ct) => {
-                self.system_call(machine_st, ct)?;
-                return_from_clause!(lco, machine_st)
-            }
         }
     }
+
+    fn call_n<'a>(&mut self, machine_st: &mut MachineState, mut arity: usize,
+                  code_dirs: CodeDirs<'a>, lco: bool)
+                  -> CallResult
+    {
+        while let Some((name, inner_arity)) = machine_st.setup_call_n(arity) {
+            let user = clause_name!("user");
+
+            match ClauseType::from(name.clone(), inner_arity, None) {
+                ClauseType::CallN => {
+                    machine_st.handle_internal_call_n(inner_arity);
+
+                    if machine_st.fail {
+                        return Ok(());
+                    }
+
+                    arity = inner_arity;
+                    continue;
+                },
+                ClauseType::BuiltIn(built_in) =>
+                    machine_st.setup_built_in_call(built_in),
+                ClauseType::Inlined(inlined) =>
+                    machine_st.execute_inlined(&inlined),
+                ClauseType::Op(..) | ClauseType::Named(..) =>
+                    if let Some(idx) = code_dirs.get(name.clone(), inner_arity, user) {
+                        self.context_call(machine_st, name, inner_arity, idx, lco)?;
+                    } else {
+                        return Err(machine_st.existence_error(name, inner_arity));
+                    },
+                ClauseType::System(ct) =>
+                    return machine_st.system_call(&ct)
+            };
+
+            break;
+        }
+
+        Ok(())
+    }
+}
+
+impl CallPolicy for CallWithInferenceLimitCallPolicy {
+    fn context_call(&mut self, machine_st: &mut MachineState, name: ClauseName,
+                    arity: usize, idx: CodeIndex, lco: bool)
+                    -> CallResult
+    {
+        self.prev_policy.context_call(machine_st, name, arity, idx, lco)?;
+        self.increment()
+    }
+
+    fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
+    {
+        self.prev_policy.retry_me_else(machine_st, offset)?;
+        self.increment()
+    }
+
+    fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
+    {
+        self.prev_policy.retry(machine_st, offset)?;
+        self.increment()
+    }
+
+    fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult
+    {
+        self.prev_policy.trust_me(machine_st)?;
+        self.increment()
+    }
+
+    fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
+    {
+        self.prev_policy.trust(machine_st, offset)?;
+        self.increment()
+    }
+
+    fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType, lco: bool)
+                        -> CallResult
+    {
+        self.prev_policy.call_builtin(machine_st, ct, lco)?;
+        self.increment()
+    }
+
+    fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize, code_dirs: CodeDirs<'a>,
+                  lco: bool)
+                  -> CallResult
+    {
+        self.prev_policy.call_n(machine_st, arity, code_dirs, lco)?;
+        self.increment()
+    }
 }
 
 downcast!(CallPolicy);
@@ -714,39 +677,6 @@ impl CallWithInferenceLimitCallPolicy {
     }
 }
 
-impl CallPolicy for CallWithInferenceLimitCallPolicy {
-    fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
-    {
-        self.prev_policy.retry_me_else(machine_st, offset)?;
-        self.increment()
-    }
-
-    fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
-    {
-        self.prev_policy.retry(machine_st, offset)?;
-        self.increment()
-    }
-
-    fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult
-    {
-        self.prev_policy.trust_me(machine_st)?;
-        self.increment()
-    }
-
-    fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
-    {
-        self.prev_policy.trust(machine_st, offset)?;
-        self.increment()
-    }
-
-    fn call_builtin<'a>(&mut self, machine_st: &mut MachineState, ct: &BuiltInClauseType, lco: bool)
-                        -> CallResult
-    {
-        self.prev_policy.call_builtin(machine_st, ct, lco)?;
-        self.increment()
-    }
-}
-
 pub(crate) trait CutPolicy: Any {
     fn cut(&mut self, &mut MachineState, RegType);
 }
index 1e368c5ff0d00dda4926786db15cef600bf32def..c81551207da004a6620ff950209d5cdf60d4b59e 100644 (file)
@@ -296,7 +296,7 @@ impl MachineState {
 
     fn get_number(&self, at: &ArithmeticTerm) -> Result<Number, MachineError> {
         match at {
-            &ArithmeticTerm::Reg(r) =>        self.arith_eval_by_metacall(r),
+            &ArithmeticTerm::Reg(r)        => self.arith_eval_by_metacall(r),
             &ArithmeticTerm::Interm(i)     => Ok(self.interms[i-1].clone()),
             &ArithmeticTerm::Number(ref n) => Ok(n.clone()),
         }
@@ -1319,9 +1319,9 @@ impl MachineState {
 
     pub(super) fn execute_inlined(&mut self, inlined: &InlinedClauseType) {
         match inlined {
-            &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));
+            &InlinedClauseType::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));
 
                 self.compare_numbers(cmp, n1, n2);
             },
@@ -1400,34 +1400,13 @@ impl MachineState {
         }
     }
 
-    pub(super) fn execute_built_in_instr<'a>(&mut self, code_dirs: CodeDirs<'a>,
-                                             call_policy: &mut Box<CallPolicy>,
-                                             cut_policy:  &mut Box<CutPolicy>,
-                                             instr: &BuiltInInstruction)
+    pub(super)
+    fn execute_built_in_instr<'a>(&mut self, code_dirs: CodeDirs<'a>,
+                                  call_policy: &mut Box<CallPolicy>,
+                                  cut_policy:  &mut Box<CutPolicy>,
+                                  instr: &BuiltInInstruction)
     {
-        match instr {
-            &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));
-
-                self.compare_numbers(cmp, n1, n2);
-            },
-            &BuiltInInstruction::DefaultRetryMeElse(o) => {
-                let mut call_policy = DefaultCallPolicy {};
-                try_or_fail!(self, call_policy.retry_me_else(self, o));
-            },
-            &BuiltInInstruction::DefaultSetCutPoint(r) => {
-                let mut cut_policy = DefaultCutPolicy {};
-                cut_policy.cut(self, r);
-            },
-            &BuiltInInstruction::DefaultTrustMe => {
-                let mut call_policy = DefaultCallPolicy {};
-                try_or_fail!(self, call_policy.trust_me(self));
-            },
-            &BuiltInInstruction::EraseBall => {
-                self.ball.reset();
-                self.p += 1;
-            },
+        match instr {            
             &BuiltInInstruction::GetArg(lco) =>
                 try_or_fail!(self, {
                     let val = self.try_get_arg();
@@ -1440,40 +1419,6 @@ impl MachineState {
 
                     val
                 }),
-            &BuiltInInstruction::GetCurrentBlock => {
-                let c = Constant::Usize(self.block);
-                let addr = self[temp_v!(1)].clone();
-
-                self.write_constant_to_var(addr, c);
-                self.p += 1;
-            },
-            &BuiltInInstruction::GetBall => {
-                let addr = self.store(self.deref(self[temp_v!(1)].clone()));
-                let h = self.heap.h;
-
-                if self.ball.stub.len() > 0 {
-                    self.copy_and_align_ball_to_heap();
-                } else {
-                    self.fail = true;
-                    return;
-                }
-
-                let ball = self.heap[h].as_addr(h);
-
-                match addr.as_var() {
-                    Some(r) => {
-                        self.bind(r, ball);
-                        self.p += 1;
-                    },
-                    _ => self.fail = true
-                };
-            },
-            &BuiltInInstruction::GetCutPoint(r) => {
-                let c = Constant::Usize(self.b);
-                self[r] = Addr::Con(c);
-
-                self.p += 1;
-            },
             &BuiltInInstruction::InferenceLevel(r1, r2) => { // X1 = R, X2 = B.
                 let a1 = self[r1].clone();
                 let a2 = self.store(self.deref(self[r2].clone()));
@@ -1597,57 +1542,8 @@ impl MachineState {
 
                 self.p += 1;
             },
-            &BuiltInInstruction::SetBall => {
-                self.set_ball();
-                self.p += 1;
-            },
             &BuiltInInstruction::SetCutPoint(r) =>
                 cut_policy.cut(self, r),
-            &BuiltInInstruction::CleanUpBlock => {
-                let nb = self.store(self.deref(self[temp_v!(1)].clone()));
-
-                match nb {
-                    Addr::Con(Constant::Usize(nb)) => {
-                        let b = self.b - 1;
-
-                        if nb > 0 && self.or_stack[b].b == nb {
-                            self.b = self.or_stack[nb - 1].b;
-                            self.or_stack.truncate(self.b);
-                        }
-
-                        self.p += 1;
-                    },
-                    _ => self.fail = true
-                };
-            },
-            &BuiltInInstruction::InstallNewBlock => {
-                self.block = self.b;
-                let c = Constant::Usize(self.block);
-                let addr = self[temp_v!(1)].clone();
-
-                self.write_constant_to_var(addr, c);
-                self.p += 1;
-            },
-            &BuiltInInstruction::ResetBlock => {
-                let addr = self.deref(self[temp_v!(1)].clone());
-                self.reset_block(addr);
-            },
-            &BuiltInInstruction::UnwindStack =>
-                self.unwind_stack(),
-            &BuiltInInstruction::Fail => {
-                self.fail = true;
-                self.p += 1;
-            },
-            &BuiltInInstruction::Succeed => {
-                self.p += 1;
-            },
-            &BuiltInInstruction::Unify => {
-                let a1 = self[temp_v!(1)].clone();
-                let a2 = self[temp_v!(2)].clone();
-
-                self.unify(a1, a2);
-                self.p += 1;
-            },
         };
     }
 
@@ -1920,7 +1816,7 @@ impl MachineState {
         false
     }
 
-    pub(super) fn setup_built_in_call(&mut self, ct: BuiltInClauseType, lco: bool)
+    pub(super) fn setup_built_in_call(&mut self, ct: BuiltInClauseType)
     {        
         self.num_of_args = ct.arity();
         self.b0 = self.b;
@@ -1964,8 +1860,8 @@ impl MachineState {
         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>,
@@ -1978,12 +1874,21 @@ impl MachineState {
                 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) =>
+            &ControlInstruction::CallClause(ClauseType::Inlined(ref ct), ..) =>
                 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::CallClause(ClauseType::System(ref ct), arity, _, lco) => {
+                try_or_fail!(self, self.system_call(ct));
+
+                if lco {
+                    self.p = CodePtr::Local(self.cp.clone());
+                } else {
+                    self.p += 1;
+                }
+            },
             &ControlInstruction::CheckCpExecute => {
                 let a = self.store(self.deref(self[temp_v!(2)].clone()));
 
@@ -2025,8 +1930,6 @@ impl MachineState {
 
                 self.fail = true;
             },
-            &ControlInstruction::Goto(p, 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));
@@ -2048,16 +1951,6 @@ impl MachineState {
         };
     }
 
-    pub(super) fn goto_ptr(&mut self, p: CodePtr, arity: usize, lco:bool) {
-        if !lco {
-            self.cp.assign_if_local(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 163c0b16e43283f52242716a29a7f329e031e687..425ee1e439ec72230dbb29e7c4aee6850bcb7617 100644 (file)
@@ -234,8 +234,6 @@ impl Machine {
                 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))
         }
     }
 
index 1d1c55b15aa0bc025c0078d287cf7b93fdd95747..715969e78b3009e17037cd16406eb0262029b74a 100644 (file)
@@ -19,7 +19,7 @@ impl BrentAlgState {
     }
 }
 
-impl MachineState {    
+impl MachineState {
     // a step in Brent's algorithm.
     fn brents_alg_step(&self, brent_st: &mut BrentAlgState) -> Option<CycleSearchResult>
     {
@@ -54,8 +54,7 @@ impl MachineState {
     pub(super) fn detect_cycles_with_max(&self, max_steps: usize, addr: Addr) -> CycleSearchResult
     {
         let addr = self.store(self.deref(addr));
-
-        let mut hare = match addr {
+        let hare = match addr {
             Addr::Lis(offset) if max_steps > 0 => offset + 1,
             Addr::Lis(offset) => return CycleSearchResult::UntouchedList(offset),
             Addr::Con(Constant::EmptyList) => return CycleSearchResult::EmptyList,
@@ -63,7 +62,7 @@ impl MachineState {
         };
 
         let mut brent_st = BrentAlgState::new(hare);
-        
+
         loop {
             if brent_st.steps == max_steps {
                 return CycleSearchResult::PartialList(brent_st.steps, brent_st.hare);
@@ -78,22 +77,21 @@ impl MachineState {
     pub(super) fn detect_cycles(&self, addr: Addr) -> CycleSearchResult
     {
         let addr = self.store(self.deref(addr));
-
-        let mut hare = match addr {
+        let hare = match addr {
             Addr::Lis(offset) => offset + 1,
             Addr::Con(Constant::EmptyList) => return CycleSearchResult::EmptyList,
             _ => return CycleSearchResult::NotList
         };
 
         let mut brent_st = BrentAlgState::new(hare);
-        
+
         loop {
             if let Some(result) = self.brents_alg_step(&mut brent_st) {
                 return result;
             }
         }
     }
-    
+
     fn finalize_skip_max_list(&mut self, n: usize, addr: Addr) {
         let target_n = self[temp_v!(1)].clone();
         self.unify(Addr::Con(integer!(n)), target_n);
@@ -111,7 +109,7 @@ impl MachineState {
             Number::Integer(ref max_steps)
                 if max_steps.to_isize().map(|i| i >= -1).unwrap_or(false) => {
                     let n = self.store(self.deref(self[temp_v!(1)].clone()));
-                    
+
                     match n {
                         Addr::Con(Constant::Number(Number::Integer(ref n))) if n.is_zero() => {
                             let xs0 = self[temp_v!(3)].clone();
@@ -152,5 +150,97 @@ impl MachineState {
         };
 
         Ok(())
-    }    
+    }
+            
+    pub(super) fn system_call(&mut self, ct: &SystemClauseType) -> CallResult
+    {
+        match ct {
+            &SystemClauseType::CleanUpBlock => {
+                let nb = self.store(self.deref(self[temp_v!(1)].clone()));
+
+                match nb {
+                    Addr::Con(Constant::Usize(nb)) => {
+                        let b = self.b - 1;
+
+                        if nb > 0 && self.or_stack[b].b == nb {
+                            self.b = self.or_stack[nb - 1].b;
+                            self.or_stack.truncate(self.b);
+                        }
+                    },
+                    _ => self.fail = true
+                };
+
+                Ok(())
+            },
+            &SystemClauseType::EraseBall => {
+                self.ball.reset();
+                Ok(())
+            },
+            &SystemClauseType::Fail => {
+                self.fail = true;
+                Ok(())
+            },
+            &SystemClauseType::GetBall => {
+                let addr = self.store(self.deref(self[temp_v!(1)].clone()));
+                let h = self.heap.h;
+
+                if self.ball.stub.len() > 0 {
+                    self.copy_and_align_ball_to_heap();
+                } else {
+                    self.fail = true;
+                    return Ok(());
+                }
+
+                let ball = self.heap[h].as_addr(h);
+
+                match addr.as_var() {
+                    Some(r) => self.bind(r, ball),
+                    _ => self.fail = true
+                };
+
+                Ok(())
+            },
+            &SystemClauseType::GetCurrentBlock => {
+                let c = Constant::Usize(self.block);
+                let addr = self[temp_v!(1)].clone();
+
+                self.write_constant_to_var(addr, c);
+                Ok(())
+            },
+            &SystemClauseType::GetCutPoint(r) => {
+                let c = Constant::Usize(self.b);
+                self[r] = Addr::Con(c);
+                Ok(())
+            },
+            &SystemClauseType::InstallNewBlock => {
+                self.block = self.b;
+
+                let c = Constant::Usize(self.block);
+                let addr = self[temp_v!(1)].clone();
+
+                self.write_constant_to_var(addr, c);
+                Ok(())
+            },
+            &SystemClauseType::ResetBlock => {
+                let addr = self.deref(self[temp_v!(1)].clone());
+                self.reset_block(addr);
+                Ok(())
+            },
+            &SystemClauseType::SetBall => {
+                self.set_ball();
+                Ok(())
+            },            
+            &SystemClauseType::SkipMaxList => {
+                self.skip_max_list()?;
+                Ok(())
+            },
+            &SystemClauseType::Succeed => {
+                Ok(())
+            },
+            &SystemClauseType::UnwindStack => {
+                self.unwind_stack();
+                Ok(())
+            }
+        }
+    }
 }
index a665add265dfcb4447d2b37976f62bcb3770e8fc..723b02c78ad4783d539b3c785d7d399d2c2e3a4b 100644 (file)
@@ -19,12 +19,6 @@ macro_rules! atom {
     )
 }
 
-macro_rules! compare_number_instr {
-    ($cmp: expr, $at_1: expr, $at_2: expr) => (
-        Line::BuiltIn(BuiltInInstruction::CompareNumber($cmp, $at_1, $at_2))
-    )
-}
-
 macro_rules! interm {
     ($n: expr) => (
         ArithmeticTerm::Interm($n)
@@ -156,18 +150,6 @@ macro_rules! is_call {
     )
 }
 
-macro_rules! fail {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::Fail)
-    )
-}
-
-macro_rules! succeed {
-    () => (
-        Line::BuiltIn(BuiltInInstruction::Succeed)
-    )
-}
-
 macro_rules! set_cp {
     ($r:expr) => (
         Line::BuiltIn(BuiltInInstruction::SetCutPoint($r))
@@ -192,6 +174,25 @@ macro_rules! rc_atom {
     )
 }
 
+macro_rules! succeed {
+    () => (
+        call_clause!(ClauseType::System(SystemClauseType::Succeed), 0, 0)
+    )
+}
+
+macro_rules! fail {
+    () => (
+        call_clause!(ClauseType::System(SystemClauseType::Fail), 0, 0)
+    )
+}
+
+macro_rules! compare_number_instr {
+    ($cmp: expr, $at_1: expr, $at_2: expr) => {{
+        let ct = ClauseType::Inlined(InlinedClauseType::CompareNumber($cmp, $at_1, $at_2));
+        call_clause!(ct, 2, 0)
+    }}
+}
+
 macro_rules! jmp_call {
     ($arity:expr, $offset:expr, $pvs:expr) => (
         Line::Control(ControlInstruction::JmpBy($arity, $offset, $pvs, false))
@@ -250,3 +251,4 @@ macro_rules! top_level_code_ptr {
         CodePtr::Local(LocalCodePtr::TopLevel($p, $q_sz))
     )
 }
+