]> Repositorios git - scryer-prolog.git/commitdiff
inline comparison instructions.
authorMark Thom <[email protected]>
Tue, 5 Dec 2017 04:01:23 +0000 (21:01 -0700)
committerMark Thom <[email protected]>
Tue, 5 Dec 2017 04:01:23 +0000 (21:01 -0700)
src/prolog/arithmetic.rs
src/prolog/ast.rs
src/prolog/codegen.rs
src/prolog/io.rs
src/prolog/iterators.rs
src/prolog/machine.rs
src/prolog/macros.rs
src/prolog/parser

index 8f00940ed58141186fd3d44543d8c2606e642b79..b80ccedc3edf9cc0830b55d51ee15b2f8703be06 100644 (file)
@@ -8,6 +8,8 @@ pub struct ArithExprIterator<'a> {
     state_stack: Vec<IteratorState<'a>>
 }
 
+pub type ArithCont = (Code, Option<ArithmeticTerm>);
+
 impl<'a> ArithExprIterator<'a> {
     fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
         self.state_stack.push(IteratorState::to_state(lvl, term));
@@ -73,14 +75,13 @@ impl<'a> Iterator for ArithExprIterator<'a> {
 
 pub struct ArithmeticEvaluator<'a> {
     bindings: &'a AllocVarDict<'a>,
-    target_int: usize,
     interm: Vec<ArithmeticTerm>,
     interm_c: usize
 }
 
 impl<'a> ArithmeticEvaluator<'a> {
     pub fn new(bindings: &'a AllocVarDict<'a>, target_int: usize) -> Self {
-        ArithmeticEvaluator { bindings, target_int, interm: Vec::new(), interm_c: target_int }
+        ArithmeticEvaluator { bindings, interm: Vec::new(), interm_c: target_int }
     }
 
     fn get_unary_instr(name: &Atom, a1: ArithmeticTerm, t: usize)
@@ -180,7 +181,7 @@ impl<'a> ArithmeticEvaluator<'a> {
         Ok(())
     }
 
-    pub fn eval(&mut self, term: &Term) -> Result<Code, ArithmeticError> {
+    pub fn eval(&mut self, term: &Term) -> Result<ArithCont, ArithmeticError> {
         let mut code = Vec::new();
 
         for term_ref in term.arith_expr_iter()? {
@@ -212,18 +213,6 @@ impl<'a> ArithmeticEvaluator<'a> {
             }
         }
 
-
-        if let Some(arith_term) = self.interm.pop() {
-            let t = self.target_int;
-            
-            match arith_term {
-                n @ ArithmeticTerm::Integer(_) => code.push(move_at!(n, t)),                
-                n @ ArithmeticTerm::Float(_)   => code.push(move_at!(n, t)),
-                r @ ArithmeticTerm::Reg(_)     => code.push(move_at!(r, t)),
-                _ => {}
-            };
-        }
-
-        Ok(code)
+        Ok((code, self.interm.pop()))
     }
 }
index 9578467b8e3bf04a1de7780f95a6f9e2188cf00a..77d5ca02dc2511493bfad272b70b2f18e08dae75 100644 (file)
@@ -315,6 +315,7 @@ pub enum Term {
 }
 
 pub enum InlinedQueryTerm {
+    CompareNumber(CompareNumberQT, Vec<Box<Term>>),
     IsAtomic(Vec<Box<Term>>),
     IsVar(Vec<Box<Term>>)
 }
@@ -322,8 +323,9 @@ pub enum InlinedQueryTerm {
 impl InlinedQueryTerm {
     pub fn arity(&self) -> usize {
         match self {
+            &InlinedQueryTerm::CompareNumber(_, _) => 2,
             &InlinedQueryTerm::IsAtomic(_) => 1,
-            &InlinedQueryTerm::IsVar(_) => 1
+            &InlinedQueryTerm::IsVar(_) => 1                
         }
     }
 }
@@ -341,7 +343,6 @@ pub enum CompareNumberQT {
 pub enum QueryTerm {
     CallN(Vec<Box<Term>>),
     Catch(Vec<Box<Term>>),
-    CompareNumber(CompareNumberQT, Vec<Box<Term>>),
     Cut,
     Is(Vec<Box<Term>>),
     Inlined(InlinedQueryTerm),
@@ -353,7 +354,6 @@ impl QueryTerm {
     pub fn arity(&self) -> usize {
         match self {
             &QueryTerm::Catch(_) => 3,
-            &QueryTerm::CompareNumber(_, _) => 2,
             &QueryTerm::Throw(_) => 1,
             &QueryTerm::Inlined(ref term) => term.arity(),
             &QueryTerm::Is(_) => 2,
@@ -709,6 +709,7 @@ pub enum ArithmeticInstruction {
 
 pub enum BuiltInInstruction {
     CleanUpBlock,
+    CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm),
     DuplicateTerm,
     EraseBall,
     Fail,
@@ -735,10 +736,8 @@ pub enum ControlInstruction {
     Execute(Atom, usize),
     ExecuteN(usize),
     Goto(usize, usize), // p, arity.
-    CompareNumberCall(CompareNumberQT),
-    CompareNumberExecute(CompareNumberQT),    
-    IsCall(RegType),
-    IsExecute(RegType),
+    IsCall(RegType, ArithmeticTerm),
+    IsExecute(RegType, ArithmeticTerm),
     Proceed,
     ThrowCall,
     ThrowExecute,
@@ -757,8 +756,8 @@ impl ControlInstruction {
             &ControlInstruction::ThrowExecute => true,
             &ControlInstruction::Goto(_, _) => true,
             &ControlInstruction::Proceed => true,
-            &ControlInstruction::IsCall(_) => true,
-            &ControlInstruction::IsExecute(_) => true,
+            &ControlInstruction::IsCall(_, _) => true,
+            &ControlInstruction::IsExecute(_, _) => true,
             _ => false
         }
     }
@@ -790,7 +789,6 @@ pub enum FactInstruction {
 }
 
 pub enum QueryInstruction {
-    MoveArithmeticTerm(ArithmeticTerm, usize),
     GetVariable(RegType, usize),
     PutConstant(Level, Constant, RegType),
     PutList(Level, RegType),
index c1784829171efa132d2941f179ec18763296499c..2dac5839b8d44994328b6d3cf004849b8352d265 100644 (file)
@@ -230,12 +230,16 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
         ConjunctInfo::new(vs, num_of_chunks, has_deep_cut)
     }
 
-    fn add_conditional_call_inlined(term: &InlinedQueryTerm, code: &mut Code)
+    fn add_conditional_call_inlined(_: &InlinedQueryTerm, code: &mut Code)
     {
+        code.push(proceed!());
+        
+        /*
         match term {
             &InlinedQueryTerm::IsAtomic(_) | &InlinedQueryTerm::IsVar(_) =>
                 code.push(proceed!())            
         };
+         */
     }
     
     fn add_conditional_call(code: &mut Code, qt: &QueryTerm, pvs: usize)
@@ -276,10 +280,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                     *ctrl = ControlInstruction::Execute(name, arity),
                 ControlInstruction::CallN(arity) =>
                     *ctrl = ControlInstruction::ExecuteN(arity),
-                ControlInstruction::CompareNumberCall(cmp) =>
-                    *ctrl = ControlInstruction::CompareNumberExecute(cmp),
-                ControlInstruction::IsCall(r) =>
-                    *ctrl = ControlInstruction::IsExecute(r),
+                ControlInstruction::IsCall(r, at) =>
+                    *ctrl = ControlInstruction::IsExecute(r, at),
                 ControlInstruction::CatchCall =>
                     *ctrl = ControlInstruction::CatchExecute,
                 ControlInstruction::ThrowCall =>
@@ -293,21 +295,33 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
     }
     
     fn compile_inlined(&mut self, term: &'a InlinedQueryTerm, term_loc: GenContext, code: &mut Code)
+                       -> Result<(), ParserError>
     {
         match term {
+            &InlinedQueryTerm::CompareNumber(cmp, ref terms) => {
+                let (mut lcode, at_1) = self.call_arith_eval(terms[0].as_ref(), 1)?;
+                let (mut rcode, at_2) = self.call_arith_eval(terms[1].as_ref(), 2)?;
+
+                code.append(&mut lcode);
+                code.append(&mut rcode);
+                
+                code.push(compare_number_instr!(cmp,
+                                                at_1.unwrap_or(interm!(1)),
+                                                at_2.unwrap_or(interm!(2))));            
+            },
             &InlinedQueryTerm::IsAtomic(ref inner_term) =>
-            match inner_term[0].as_ref() {
-                &Term::AnonVar | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
-                    code.push(fail!());
-                },
-                &Term::Constant(_, _) => {
-                    code.push(succeed!());
-                },
-                &Term::Var(ref vr, ref name) => {
-                    let r = self.mark_non_callable(name, 1, term_loc, vr, code);
-                    code.push(is_atomic!(r));
-                }
-            },            
+                match inner_term[0].as_ref() {
+                    &Term::AnonVar | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
+                        code.push(fail!());
+                    },
+                    &Term::Constant(_, _) => {
+                        code.push(succeed!());
+                    },
+                    &Term::Var(ref vr, ref name) => {
+                        let r = self.mark_non_callable(name, 1, term_loc, vr, code);
+                        code.push(is_atomic!(r));
+                    }
+                },            
             &InlinedQueryTerm::IsVar(ref inner_term) =>
                 match inner_term[0].as_ref() {
                     &Term::Constant(_, _) | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
@@ -322,9 +336,12 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                     }
                 }
         }
+
+        Ok(())
     }
     
-    fn call_arith_eval(&self, term: &'a Term, target_int: usize) -> Result<Code, ArithmeticError> {
+    fn call_arith_eval(&self, term: &'a Term, target_int: usize) -> Result<ArithCont, ArithmeticError>
+    {
         let mut evaluator = ArithmeticEvaluator::new(self.marker.bindings(), target_int);
         evaluator.eval(term)
     }
@@ -360,10 +377,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                         });
                     },
                     &QueryTerm::Inlined(ref term) =>
-                        self.compile_inlined(term, term_loc, code),
+                        self.compile_inlined(term, term_loc, code)?,                    
                     &QueryTerm::Is(ref terms) => {
-                        let mut arith_code = self.call_arith_eval(terms[1].as_ref(), 1)?;
-                        code.append(&mut arith_code);
+                        let (mut acode, at) = try!(self.call_arith_eval(terms[1].as_ref(), 1));
+                        code.append(&mut acode);
 
                         match terms[0].as_ref() {
                             &Term::Var(ref vr, ref name) => {
@@ -373,35 +390,26 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                                                                vr,
                                                                code);
 
-                                code.push(is_call!(r));
+                                code.push(is_call!(r, at.unwrap_or(interm!(1))));
                             },
                             &Term::Constant(_, Constant::Float(fl)) => {
                                 code.push(query![put_constant!(Level::Shallow,
                                                                Constant::Float(fl),
                                                                temp_v!(1))]);
-                                code.push(is_call!(temp_v!(1)));
+                                code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))));
                             },
                             &Term::Constant(_, Constant::Integer(ref bi)) => {
                                 let bi = bi.clone();
                                 code.push(query![put_constant!(Level::Shallow,
                                                                Constant::Integer(bi),
                                                                temp_v!(1))]);
-                                code.push(is_call!(temp_v!(1)));
+                                code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))));
                             },
                             _ => {
                                 code.push(fail!());
                             }
                         }
