summaryrefslogtreecommitdiff
path: root/dhall_core
diff options
context:
space:
mode:
authorNadrieril2019-03-21 21:27:36 +0100
committerNadrieril2019-03-21 21:27:36 +0100
commit8d527e88168885ab754a039219d0ae682fa4508b (patch)
treeb26d26902ba84d611f9905add97b3a29d0dcf025 /dhall_core
parent6cbe21b84ffd274f92791ab8dbf9af6527978688 (diff)
Follow the spec for handling Doubles
Diffstat (limited to 'dhall_core')
-rw-r--r--dhall_core/src/core.rs28
-rw-r--r--dhall_core/src/parser.rs9
-rw-r--r--dhall_core/src/printer.rs18
-rw-r--r--dhall_core/src/text.rs2
4 files changed, 49 insertions, 8 deletions
diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs
index 52fc0cf..9f26b65 100644
--- a/dhall_core/src/core.rs
+++ b/dhall_core/src/core.rs
@@ -3,15 +3,39 @@ use crate::*;
use std::collections::BTreeMap;
use std::rc::Rc;
-pub type Double = f64;
pub type Int = isize;
pub type Integer = isize;
pub type Natural = usize;
+pub type Double = NaiveDouble;
/// An empty type
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum X {}
+/// Double with bitwise equality
+#[derive(Debug, Copy, Clone)]
+pub struct NaiveDouble(f64);
+
+impl PartialEq for NaiveDouble {
+ fn eq(&self, other: &Self) -> bool {
+ return self.0.to_bits() == other.0.to_bits();
+ }
+}
+
+impl Eq for NaiveDouble {}
+
+impl From<f64> for NaiveDouble {
+ fn from(x: f64) -> Self {
+ NaiveDouble(x)
+ }
+}
+
+impl From<NaiveDouble> for f64 {
+ fn from(x: NaiveDouble) -> f64 {
+ x.0
+ }
+}
+
/// Constants for a pure type system
///
/// The only axiom is:
@@ -147,7 +171,7 @@ pub type DhallExpr = ResolvedExpr<X>;
pub type SubExpr<Note, Embed> = Rc<Expr<Note, Embed>>;
/// Syntax tree for expressions
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Expr<Note, Embed> {
/// `Const c ~ c`
Const(Const),
diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs
index b07094d..7de75d2 100644
--- a/dhall_core/src/parser.rs
+++ b/dhall_core/src/parser.rs
@@ -348,7 +348,8 @@ make_parser! {
rule!(double_literal_raw<core::Double>;
raw_pair!(pair) => {
pair.as_str().trim()
- .parse()
+ .parse::<f64>()
+ .map(NaiveDouble::from)
.map_err(|e: std::num::ParseFloatError| custom_parse_error(&pair, format!("{}", e)))?
}
);
@@ -599,9 +600,9 @@ make_parser! {
rule!(literal_expression_raw<ParsedExpr> as expression; children!(
[double_literal_raw(n)] => bx(Expr::DoubleLit(n)),
- [minus_infinity_literal(n)] => bx(Expr::DoubleLit(std::f64::NEG_INFINITY)),
- [plus_infinity_literal(n)] => bx(Expr::DoubleLit(std::f64::INFINITY)),
- [NaN_raw(n)] => bx(Expr::DoubleLit(std::f64::NAN)),
+ [minus_infinity_literal(n)] => bx(Expr::DoubleLit(std::f64::NEG_INFINITY.into())),
+ [plus_infinity_literal(n)] => bx(Expr::DoubleLit(std::f64::INFINITY.into())),
+ [NaN_raw(n)] => bx(Expr::DoubleLit(std::f64::NAN.into())),
[natural_literal_raw(n)] => bx(Expr::NaturalLit(n)),
[integer_literal_raw(n)] => bx(Expr::IntegerLit(n)),
[double_quote_literal(s)] => bx(Expr::TextLit(s)),
diff --git a/dhall_core/src/printer.rs b/dhall_core/src/printer.rs
index b72f32b..e43f1be 100644
--- a/dhall_core/src/printer.rs
+++ b/dhall_core/src/printer.rs
@@ -183,7 +183,23 @@ impl<S, A: Display> Expr<S, A> {
a.fmt(f)
}
&IntegerLit(a) => a.fmt(f),
- &DoubleLit(a) => a.fmt(f),
+ &DoubleLit(a) => {
+ let a = f64::from(*a);
+ if a == std::f64::INFINITY {
+ f.write_str("Infinity")
+ } else if a == std::f64::NEG_INFINITY {
+ f.write_str("-Infinity")
+ } else if a.is_nan() {
+ f.write_str("NaN")
+ } else {
+ let s = format!("{}", a);
+ if s.contains("e") || s.contains(".") {
+ f.write_str(&s)
+ } else {
+ write!(f, "{}.0", s)
+ }
+ }
+ }
&TextLit(ref a) => {
f.write_str("\"")?;
for x in a.iter() {
diff --git a/dhall_core/src/text.rs b/dhall_core/src/text.rs
index cd5fef3..eb0d39c 100644
--- a/dhall_core/src/text.rs
+++ b/dhall_core/src/text.rs
@@ -3,7 +3,7 @@ use std::iter::FromIterator;
use std::ops::Add;
use std::rc::Rc;
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InterpolatedText<Note, Embed> {
head: String,
tail: Vec<(Rc<Expr<Note, Embed>>, String)>,