]> Repositorios git - scryer-prolog.git/commitdiff
clean up arithmetic.rs
authorMark Thom <[email protected]>
Fri, 19 Jan 2018 02:54:15 +0000 (19:54 -0700)
committerMark Thom <[email protected]>
Fri, 19 Jan 2018 02:54:15 +0000 (19:54 -0700)
src/prolog/arithmetic.rs
src/prolog/ast.rs
src/prolog/iterators.rs

index 95cea1b0a1524154c823ee713f1e2c90ffa88676..91451fcb49b2d012cca285335fb34f2a3f28a8a2 100644 (file)
@@ -1,6 +1,5 @@
 use prolog::ast::*;
 use prolog::fixtures::*;
-use prolog::tabled_rc::*;
 
 use std::cell::Cell;
 use std::cmp::{min, max};
@@ -21,8 +20,8 @@ impl<'a> ArithInstructionIterator<'a> {
         let state = match term {
             &Term::AnonVar =>
                 return Err(ArithmeticError::InvalidTerm),
-            &Term::Clause(_, _, ref terms, _) =>
-                TermIterState::Clause(0, ClauseType::Root, terms),
+            &Term::Clause(_, ref name, ref terms, _) =>
+                TermIterState::Clause(0, ClauseType::Root(name), terms),
             &Term::Constant(ref cell, ref cons) =>
                 TermIterState::Constant(Level::Shallow, cell, cons),
             &Term::Cons(_, _, _) =>
@@ -37,7 +36,7 @@ impl<'a> ArithInstructionIterator<'a> {
 
 pub enum ArithTermRef<'a> {
     Constant(&'a Constant),
-    Op(ClauseType<'a>, &'a Vec<Box<Term>>),
+    Op(&'a str, usize), // name, arity.
     Var(&'a Cell<VarReg>, &'a Var)
 }
 
@@ -50,8 +49,10 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
                 TermIterState::AnonVar(_) =>
                     return Some(Err(ArithmeticError::UninstantiatedVar)),
                 TermIterState::Clause(child_num, ct, child_terms) => {
-                    if child_num == child_terms.len() {
-                        return Some(Ok(ArithTermRef::Op(ct, child_terms)));
+                    let arity = child_terms.len();
+
+                    if child_num == arity {
+                        return Some(Ok(ArithTermRef::Op(ct.name(), arity)));
                     } else {
                         self.state_stack.push(TermIterState::Clause(child_num + 1, ct, child_terms));
                         self.push_subterm(ct.level_of_subterms(), child_terms[child_num].as_ref());
@@ -73,29 +74,21 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
 pub struct ArithmeticEvaluator<'a> {
     bindings: &'a AllocVarDict<'a>,
     interm: Vec<ArithmeticTerm>,
-    interm_c: usize    
+    interm_c: usize
 }
 
-pub trait ArithmeticTermIter<'a> {        
+pub trait ArithmeticTermIter<'a> {
     type Iter : Iterator<Item=Result<ArithTermRef<'a>, ArithmeticError>>;
-    
+
     fn iter(&self) -> Result<Self::Iter, ArithmeticError>;
-    fn root_name(&self) -> Result<TabledRc<Atom>, ArithmeticError>;
 }
 
-impl<'a> ArithmeticTermIter<'a> for &'a Term {    
-    type Iter = ArithInstructionIterator<'a>;    
+impl<'a> ArithmeticTermIter<'a> for &'a Term {
+    type Iter = ArithInstructionIterator<'a>;
 
     fn iter(&self) -> Result<Self::Iter, ArithmeticError> {
         ArithInstructionIterator::new(self)
     }
-
-    fn root_name(&self) -> Result<TabledRc<Atom>, ArithmeticError> {
-        match self {
-            &&Term::Clause(_, ref name, _, _) => Ok(name.clone()),
-            _ => Err(ArithmeticError::InvalidTerm)
-        }
-    }
 }
 
 impl<'a> ArithmeticEvaluator<'a>
@@ -103,20 +96,20 @@ impl<'a> ArithmeticEvaluator<'a>
     pub fn new(bindings: &'a AllocVarDict<'a>, target_int: usize) -> Self {
         ArithmeticEvaluator { bindings, interm: Vec::new(), interm_c: target_int }
     }
-    
-    fn get_unary_instr(name: &Atom, a1: ArithmeticTerm, t: usize)
+
+    fn get_unary_instr(name: &str, a1: ArithmeticTerm, t: usize)
                        -> Result<ArithmeticInstruction, ArithmeticError>
     {
-        match name.as_str() {
+        match name {
             "-" => Ok(ArithmeticInstruction::Neg(a1, t)),
              _  => Err(ArithmeticError::InvalidOp)
         }
     }
 
-    fn get_binary_instr(name: &Atom, a1: ArithmeticTerm, a2: ArithmeticTerm, t: usize)
+    fn get_binary_instr(name: &str, a1: ArithmeticTerm, a2: ArithmeticTerm, t: usize)
                         -> Result<ArithmeticInstruction, ArithmeticError>
     {
-        match name.as_str() {
+        match name {
             "+"    => Ok(ArithmeticInstruction::Add(a1, a2, t)),
             "-"    => Ok(ArithmeticInstruction::Sub(a1, a2, t)),
             "/"    => Ok(ArithmeticInstruction::Div(a1, a2, t)),
@@ -134,7 +127,7 @@ impl<'a> ArithmeticEvaluator<'a>
              _     => Err(ArithmeticError::InvalidOp)
         }
     }
-    
+
     fn incr_interm(&mut self) -> usize {
         let temp = self.interm_c;
 
@@ -144,10 +137,10 @@ impl<'a> ArithmeticEvaluator<'a>
         temp
     }
 
-    fn instr_from_clause(&mut self, name: &Atom, terms: &Vec<Box<Term>>)
+    fn instr_from_clause(&mut self, name: &str, arity: usize)
                          -> Result<ArithmeticInstruction, ArithmeticError>
     {
-        match terms.len() {
+        match arity {
             1 => {
                 let a1 = self.interm.pop().unwrap();
 
@@ -203,7 +196,7 @@ impl<'a> ArithmeticEvaluator<'a>
         where Iter: ArithmeticTermIter<'a>
     {
         let mut code = vec![];
-        
+
         for term_ref in src.iter()?
         {
             match term_ref? {
@@ -221,15 +214,9 @@ impl<'a> ArithmeticEvaluator<'a>
 
                     self.interm.push(ArithmeticTerm::Reg(r));
                 },
-                ArithTermRef::Op(ClauseType::Deep(_, _, name, _), terms) => {
-                    code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?));
-                },
-                ArithTermRef::Op(ClauseType::Root, terms) => {
-                    let name = src.root_name()?;
-                    code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?));
-                },
-                _ =>
-                    return Err(ArithmeticError::InvalidTerm)
+                ArithTermRef::Op(name, arity) => {
+                    code.push(Line::Arithmetic(self.instr_from_clause(&*name, arity)?));
+                }
             }
         }
 
index c1ce933a554eef5ea430ccbab201d440b28fc42d..475792e6ae480d6a6bc94acbd4e681589a23c4e0 100644 (file)
@@ -366,15 +366,34 @@ pub struct Rule {
 
 #[derive(Clone, Copy)]
 pub enum ClauseType<'a> {
+    Arg,
     CallN,
     Catch,
     Deep(Level, &'a Cell<RegType>, &'a TabledRc<Atom>, Option<Fixity>),
+    Display,
+    DuplicateTerm,
+    Functor,
     Is,
-    Root,
+    Root(&'a TabledRc<Atom>),
     Throw,
 }
 
 impl<'a> ClauseType<'a> {
+    pub fn name(&self) -> &'a str {
+        match self {
+            &ClauseType::Arg => "arg",
+            &ClauseType::CallN => "call",
+            &ClauseType::Catch => "catch",
+            &ClauseType::Deep(_, _, name, _) => name.as_str(),
+            &ClauseType::Display => "display",
+            &ClauseType::DuplicateTerm => "duplicate_term",
+            &ClauseType::Functor => "functor",
+            &ClauseType::Is => "is",
+            &ClauseType::Root(name) => name.as_str(),
+            &ClauseType::Throw => "throw"
+        }
+    }
+    
     pub fn level_of_subterms(self) -> Level {
         match self {
             ClauseType::Deep(..) => Level::Deep,
index fa5a9f56e152701c0d58b93b63a86c86ba2847fc..074d2bd54d77cd14965c106de77b04913264fc7b 100644 (file)
@@ -17,8 +17,8 @@ impl<'a> QueryIterator<'a> {
         let state = match term {
             &Term::AnonVar =>
                 return QueryIterator { state_stack: vec![] },
-            &Term::Clause(.., ref terms, _) =>
-                TermIterState::Clause(0, ClauseType::Root, terms),
+            &Term::Clause(_, ref name, ref terms, _) =>
+                TermIterState::Clause(0, ClauseType::Root(name), terms),
             &Term::Cons(..) =>
                 return QueryIterator { state_stack: vec![] },
             &Term::Constant(_, _) =>
@@ -40,21 +40,27 @@ impl<'a> QueryIterator<'a> {
                 let state = TermIterState::Clause(0, ClauseType::Catch, terms);
                 QueryIterator { state_stack: vec![state] }
             },
-            &QueryTerm::Display(ref terms)
-          | &QueryTerm::DuplicateTerm(ref terms) => {
-                let state = TermIterState::Clause(0, ClauseType::Root, terms);
+            &QueryTerm::Display(ref terms) => {
+                let state = TermIterState::Clause(0, ClauseType::Display, terms);
                 QueryIterator { state_stack: vec![state] }
             },
-            &QueryTerm::Arg(ref terms)
-          | &QueryTerm::Functor(ref terms) => {
-                let state = TermIterState::Clause(0, ClauseType::Root, terms);
+            &QueryTerm::DuplicateTerm(ref terms) => {
+                let state = TermIterState::Clause(0, ClauseType::DuplicateTerm, terms);
+                QueryIterator { state_stack: vec![state] }
+            },
+            &QueryTerm::Arg(ref terms) => {
+                let state = TermIterState::Clause(0, ClauseType::Arg, terms);
+                QueryIterator { state_stack: vec![state] }
+            },
+            &QueryTerm::Functor(ref terms) => {
+                let state = TermIterState::Clause(0, ClauseType::Functor, terms);
                 QueryIterator { state_stack: vec![state] }
             },
             &QueryTerm::Inlined(InlinedQueryTerm::CompareNumber(_, ref terms))
           | &QueryTerm::Is(ref terms) => {
                     let state = TermIterState::Clause(0, ClauseType::Is, terms);
                     QueryIterator { state_stack: vec![state] }
-            },            
+            },
             &QueryTerm::Inlined(InlinedQueryTerm::IsAtomic(ref terms))
           | &QueryTerm::Inlined(InlinedQueryTerm::IsInteger(ref terms))
           | &QueryTerm::Inlined(InlinedQueryTerm::IsVar(ref terms)) =>
@@ -78,7 +84,7 @@ impl QueryTerm {
 
 impl<'a> Iterator for QueryIterator<'a> {
     type Item = TermRef<'a>;
-    
+
     fn next(&mut self) -> Option<Self::Item> {
         while let Some(iter_state) = self.state_stack.pop() {
             match iter_state {
@@ -113,7 +119,7 @@ impl<'a> Iterator for QueryIterator<'a> {
             };
         }
 
-        None        
+        None
     }
 }
 
@@ -130,8 +136,8 @@ impl<'a> FactIterator<'a> {
         let states = match term {
             &Term::AnonVar =>
                 vec![TermIterState::AnonVar(Level::Shallow)],
-            &Term::Clause(.., ref terms, _) =>
-                vec![TermIterState::Clause(0, ClauseType::Root, terms)],
+            &Term::Clause(.., ref name, ref terms, _) =>
+                vec![TermIterState::Clause(0, ClauseType::Root(name), terms)],
             &Term::Cons(ref cell, ref head, ref tail) =>
                 vec![TermIterState::InitialCons(Level::Shallow,
                                                 cell,
@@ -217,7 +223,7 @@ impl<'a> ChunkedIterator<'a>
     {
         let inner_iter = Box::new(once(p1));
         let iter = inner_iter.chain(clauses.iter());
-        
+
         ChunkedIterator {
             term_loc: GenContext::Last(0),
             iter: Box::new(iter),
@@ -237,7 +243,7 @@ impl<'a> ChunkedIterator<'a>
             term_loc: GenContext::Head,
             iter: Box::new(iter),
             deep_cut_encountered: false,
-        }        
+        }
     }
 
     pub fn encountered_deep_cut(&self) -> bool {
@@ -257,21 +263,21 @@ impl<'a> ChunkedIterator<'a>
         let mut arity  = 0;
         let mut item   = Some(term);
         let mut result = Vec::new();
-        
+
         while let Some(term) = item {
             match term {
-                &QueryTerm::Term(ref inner_term) => 
+                &QueryTerm::Term(ref inner_term) =>
                     if let GenContext::Head = self.term_loc {
                         result.push(term);
                         self.term_loc = GenContext::Last(0);
                     } else {
                         result.push(term);
-                        
+
                         if inner_term.is_callable() {
                             arity = inner_term.arity();
                             break;
                         }
-                    },                
+                    },
                 &QueryTerm::CallN(ref child_terms) => {
                     result.push(term);
                     arity = child_terms.len() + 1;