-                    },
-                    &QueryTerm::CompareNumber(cmp, ref terms) => {
-                        let mut larith_code = self.call_arith_eval(terms[0].as_ref(), 1)?;
-                        let mut rarith_code = self.call_arith_eval(terms[1].as_ref(), 2)?;
-
-                        code.append(&mut larith_code);
-                        code.append(&mut rarith_code);
-
-                        code.push(compare_number_call!(cmp));
-                    },
+                    },                    
                     _ if chunk_num == 0 => {
                         self.marker.reset_arg(term.arity());
 
index ccede0414b1073487acf2b9cb682ea650d00085a..298ecb3542e899a6fc872a4a280388586947dcba 100644 (file)
@@ -46,8 +46,6 @@ impl fmt::Display for FactInstruction {
 impl fmt::Display for QueryInstruction {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
-            &QueryInstruction::MoveArithmeticTerm(ref at, ref r) =>
-                write!(f, "move_arithmetic_term {}, {}", at, r),
             &QueryInstruction::GetVariable(ref x, ref a) =>
                 write!(f, "query:get_variable {}, A{}", x, a),
             &QueryInstruction::PutConstant(Level::Shallow, ref constant, ref r) =>
@@ -107,11 +105,7 @@ impl fmt::Display for ControlInstruction {
             &ControlInstruction::CatchCall =>
                 write!(f, "call_catch"),
             &ControlInstruction::CatchExecute =>
-                write!(f, "execute_catch"),
-            &ControlInstruction::CompareNumberCall(cmp) =>
-                write!(f, "n_compare_call {}", cmp),
-            &ControlInstruction::CompareNumberExecute(cmp) =>
-                write!(f, "n_compare_execute {}", cmp),
+                write!(f, "execute_catch"),            
             &ControlInstruction::ExecuteN(arity) =>
                 write!(f, "execute_N {}", arity),
             &ControlInstruction::Deallocate =>
@@ -126,10 +120,10 @@ impl fmt::Display for ControlInstruction {
                 write!(f, "call_throw"),
             &ControlInstruction::ThrowExecute =>
                 write!(f, "execute_throw"),
-            &ControlInstruction::IsCall(r) =>
-                write!(f, "is_call {}", r),
-            &ControlInstruction::IsExecute(r) =>
-                write!(f, "is_execute {}", r),
+            &ControlInstruction::IsCall(r, ref at) =>
+                write!(f, "is_call {}, {}", r, at),
+            &ControlInstruction::IsExecute(r, ref at) =>
+                write!(f, "is_execute {}, {}", r, at),
         }
     }
 }
@@ -153,6 +147,8 @@ impl fmt::Display for BuiltInInstruction {
         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::DuplicateTerm =>
                 write!(f, "duplicate_term X1"),
             &BuiltInInstruction::EraseBall =>
index 9471619acae723f4a6019105e2cc4847d981474d..62002207483f4b7e21068115211bbd5b88b174cf 100644 (file)
@@ -40,9 +40,10 @@ impl<'a> QueryIterator<'a> {
                 let state = IteratorState::Clause(0, ClauseType::Catch, terms);
                 QueryIterator { state_stack: vec![state] }
             },
-            &QueryTerm::CompareNumber(_, ref terms) | &QueryTerm::Is(ref terms) => {
-                let state = IteratorState::Clause(0, ClauseType::Is, terms);
-                QueryIterator { state_stack: vec![state] }
+            &QueryTerm::Inlined(InlinedQueryTerm::CompareNumber(_, ref terms))
+          | &QueryTerm::Is(ref terms) => {
+              let state = IteratorState::Clause(0, ClauseType::Is, terms);
+              QueryIterator { state_stack: vec![state] }
             },
             &QueryTerm::Inlined(InlinedQueryTerm::IsAtomic(ref terms))
           | &QueryTerm::Inlined(InlinedQueryTerm::IsVar(ref terms)) =>
@@ -270,7 +271,7 @@ impl<'a> ChunkedIterator<'a>
                     arity = child_terms.len();
                     break;
                 },
-                &QueryTerm::Is(_) | &QueryTerm::CompareNumber(_, _) => {
+                &QueryTerm::Is(_) => {
                     result.push(term);
                     arity = 2;
                     break;
index 939b81fbed0eb1b63bec7ce6b0d047c200d56074..73d5eb8f6f9cad2b97f9d2a066faf9f620d84efc 100644 (file)
@@ -1379,10 +1379,6 @@ impl MachineState {
 
     fn execute_query_instr(&mut self, instr: &QueryInstruction) {
         match instr {
-            &QueryInstruction::MoveArithmeticTerm(ref at, t) => {
-                let n = try_or_fail!(self, self.get_number(at));
-                self.interms[t - 1] = n;
-            },
             &QueryInstruction::GetVariable(norm, arg) =>
                 self[norm] = self.registers[arg].clone(),
             &QueryInstruction::PutConstant(_, ref constant, reg) =>
@@ -1609,6 +1605,22 @@ impl MachineState {
     fn execute_built_in_instr(&mut self, code_dir: &CodeDir, 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.fail = match cmp {
+                    CompareNumberQT::GreaterThan if !(n1.gt(n2)) => true,
+                    CompareNumberQT::GreaterThanOrEqual if !(n1.gte(n2)) => true,
+                    CompareNumberQT::LessThan if !(n1.lt(n2)) => true,
+                    CompareNumberQT::LessThanOrEqual if !(n1.lte(n2)) => true,
+                    CompareNumberQT::NotEqual if !(n1.ne(n2)) => true,
+                    CompareNumberQT::Equal if !(n1.eq(n2)) => true,
+                    _ => false
+                };
+
+                self.p += 1;
+            },
             &BuiltInInstruction::DuplicateTerm => {
                 let old_h = self.h;
 
@@ -1743,21 +1755,6 @@ impl MachineState {
             }
         };
     }
-
-    fn handle_n_compare(&mut self, cmp: CompareNumberQT) {
-        let n1 = self.interms[0].clone();
-        let n2 = self.interms[1].clone();
-        
-        self.fail = match cmp {
-            CompareNumberQT::GreaterThan if !(n1.gt(n2)) => true,
-            CompareNumberQT::GreaterThanOrEqual if !(n1.gte(n2)) => true,
-            CompareNumberQT::LessThan if !(n1.lt(n2)) => true,
-            CompareNumberQT::LessThanOrEqual if !(n1.lte(n2)) => true,
-            CompareNumberQT::NotEqual if !(n1.ne(n2)) => true,
-            CompareNumberQT::Equal if !(n1.eq(n2)) => true,
-            _ => false
-        };
-    }
     
     fn execute_ctrl_instr(&mut self, code_dir: &CodeDir, instr: &ControlInstruction)
     {
@@ -1837,27 +1834,19 @@ impl MachineState {
             },
             &ControlInstruction::ThrowExecute => {
                 self.goto_throw();
-            },
-            &ControlInstruction::CompareNumberCall(cmp) => {
-                self.handle_n_compare(cmp);
-                self.p += 1;
-            },
-            &ControlInstruction::CompareNumberExecute(cmp) => {
-                self.handle_n_compare(cmp);
-                self.p = self.cp;
-            },
-            &ControlInstruction::IsCall(r) => {
+            },            
+            &ControlInstruction::IsCall(r, ref at) => {
                 let a1 = self[r].clone();
-                let a2 = Addr::Con(Constant::from(self.interms[0].clone()));
+                let a2 = try_or_fail!(self, self.get_number(at));
 
-                self.unify(a1, a2);
+                self.unify(a1, Addr::Con(Constant::from(a2)));
                 self.p += 1;
             },
-            &ControlInstruction::IsExecute(r) => {
+            &ControlInstruction::IsExecute(r, ref at) => {
                 let a1 = self[r].clone();
-                let a2 = Addr::Con(Constant::from(self.interms[0].clone()));
+                let a2 = try_or_fail!(self, self.get_number(at));
 
-                self.unify(a1, a2);
+                self.unify(a1, Addr::Con(Constant::from(a2)));
                 self.p = self.cp;
             }
         };
index d2ec77f88d42854d831c050933a33ec4e83fd9e5..3398a36bf5cd040589a2e4d3a921d39e4bd9602b 100644 (file)
@@ -16,9 +16,21 @@ macro_rules! deallocate {
     )
 }
 
-macro_rules! move_at {
-    ($at:expr, $r:expr) => (
-        Line::Query(vec![QueryInstruction::MoveArithmeticTerm($at, $r)])
+macro_rules! compare_number {
+    ($cmp: expr, $terms: expr) => (
+        QueryTerm::Inlined(InlinedQueryTerm::CompareNumber($cmp, $terms))
+    )
+}
+
+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)
     )
 }
 
@@ -50,12 +62,6 @@ macro_rules! fact {
     )
 }
 
-macro_rules! compare_number_call {
-    ($cmp: expr) => (
-        Line::Control(ControlInstruction::CompareNumberCall($cmp))
-    )
-}
-
 macro_rules! temp_v {
     ($x:expr) => (
         RegType::Temp($x)
@@ -216,8 +222,8 @@ macro_rules! unify {
 }
 
 macro_rules! is_call {
-    ($r:expr) => (
-        Line::Control(ControlInstruction::IsCall($r))
+    ($r:expr, $at:expr) => (
+        Line::Control(ControlInstruction::IsCall($r, $at))
     )
 }
 
index c1058528434bb05237a034449adcfeb56e4b6214..87230857805adcfff30c8f0257179e87c531fb21 160000 (submodule)
@@ -1 +1 @@
-Subproject commit c1058528434bb05237a034449adcfeb56e4b6214
+Subproject commit 87230857805adcfff30c8f0257179e87c531fb21