Move Real to its own module and bring a bunch of stuff from rational and integer over
This commit is contained in:
parent
3571fd02c5
commit
6baf62e8c2
2 changed files with 202 additions and 6 deletions
|
@ -6,11 +6,9 @@
|
|||
///
|
||||
/// Scheme numbers are complex, literally.
|
||||
|
||||
pub mod integer;
|
||||
pub mod rational;
|
||||
pub mod real;
|
||||
|
||||
pub use self::integer::Integer;
|
||||
pub use self::rational::Rational;
|
||||
pub use self::real::Real;
|
||||
|
||||
use std::any::Any;
|
||||
use std::fmt::Debug;
|
||||
|
@ -24,7 +22,9 @@ type Flt = f64;
|
|||
trait Number: Debug + IsBool + IsChar + IsNumber + Value {
|
||||
/// Convert a Number to the next lowest type in Scheme's number pyramid, if possible.
|
||||
fn convert_down(&self) -> Option<Box<Number>>;
|
||||
}
|
||||
|
||||
trait IsExact {
|
||||
/// Should return `true` if this Number is represented exactly. This should be an inverse of
|
||||
/// `is_inexact()`.
|
||||
fn is_exact(&self) -> bool { false }
|
||||
|
@ -49,6 +49,13 @@ impl ValueEq for Box<Number> {
|
|||
fn as_any(&self) -> &Any { self }
|
||||
}
|
||||
|
||||
struct Real(Flt);
|
||||
struct Complex<'a>(&'a Number, &'a Number);
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct Complex {
|
||||
real: Real,
|
||||
imag: Real
|
||||
}
|
||||
|
||||
impl IsNumber for Complex {
|
||||
fn is_complex(&self) -> bool { true }
|
||||
}
|
||||
|
|
189
types/src/number/real.rs
Normal file
189
types/src/number/real.rs
Normal file
|
@ -0,0 +1,189 @@
|
|||
/* types/src/number/real.rs
|
||||
* Eryn Wells <eryn@erynwells.me>
|
||||
*/
|
||||
|
||||
use std::any::Any;
|
||||
use std::ops::{Add, Sub, Mul, Div};
|
||||
use super::*;
|
||||
use value::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Real {
|
||||
Integer(Int),
|
||||
Rational(Int, Int),
|
||||
Irrational(Flt)
|
||||
}
|
||||
|
||||
impl PartialEq for Real {
|
||||
fn eq(&self, other: &Real) -> bool {
|
||||
match *other {
|
||||
Real::Integer(v) => self.eq_integer(v),
|
||||
Real::Rational(p, q) => self.eq_rational(p, q),
|
||||
Real::Irrational(v) => self.eq_irrational(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Real {
|
||||
fn eq_integer(&self, v_other: Int) -> bool {
|
||||
match *self {
|
||||
Real::Integer(v) => v == v_other,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn eq_rational(&self, p_other: Int, q_other: Int) -> bool {
|
||||
match *self {
|
||||
Real::Rational(p, q) => p == p_other && q == q_other,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn eq_irrational(&self, v_other: Flt) -> bool {
|
||||
match *self {
|
||||
Real::Irrational(v) => v == v_other,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IsBool for Real { }
|
||||
impl IsChar for Real { }
|
||||
|
||||
impl IsNumber for Real {
|
||||
fn is_number(&self) -> 9bool { true }
|
||||
|
||||
fn is_integer(&self) -> bool {
|
||||
match *self {
|
||||
Real::Integer(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_rational(&self) -> bool {
|
||||
match *self {
|
||||
Real::Irrational(_) => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_real(&self) -> bool { true }
|
||||
}
|
||||
|
||||
impl IsExact for Real {
|
||||
fn is_exact(&self) -> bool { self.is_rational() }
|
||||
}
|
||||
|
||||
impl Value for Real {
|
||||
fn as_value(&self) -> &Value { self }
|
||||
}
|
||||
|
||||
impl ValueEq for Real {
|
||||
fn eq(&self, other: &Value) -> bool {
|
||||
other.as_any().downcast_ref::<Self>().map_or(false, |x| x == self)
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &Any { self }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use number::Real;
|
||||
use value::*;
|
||||
|
||||
#[test]
|
||||
fn reals_are_numbers() {
|
||||
assert!(Real::Integer(3).is_number());
|
||||
assert!(Real::Integer(3).as_value().is_number());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reals_are_not_other_values() {
|
||||
assert!(!Real::Integer(3).is_bool());
|
||||
assert!(!Real::Integer(3).is_char());
|
||||
assert!(!Real::Integer(3).as_value().is_bool());
|
||||
assert!(!Real::Integer(3).as_value().is_char());
|
||||
}
|
||||
|
||||
mod integers {
|
||||
use number::*;
|
||||
use value::*;
|
||||
|
||||
#[test]
|
||||
fn are_equal() {
|
||||
assert_eq!(Real::Integer(3), Real::Integer(3));
|
||||
assert_ne!(Real::Integer(12), Real::Integer(9));
|
||||
assert_eq!(Real::Integer(4).as_value(), Real::Integer(4).as_value());
|
||||
assert_ne!(Real::Integer(5).as_value(), Real::Integer(7).as_value());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn are_correctly_placed_in_the_number_pyramid() {
|
||||
assert!(Real::Integer(4).is_complex());
|
||||
assert!(Real::Integer(4).is_real());
|
||||
assert!(Real::Integer(4).is_rational());
|
||||
assert!(Real::Integer(4).is_integer());
|
||||
assert!(Real::Integer(4).is_number());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn are_exact() {
|
||||
assert!(Real::Integer(3).is_exact());
|
||||
assert!(!Real::Integer(3).is_inexact());
|
||||
}
|
||||
}
|
||||
|
||||
mod rationals {
|
||||
use number::*;
|
||||
use value::*;
|
||||
|
||||
#[test]
|
||||
fn are_equal() {
|
||||
assert_eq!(Real::Rational(3, 2), Real::Rational(3, 2));
|
||||
assert_ne!(Real::Rational(12, 4), Real::Rational(9, 7));
|
||||
assert_eq!(Real::Rational(4, 5).as_value(), Real::Rational(4, 5).as_value());
|
||||
assert_ne!(Real::Rational(5, 6).as_value(), Real::Rational(7, 6).as_value());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn are_correctly_placed_in_the_number_pyramid() {
|
||||
assert!(Real::Rational(4, 3).is_complex());
|
||||
assert!(Real::Rational(4, 3).is_real());
|
||||
assert!(Real::Rational(4, 3).is_rational());
|
||||
assert!(!Real::Rational(4, 3).is_integer());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn are_exact() {
|
||||
assert!(Real::Rational(3, 5).is_exact());
|
||||
assert!(!Real::Rational(3, 5).is_inexact());
|
||||
}
|
||||
}
|
||||
|
||||
mod irrationals {
|
||||
use number::*;
|
||||
use value::*;
|
||||
|
||||
#[test]
|
||||
fn are_equal() {
|
||||
assert_eq!(Real::Irrational(3.2), Real::Irrational(3.2));
|
||||
assert_ne!(Real::Irrational(12.0), Real::Irrational(9.0));
|
||||
assert_eq!(Real::Irrational(4.0).as_value(), Real::Irrational(4.0).as_value());
|
||||
assert_ne!(Real::Irrational(5.0).as_value(), Real::Irrational(7.0).as_value());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn are_correctly_placed_in_the_number_pyramid() {
|
||||
assert!(Real::Irrational(4.0).is_complex());
|
||||
assert!(Real::Irrational(4.0).is_real());
|
||||
assert!(!Real::Irrational(4.0).is_rational());
|
||||
assert!(!Real::Irrational(4.0).is_integer());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn are_inexact() {
|
||||
assert!(Real::Irrational(3.0).is_inexact());
|
||||
assert!(!Real::Irrational(3.0).is_exact());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue