Bunch of work on types

- Comment out a bunch of types modules for now
- Implement fmt::Display on Object (this breaks the build because Number doesn't
  implement Display yet)
- Move all the Is* traits to predicates.rs

Haven't run tests yet because they won't build...
This commit is contained in:
Eryn Wells 2017-04-22 09:29:11 -07:00
parent d63eef3da0
commit beb32bf2ce
3 changed files with 107 additions and 33 deletions

View file

@ -1,12 +1,12 @@
pub mod number; //pub mod number;
mod bool; mod bool;
mod char; //mod char;
mod value; mod number;
mod object;
mod predicates;
pub use bool::Bool; pub use object::Object;
pub use char::Char; pub use predicates::*;
pub use number::Number;
pub use value::Value;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View file

@ -1,12 +1,23 @@
/* types/value.rs /* types/src/object.rs
* Eryn Wells <eryn@erynwells.me> * Eryn Wells <eryn@erynwells.me>
*/ */
//! # Objects
//!
//! All scheme types are represented by the `Object` enum defined in this
//! module. Most references to objects are going to be through an `ObjectPtr`.
//!
//! ## Type Predicates
//!
//! Objects satisfy one (and only one) of several predicates which define the
//! available types in Scheme. These predicates are implemented as `is_*`
//! methods in a bunch of `Is*` traits defined below.
use std::fmt; use std::fmt;
use std::any::Any; use std::ops::Deref;
use number::Number;
type ObjectPtr = Option<Box<Object>>;
#[derive(Debug)]
pub enum ObjectPtr { pub enum ObjectPtr {
/// Absence of a value. A null pointer. /// Absence of a value. A null pointer.
Null, Null,
@ -19,6 +30,7 @@ pub enum Object {
Bool(bool), Bool(bool),
ByteVector(Vec<u8>), ByteVector(Vec<u8>),
Char(char), Char(char),
Number(Number),
Pair(ObjectPtr, ObjectPtr), Pair(ObjectPtr, ObjectPtr),
//Procedure/*( TODO: Something )*/, //Procedure/*( TODO: Something )*/,
//Record/*( TODO: Something )*/, //Record/*( TODO: Something )*/,
@ -27,30 +39,61 @@ pub enum Object {
Vector(Vec<ObjectPtr>), Vector(Vec<ObjectPtr>),
} }
pub trait IsNull { impl fmt::Display for ObjectPtr {
fn is_null(&self) -> bool { false } fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn is_eof(&self) -> bool { false } match *self {
ObjectPtr::Null => write!(f, "()"),
ObjectPtr::Ptr(ref bx) => write!(f, "{}", bx.deref()),
}
}
} }
pub trait IsBool { impl fmt::Display for Object {
/// Should return `true` if this Value is a Bool. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn is_bool(&self) -> bool { false } match *self {
} Object::Bool(ref v) => {
let out = if *v { "#t" } else { "#f" };
write!(f, "{}", out)
},
pub trait IsChar { Object::ByteVector(ref vec) => {
/// Should return `true` if this Value is a Char. // TODO: Actually write the vector values.
fn is_char(&self) -> bool { false } write!(f, "#u8(").and_then(|_| write!(f, ")"))
} },
pub trait IsNumber { Object::Char(ref c) => {
/// Should return `true` if this Value is any kind of number. // TODO: This is not correct for all cases. See section 6.6 of the spec.
fn is_number(&self) -> bool { self.is_complex() || self.is_real() || self.is_rational() || self.is_integer() } write!(f, "#\\{}", c)
/// Should return `true` if this Value is a complex number type. },
fn is_complex(&self) -> bool { self.is_real() }
/// Should return `true` if this Value is a real number type. Object::Number(ref n) => {
fn is_real(&self) -> bool { self.is_rational() } write!(f, "{}", n)
/// Should return `true` if this Value is a rational number type. }
fn is_rational(&self) -> bool { self.is_integer() }
/// Should return `true` if this Value is a integer number type. Object::Pair(ref car, ref cdr) => {
fn is_integer(&self) -> bool { false } // TODO: There are rules for printing pairs...
// Print a dot before the cdr iff it's anything but Null or another Pair.
write!(f, "({}", car).and_then(|_| match cdr {
&ObjectPtr::Null => write!(f, ")"),
&ObjectPtr::Ptr(ref ptr) => match ptr.deref() {
&Object::Pair(_, _) => write!(f, "{}", ptr),
_ => write!(f, " . {})", ptr)
}
})
},
Object::String(ref st) => {
write!(f, "\"{}\"", st)
},
Object::Symbol(ref sym) => {
write!(f, "{}", sym)
},
Object::Vector(ref vec) => {
// TODO: Actually write the vector values.
write!(f, "#(").and_then(|_| write!(f, ")"))
}
}
}
} }

31
types/src/predicates.rs Normal file
View file

@ -0,0 +1,31 @@
/* types/src/predicates.rs
* Eryn Wells <eryn@erynwells.me>
*/
pub trait IsNull {
/// Is this thing null?
fn is_null(&self) -> bool { false }
}
pub trait IsBool {
/// Is this thing a boolean?
fn is_bool(&self) -> bool { false }
}
pub trait IsChar {
/// Is this thing a char?
fn is_char(&self) -> bool { false }
}
pub trait IsNumber {
/// Is this thing a number?
fn is_number(&self) -> bool { self.is_complex() || self.is_real() || self.is_rational() || self.is_integer() }
/// Should return `true` if this Value is a complex number type.
fn is_complex(&self) -> bool { self.is_real() }
/// Should return `true` if this Value is a real number type.
fn is_real(&self) -> bool { self.is_rational() }
/// Should return `true` if this Value is a rational number type.
fn is_rational(&self) -> bool { self.is_integer() }
/// Should return `true` if this Value is a integer number type.
fn is_integer(&self) -> bool { false }
}