This commit is contained in:
parent
c038c11017
commit
0b20d7691b
3 changed files with 47 additions and 5 deletions
|
@ -12,6 +12,7 @@
|
|||
|
||||
use std::collections::{BTreeSet, BTreeMap, LinkedList};
|
||||
use std::iter::FromIterator;
|
||||
use std::f64::{NAN, INFINITY, NEG_INFINITY};
|
||||
|
||||
use num::BigInt;
|
||||
use ordered_float::OrderedFloat;
|
||||
|
@ -30,6 +31,14 @@ use types::Value;
|
|||
pub nil -> Value =
|
||||
"nil" { Value::Nil }
|
||||
|
||||
pub nan -> Value =
|
||||
"#f NaN" { Value::Float(OrderedFloat(NAN)) }
|
||||
|
||||
pub infinity -> Value =
|
||||
"#f" s:$(sign) "Infinity" {
|
||||
Value::Float(OrderedFloat(if s == "+" { INFINITY } else { NEG_INFINITY }))
|
||||
}
|
||||
|
||||
pub boolean -> Value =
|
||||
"true" { Value::Boolean(true) } /
|
||||
"false" { Value::Boolean(false) }
|
||||
|
@ -125,7 +134,7 @@ pub map -> Value =
|
|||
// It's important that float comes before integer or the parser assumes that
|
||||
// floats are integers and fails to parse
|
||||
pub value -> Value =
|
||||
__ v:(nil / boolean / float / bigint / integer / text / keyword / symbol / list / vector / map / set) __ {
|
||||
__ v:(nil / nan / infinity / boolean / float / bigint / integer / text / keyword / symbol / list / vector / map / set) __ {
|
||||
v
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
use std::collections::{BTreeSet, BTreeMap, LinkedList};
|
||||
use std::cmp::{Ordering, Ord, PartialOrd};
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::f64;
|
||||
|
||||
use symbols;
|
||||
use num::BigInt;
|
||||
|
@ -54,7 +55,19 @@ impl Display for Value {
|
|||
Boolean(v) => write!(f, "{}", v),
|
||||
Integer(v) => write!(f, "{}", v),
|
||||
BigInteger(ref v) => write!(f, "{}N", v),
|
||||
Float(OrderedFloat(v)) => write!(f, "{}", v),
|
||||
Float(ref v) => {
|
||||
// TODO: make sure float syntax is correct.
|
||||
if *v == OrderedFloat(f64::INFINITY) {
|
||||
write!(f, "#f {}", "+Infinity")
|
||||
} else if *v == OrderedFloat(f64::NEG_INFINITY) {
|
||||
write!(f, "#f {}", "-Infinity")
|
||||
} else if *v == OrderedFloat(f64::NAN) {
|
||||
write!(f, "#f {}", "NaN")
|
||||
} else {
|
||||
write!(f, "{}", v)
|
||||
}
|
||||
}
|
||||
// TODO: EDN escaping.
|
||||
Text(ref v) => write!(f, "{}", v),
|
||||
PlainSymbol(ref v) => v.fmt(f),
|
||||
NamespacedSymbol(ref v) => v.fmt(f),
|
||||
|
@ -266,6 +279,7 @@ mod test {
|
|||
|
||||
use std::collections::{BTreeSet, BTreeMap, LinkedList};
|
||||
use std::cmp::{Ordering};
|
||||
use std::f64;
|
||||
|
||||
use symbols;
|
||||
use num::BigInt;
|
||||
|
@ -280,7 +294,7 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_print_edn() {
|
||||
assert_eq!("[ 1 2 ( 3.14 ) #{ 4N } { :foo/bar 42 } [ ] :five :six/seven eight nine/ten true false nil ]",
|
||||
assert_eq!("[ 1 2 ( 3.14 ) #{ 4N } { :foo/bar 42 } [ ] :five :six/seven eight nine/ten true false nil #f NaN #f -Infinity #f +Infinity ]",
|
||||
Value::Vector(vec![
|
||||
Value::Integer(1),
|
||||
Value::Integer(2),
|
||||
|
@ -300,7 +314,10 @@ mod test {
|
|||
Value::NamespacedSymbol(symbols::NamespacedSymbol::new("nine", "ten")),
|
||||
Value::Boolean(true),
|
||||
Value::Boolean(false),
|
||||
Value::Nil
|
||||
Value::Nil,
|
||||
Value::Float(OrderedFloat(f64::NAN)),
|
||||
Value::Float(OrderedFloat(f64::NEG_INFINITY)),
|
||||
Value::Float(OrderedFloat(f64::INFINITY)),
|
||||
]
|
||||
).to_string());
|
||||
}
|
||||
|
@ -323,4 +340,4 @@ mod test {
|
|||
assert_eq!(Value::Set(BTreeSet::new()).cmp(&Value::Set(BTreeSet::new())), Ordering::Equal);
|
||||
assert_eq!(Value::Map(BTreeMap::new()).cmp(&Value::Map(BTreeMap::new())), Ordering::Equal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ extern crate ordered_float;
|
|||
|
||||
use std::collections::{BTreeSet, BTreeMap, LinkedList};
|
||||
use std::iter::FromIterator;
|
||||
use std::f64;
|
||||
use num::bigint::ToBigInt;
|
||||
use num::traits::{Zero, One};
|
||||
use ordered_float::OrderedFloat;
|
||||
|
@ -50,6 +51,21 @@ fn test_nil() {
|
|||
assert!(nil("true").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nan() {
|
||||
assert_eq!(nan("#f NaN").unwrap(), Float(OrderedFloat(f64::NAN)));
|
||||
|
||||
assert!(nan("true").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_infinity() {
|
||||
assert_eq!(infinity("#f-Infinity").unwrap(), Float(OrderedFloat(f64::NEG_INFINITY)));
|
||||
assert_eq!(infinity("#f+Infinity").unwrap(), Float(OrderedFloat(f64::INFINITY)));
|
||||
|
||||
assert!(infinity("true").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_boolean() {
|
||||
assert_eq!(boolean("true").unwrap(), Boolean(true));
|
||||
|
|
Loading…
Reference in a new issue