pass Number's by reference when possible
This commit is contained in:
@@ -10,7 +10,7 @@ use prolog::machine::machine_errors::*;
|
|||||||
use prolog::machine::machine_indices::*;
|
use prolog::machine::machine_indices::*;
|
||||||
|
|
||||||
use prolog::ordered_float::*;
|
use prolog::ordered_float::*;
|
||||||
use prolog::rug::{Integer, Rational};
|
use prolog::rug::{Assign, Integer, Rational};
|
||||||
use prolog::rug::ops::PowAssign;
|
use prolog::rug::ops::PowAssign;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
@@ -279,35 +279,42 @@ impl<'a> ArithmeticEvaluator<'a>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// integer division rounding function -- 9.1.3.1.
|
// 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 {
|
match n {
|
||||||
Number::Integer(n) => n,
|
&Number::Integer(ref n) =>
|
||||||
Number::Float(OrderedFloat(f)) =>
|
RefOrOwned::Borrowed(n),
|
||||||
Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0)),
|
&Number::Float(OrderedFloat(f)) =>
|
||||||
Number::Rational(r) => r.fract_floor(Integer::new()).1
|
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.
|
// floating point rounding function -- 9.1.4.1.
|
||||||
pub fn rnd_f(n: Number) -> f64 {
|
pub fn rnd_f(n: &Number) -> f64 {
|
||||||
match n {
|
match n {
|
||||||
Number::Integer(n) => n.to_f64(),
|
&Number::Integer(ref n) => n.to_f64(),
|
||||||
Number::Float(OrderedFloat(f)) => f,
|
&Number::Float(OrderedFloat(f)) => f,
|
||||||
Number::Rational(r) => r.to_f64()
|
&Number::Rational(ref r) => r.to_f64()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// floating point result function -- 9.1.4.2.
|
// floating point result function -- 9.1.4.2.
|
||||||
pub fn result_f<Round>(n: Number, round: Round) -> Result<f64, EvalError>
|
pub fn result_f<Round>(n: &Number, round: Round) -> Result<f64, EvalError>
|
||||||
where Round: Fn(Number) -> f64
|
where Round: Fn(&Number) -> f64
|
||||||
{
|
{
|
||||||
let f = rnd_f(n);
|
let f = rnd_f(n);
|
||||||
|
|
||||||
match f.classify() {
|
match f.classify() {
|
||||||
FpCategory::Normal | FpCategory::Zero =>
|
FpCategory::Normal | FpCategory::Zero =>
|
||||||
Ok(round(Number::Float(OrderedFloat(f)))),
|
Ok(round(&Number::Float(OrderedFloat(f)))),
|
||||||
FpCategory::Infinite => {
|
FpCategory::Infinite => {
|
||||||
let f = round(Number::Float(OrderedFloat(f)));
|
let f = round(&Number::Float(OrderedFloat(f)));
|
||||||
|
|
||||||
if OrderedFloat(f) == OrderedFloat(f64::MAX) {
|
if OrderedFloat(f) == OrderedFloat(f64::MAX) {
|
||||||
Ok(f)
|
Ok(f)
|
||||||
@@ -316,31 +323,31 @@ pub fn result_f<Round>(n: Number, round: Round) -> Result<f64, EvalError>
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
FpCategory::Nan => Err(EvalError::Undefined),
|
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> {
|
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> {
|
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> {
|
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> {
|
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> {
|
fn div_f(f1: f64, f2: f64) -> Result<OrderedFloat<f64>, EvalError> {
|
||||||
if FpCategory::Zero == f2.classify() {
|
if FpCategory::Zero == f2.classify() {
|
||||||
Err(EvalError::ZeroDivisor)
|
Err(EvalError::ZeroDivisor)
|
||||||
} else {
|
} 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.
|
// Computes n ^ power. Ignores the sign of power.
|
||||||
pub fn binary_pow(mut n: Integer, power: Integer) -> Integer
|
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();
|
let mut power = power.abs();
|
||||||
|
|
||||||
if power == Integer::from(0) {
|
if power == 0 {
|
||||||
return Integer::from(1);
|
return one;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut oddand = Integer::from(1);
|
let mut oddand = Integer::from(1);
|
||||||
|
|||||||
@@ -595,17 +595,25 @@ impl CompileTimeHook {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) enum RefOrOwned<'a, T: 'a> {
|
pub enum RefOrOwned<'a, T: 'a> {
|
||||||
Borrowed(&'a T),
|
Borrowed(&'a T),
|
||||||
Owned(T)
|
Owned(T)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> RefOrOwned<'a, T> {
|
impl<'a, T> RefOrOwned<'a, T> {
|
||||||
pub(super)
|
pub fn as_ref(&'a self) -> &'a T {
|
||||||
fn as_ref(&'a self) -> &'a T {
|
|
||||||
match self {
|
match self {
|
||||||
&RefOrOwned::Borrowed(r) => r,
|
&RefOrOwned::Borrowed(r) => r,
|
||||||
&RefOrOwned::Owned(ref 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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -957,7 +957,7 @@ impl MachineState {
|
|||||||
let stub = MachineError::functor_stub(clause_name!("(div)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(div)"), 2);
|
||||||
|
|
||||||
match n1 / n2 {
|
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))
|
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>
|
fn float_pow(&self, n1: Number, n2: Number) -> Result<Number, MachineStub>
|
||||||
{
|
{
|
||||||
let f1 = result_f(n1, rnd_f);
|
let f1 = result_f(&n1, rnd_f);
|
||||||
let f2 = result_f(n2, rnd_f);
|
let f2 = result_f(&n2, rnd_f);
|
||||||
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("(**)"), 2);
|
let stub = MachineError::functor_stub(clause_name!("(**)"), 2);
|
||||||
|
|
||||||
let f1 = try_numeric_result!(self, f1, stub.clone())?;
|
let f1 = try_numeric_result!(self, f1, stub.clone())?;
|
||||||
let f2 = try_numeric_result!(self, f2, 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)?)))
|
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 stub = MachineError::functor_stub(clause_name!("(is)"), 2);
|
||||||
|
|
||||||
let f1 = try_numeric_result!(self, result_f(n1, rnd_f), stub.clone())?;
|
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 = result_f(&Number::Float(OrderedFloat(f(f1))), rnd_f);
|
||||||
|
|
||||||
try_numeric_result!(self, f1, stub)
|
try_numeric_result!(self, f1, stub)
|
||||||
}
|
}
|
||||||
@@ -1143,12 +1143,12 @@ impl MachineState {
|
|||||||
fn float(&self, n: Number) -> Result<f64, MachineStub>
|
fn float(&self, n: Number) -> Result<f64, MachineStub>
|
||||||
{
|
{
|
||||||
let stub = MachineError::functor_stub(clause_name!("(is)"), 2);
|
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
|
fn floor(&self, n1: Number) -> Integer
|
||||||
{
|
{
|
||||||
rnd_i(n1)
|
rnd_i(&n1).to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ceiling(&self, n1: Number) -> Integer
|
fn ceiling(&self, n1: Number) -> Integer
|
||||||
@@ -1300,8 +1300,8 @@ impl MachineState {
|
|||||||
(n1, n2) => {
|
(n1, n2) => {
|
||||||
let stub = MachineError::functor_stub(clause_name!("max"), 2);
|
let stub = MachineError::functor_stub(clause_name!("max"), 2);
|
||||||
|
|
||||||
let f1 = try_numeric_result!(self, result_f(n1, rnd_f), stub.clone())?;
|
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 f2 = try_numeric_result!(self, result_f(&n2, rnd_f), stub)?;
|
||||||
|
|
||||||
Ok(Number::Float(max(OrderedFloat(f1), OrderedFloat(f2))))
|
Ok(Number::Float(max(OrderedFloat(f1), OrderedFloat(f2))))
|
||||||
}
|
}
|
||||||
@@ -1319,8 +1319,8 @@ impl MachineState {
|
|||||||
(n1, n2) => {
|
(n1, n2) => {
|
||||||
let stub = MachineError::functor_stub(clause_name!("max"), 2);
|
let stub = MachineError::functor_stub(clause_name!("max"), 2);
|
||||||
|
|
||||||
let f1 = try_numeric_result!(self, result_f(n1, rnd_f), stub.clone())?;
|
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 f2 = try_numeric_result!(self, result_f(&n2, rnd_f), stub)?;
|
||||||
|
|
||||||
Ok(Number::Float(min(OrderedFloat(f1), OrderedFloat(f2))))
|
Ok(Number::Float(min(OrderedFloat(f1), OrderedFloat(f2))))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user