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::collections::{BTreeSet, BTreeMap, LinkedList};
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
|
use std::f64::{NAN, INFINITY, NEG_INFINITY};
|
||||||
|
|
||||||
use num::BigInt;
|
use num::BigInt;
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
|
@ -30,6 +31,14 @@ use types::Value;
|
||||||
pub nil -> Value =
|
pub nil -> Value =
|
||||||
"nil" { Value::Nil }
|
"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 =
|
pub boolean -> Value =
|
||||||
"true" { Value::Boolean(true) } /
|
"true" { Value::Boolean(true) } /
|
||||||
"false" { Value::Boolean(false) }
|
"false" { Value::Boolean(false) }
|
||||||
|
@ -125,7 +134,7 @@ pub map -> Value =
|
||||||
// It's important that float comes before integer or the parser assumes that
|
// It's important that float comes before integer or the parser assumes that
|
||||||
// floats are integers and fails to parse
|
// floats are integers and fails to parse
|
||||||
pub value -> Value =
|
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
|
v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
use std::collections::{BTreeSet, BTreeMap, LinkedList};
|
use std::collections::{BTreeSet, BTreeMap, LinkedList};
|
||||||
use std::cmp::{Ordering, Ord, PartialOrd};
|
use std::cmp::{Ordering, Ord, PartialOrd};
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
use std::f64;
|
||||||
|
|
||||||
use symbols;
|
use symbols;
|
||||||
use num::BigInt;
|
use num::BigInt;
|
||||||
|
@ -54,7 +55,19 @@ impl Display for Value {
|
||||||
Boolean(v) => write!(f, "{}", v),
|
Boolean(v) => write!(f, "{}", v),
|
||||||
Integer(v) => write!(f, "{}", v),
|
Integer(v) => write!(f, "{}", v),
|
||||||
BigInteger(ref v) => write!(f, "{}N", 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),
|
Text(ref v) => write!(f, "{}", v),
|
||||||
PlainSymbol(ref v) => v.fmt(f),
|
PlainSymbol(ref v) => v.fmt(f),
|
||||||
NamespacedSymbol(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::collections::{BTreeSet, BTreeMap, LinkedList};
|
||||||
use std::cmp::{Ordering};
|
use std::cmp::{Ordering};
|
||||||
|
use std::f64;
|
||||||
|
|
||||||
use symbols;
|
use symbols;
|
||||||
use num::BigInt;
|
use num::BigInt;
|
||||||
|
@ -280,7 +294,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_print_edn() {
|
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::Vector(vec![
|
||||||
Value::Integer(1),
|
Value::Integer(1),
|
||||||
Value::Integer(2),
|
Value::Integer(2),
|
||||||
|
@ -300,7 +314,10 @@ mod test {
|
||||||
Value::NamespacedSymbol(symbols::NamespacedSymbol::new("nine", "ten")),
|
Value::NamespacedSymbol(symbols::NamespacedSymbol::new("nine", "ten")),
|
||||||
Value::Boolean(true),
|
Value::Boolean(true),
|
||||||
Value::Boolean(false),
|
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());
|
).to_string());
|
||||||
}
|
}
|
||||||
|
@ -323,4 +340,4 @@ mod test {
|
||||||
assert_eq!(Value::Set(BTreeSet::new()).cmp(&Value::Set(BTreeSet::new())), Ordering::Equal);
|
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);
|
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::collections::{BTreeSet, BTreeMap, LinkedList};
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
|
use std::f64;
|
||||||
use num::bigint::ToBigInt;
|
use num::bigint::ToBigInt;
|
||||||
use num::traits::{Zero, One};
|
use num::traits::{Zero, One};
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
|
@ -50,6 +51,21 @@ fn test_nil() {
|
||||||
assert!(nil("true").is_err());
|
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]
|
#[test]
|
||||||
fn test_boolean() {
|
fn test_boolean() {
|
||||||
assert_eq!(boolean("true").unwrap(), Boolean(true));
|
assert_eq!(boolean("true").unwrap(), Boolean(true));
|
||||||
|
|
Loading…
Reference in a new issue