]> Repositorios git - scryer-prolog.git/commitdiff
pass Number's by reference when possible
authorMark Thom <[email protected]>
Wed, 22 May 2019 23:48:34 +0000 (19:48 -0400)
committerMark Thom <[email protected]>
Wed, 22 May 2019 23:48:34 +0000 (19:48 -0400)
src/prolog/arithmetic.rs
src/prolog/machine/machine_indices.rs
src/prolog/machine/machine_state_impl.rs

index cad6f04cd67c5a4b7ccfccb7b746a6da81eff6a0..b9115793d3f7637cf333b3814796074aa1343bf3 100644 (file)
@@ -10,7 +10,7 @@ use prolog::machine::machine_errors::*;
 use prolog::machine::machine_indices::*;
 
 use prolog::ordered_float::*;
-use prolog::rug::{Integer, Rational};
+use prolog::rug::{Assign, Integer, Rational};
 use prolog::rug::ops::PowAssign;
 
 use std::cell::Cell;
@@ -279,35 +279,42 @@ impl<'a> ArithmeticEvaluator<'a>
 }
 
 // integer division rounding function -- 9.1.3.1.
-pub fn rnd_i(n: Number) -> Integer {
+pub fn rnd_i<'a>(n: &'a Number) -> RefOrOwned<'a, Integer> {
     match n {
-        Number::Integer(n) => n,
-        Number::Float(OrderedFloat(f)) =>
-            Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0)),
-        Number::Rational(r) => r.fract_floor(Integer::new()).1
+        &Number::Integer(ref n) =>
+            RefOrOwned::Borrowed(n),
+        &Number::Float(OrderedFloat(f)) =>
+            RefOrOwned::Owned(Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0))),
+        &Number::Rational(ref r) => {
+            let r_ref = r.fract_floor_ref();
+            let (mut fract, mut floor) = (Rational::new(), Integer::new());
+            
+            (&mut fract, &mut floor).assign(r_ref);            
+            RefOrOwned::Owned(floor)
+        }
     }
 }
 
 // floating point rounding function -- 9.1.4.1.
-pub fn rnd_f(n: Number) -> f64 {
+pub fn rnd_f(n: &Number) -> f64 {
     match n {
-        Number::Integer(n) => n.to_f64(),
-        Number::Float(OrderedFloat(f)) => f,
-        Number::Rational(r) => r.to_f64()
+        &Number::Integer(ref n) => n.to_f64(),
+        &Number::Float(OrderedFloat(f)) => f,
+        &Number::Rational(ref r) => r.to_f64()
     }
 }
 
 // floating point result function -- 9.1.4.2.
-pub fn result_f<Round>(n: Number, round: Round) -> Result<f64, EvalError>
-  where Round: Fn(Number) -> f64
+pub fn result_f<Round>(n: &Number, round: Round) -> Result<f64, EvalError>
+  where Round: Fn(&Number) -> f64
 {
     let f = rnd_f(n);
 
     match f.classify() {
         FpCategory::Normal | FpCategory::Zero =>
-            Ok(round(Number::Float(OrderedFloat(f)))),
+            Ok(round(&Number::Float(OrderedFloat(f)))),
         FpCategory::Infinite => {
-            let f = round(Number::Float(OrderedFloat(f)));
+            let f = round(&Number::Float(OrderedFloat(f)));
 
             if OrderedFloat(f) == OrderedFloat(f64::MAX) {
                 Ok(f)
@@ -316,31 +323,31 @@ pub fn result_f<Round>(n: Number, round: Round) -> Result<f64, EvalError>
             }
         },
         FpCategory::Nan => Err(EvalError::Undefined),
-        _ => Ok(round(Number::Float(OrderedFloat(f))))
+        _ => Ok(round(&Number::Float(OrderedFloat(f))))
     }
 }
 
 fn float_i_to_f(n: Integer) -> Result<f64, EvalError> {
-    result_f(Number::Integer(n), rnd_f)
+    result_f(&Number::Integer(n), rnd_f)
 }
 
 fn float_r_to_f(r: Rational) -> Result<f64, EvalError> {
-    result_f(Number::Rational(r), rnd_f)
+    result_f(&Number::Rational(r), rnd_f)
 }
 
 fn add_f(f1: f64, f2: f64) -> Result<OrderedFloat<f64>, EvalError> {
-    Ok(OrderedFloat(result_f(Number::Float(OrderedFloat(f1 + f2)), rnd_f)?))
+    Ok(OrderedFloat(result_f(&Number::Float(OrderedFloat(f1 + f2)), rnd_f)?))
 }
 
 fn mul_f(f1: f64, f2: f64) -> Result<OrderedFloat<f64>, EvalError> {
-    Ok(OrderedFloat(result_f(Number::Float(OrderedFloat(f1 * f2)), rnd_f)?))
+    Ok(OrderedFloat(result_f(&Number::Float(OrderedFloat(f1 * f2)), rnd_f)?))
 }
 
 fn div_f(f1: f64, f2: f64) -> Result<OrderedFloat<f64>, EvalError> {
     if FpCategory::Zero == f2.classify() {
         Err(EvalError::ZeroDivisor)
     } else {
-        Ok(OrderedFloat(result_f(Number::Float(OrderedFloat(f1 / f2)), rnd_f)?))
+        Ok(OrderedFloat(result_f(&Number::Float(OrderedFloat(f1 / f2)), rnd_f)?))
     }
 }
 
@@ -492,12 +499,11 @@ impl Ord for Number {
 // Computes n ^ power. Ignores the sign of power.
 pub fn binary_pow(mut n: Integer, power: Integer) -> Integer
 {
-    let one = Integer::from(1);
-    
+    let one = Integer::from(1);    
     let mut power = power.abs();
 
-    if power == Integer::from(0) {
-        return Integer::from(1);
+    if power == 0 {
+        return one;
     }
 
     let mut oddand = Integer::from(1);
index 45db2f929c21d7349e4d76addc87cbaf730e0cab..99a91998e2d8c4a0a9956c40a32fc2122423cd86 100644 (file)
@@ -595,17 +595,25 @@ impl CompileTimeHook {
     }
 }
 
-pub(super) enum RefOrOwned<'a, T: 'a> {
+pub enum RefOrOwned<'a, T: 'a> {
     Borrowed(&'a T),
     Owned(T)
 }
 
 impl<'a, T> RefOrOwned<'a, T> {
-    pub(super)
-    fn as_ref(&'a self) -> &'a T {
+    pub fn as_ref(&'a self) -> &'a T {
         match self {
             &RefOrOwned::Borrowed(r) => r,
             &RefOrOwned::Owned(ref r) => r
         }
     }
+
+    pub fn to_owned(self) -> T
+      where T: Clone
+    {
+        match self {
+            RefOrOwned::Borrowed(item) => item.clone(),
+            RefOrOwned::Owned(item) => item
+        }
+    }
 }
index 1cfbf9ade83408ce00fc121a3e92dece774d68c1..486f2f0d274828a6df84b2e135273cf98db7acf5 100644 (file)
@@ -957,7 +957,7 @@ impl MachineState {
         let stub = MachineError::functor_stub(clause_name!("(div)"), 2);
 
         match n1 / n2 {
-            Ok(result) => Ok(rnd_i(result)),
+            Ok(result) => Ok(rnd_i(&result).to_owned()),
             Err(e) => Err(self.error_form(MachineError::evaluation_error(e), stub))
         }
     }
@@ -1051,15 +1051,15 @@ impl MachineState {
 
     fn float_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub>
     {
-        let f1 = result_f(n1, rnd_f);
-        let f2 = result_f(n2, rnd_f);
+        let f1 = result_f(&n1, rnd_f);
+        let f2 = result_f(&n2, rnd_f);
 
         let stub = MachineError::functor_stub(clause_name!("(**)"), 2);
 
         let f1 = try_numeric_result!(self, f1, stub.clone())?;
         let f2 = try_numeric_result!(self, f2, stub.clone())?;
 
-        let result = result_f(Number::Float(OrderedFloat(f1.powf(f2))), rnd_f);
+        let result = result_f(&Number::Float(OrderedFloat(f1.powf(f2))), rnd_f);
 
         Ok(Number::Float(OrderedFloat(try_numeric_result!(self, result, stub)?)))
     }
@@ -1084,8 +1084,8 @@ impl MachineState {
     {
         let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
 
-        let f1 = try_numeric_result!(self, result_f(n1, rnd_f), stub.clone())?;
-        let f1 = result_f(Number::Float(OrderedFloat(f(f1))), rnd_f);
+        let f1 = try_numeric_result!(self, result_f(&n1, rnd_f), stub.clone())?;
+        let f1 = result_f(&Number::Float(OrderedFloat(f(f1))), rnd_f);
 
         try_numeric_result!(self, f1, stub)
     }
@@ -1143,12 +1143,12 @@ impl MachineState {
     fn float(&self, n: Number) -> Result<f64, MachineStub>
     {
         let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
-        try_numeric_result!(self, result_f(n, rnd_f), stub)
+        try_numeric_result!(self, result_f(&n, rnd_f), stub)
     }
 
     fn floor(&self, n1: Number) -> Integer
     {
-        rnd_i(n1)
+        rnd_i(&n1).to_owned()
     }
 
     fn ceiling(&self, n1: Number) -> Integer
@@ -1300,8 +1300,8 @@ impl MachineState {
             (n1, n2) => {
                 let stub = MachineError::functor_stub(clause_name!("max"), 2);
 
-                let f1 = try_numeric_result!(self, result_f(n1, rnd_f), stub.clone())?;
-                let f2 = try_numeric_result!(self, result_f(n2, rnd_f), stub)?;
+                let f1 = try_numeric_result!(self, result_f(&n1, rnd_f), stub.clone())?;
+                let f2 = try_numeric_result!(self, result_f(&n2, rnd_f), stub)?;
 
                 Ok(Number::Float(max(OrderedFloat(f1), OrderedFloat(f2))))
             }
@@ -1319,8 +1319,8 @@ impl MachineState {
             (n1, n2) => {
                 let stub = MachineError::functor_stub(clause_name!("max"), 2);
                 
-                let f1 = try_numeric_result!(self, result_f(n1, rnd_f), stub.clone())?;
-                let f2 = try_numeric_result!(self, result_f(n2, rnd_f), stub)?;
+                let f1 = try_numeric_result!(self, result_f(&n1, rnd_f), stub.clone())?;
+                let f2 = try_numeric_result!(self, result_f(&n2, rnd_f), stub)?;
 
                 Ok(Number::Float(min(OrderedFloat(f1), OrderedFloat(f2))))
             }