summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dhall/src/normalize.rs25
-rw-r--r--dhall_core/src/text.rs51
2 files changed, 40 insertions, 36 deletions
diff --git a/dhall/src/normalize.rs b/dhall/src/normalize.rs
index ec25010..9e7c531 100644
--- a/dhall/src/normalize.rs
+++ b/dhall/src/normalize.rs
@@ -667,11 +667,16 @@ fn normalize_whnf(ctx: NormalizationContext, expr: InputSubExpr) -> WHNF {
match b {
WHNF::BoolLit(true) => normalize_whnf(ctx, e1.clone()),
WHNF::BoolLit(false) => normalize_whnf(ctx, e2.clone()),
- _ => normalize_last_layer(ExprF::BoolIf(
- b,
- normalize_whnf(ctx.clone(), e1.clone()),
- normalize_whnf(ctx, e2.clone()),
- )),
+ b => {
+ let e1 = normalize_whnf(ctx.clone(), e1.clone());
+ let e2 = normalize_whnf(ctx, e2.clone());
+ match (e1, e2) {
+ (WHNF::BoolLit(true), WHNF::BoolLit(false)) => b,
+ (e1, e2) => {
+ normalize_last_layer(ExprF::BoolIf(b, e1, e2))
+ }
+ }
+ }
}
}
expr => {
@@ -736,6 +741,8 @@ fn normalize_last_layer(expr: ExprF<WHNF, Label, X, X>) -> WHNF {
x.append(&mut y);
TextLit(x)
}
+ ExprF::BinOp(TextAppend, TextLit(x), y) if x.is_empty() => y,
+ ExprF::BinOp(TextAppend, x, TextLit(y)) if y.is_empty() => x,
ExprF::Field(UnionType(ctx, kts), l) => UnionConstructor(ctx, l, kts),
ExprF::Field(RecordLit(mut kvs), l) => match kvs.remove(&l) {
@@ -981,7 +988,7 @@ mod spec_tests {
// norm!(success_unit_IfAlternativesIdentical, "unit/IfAlternativesIdentical");
norm!(success_unit_IfFalse, "unit/IfFalse");
norm!(success_unit_IfNormalizePredicateAndBranches, "unit/IfNormalizePredicateAndBranches");
- // norm!(success_unit_IfTrivial, "unit/IfTrivial");
+ norm!(success_unit_IfTrivial, "unit/IfTrivial");
norm!(success_unit_IfTrue, "unit/IfTrue");
norm!(success_unit_Integer, "unit/Integer");
norm!(success_unit_IntegerNegative, "unit/IntegerNegative");
@@ -1075,9 +1082,9 @@ mod spec_tests {
norm!(success_unit_OperatorPlusNormalizeArguments, "unit/OperatorPlusNormalizeArguments");
norm!(success_unit_OperatorPlusOneAndOne, "unit/OperatorPlusOneAndOne");
norm!(success_unit_OperatorPlusRhsZero, "unit/OperatorPlusRhsZero");
- // norm!(success_unit_OperatorTextConcatenateLhsEmpty, "unit/OperatorTextConcatenateLhsEmpty");
- // norm!(success_unit_OperatorTextConcatenateNormalizeArguments, "unit/OperatorTextConcatenateNormalizeArguments");
- // norm!(success_unit_OperatorTextConcatenateRhsEmpty, "unit/OperatorTextConcatenateRhsEmpty");
+ norm!(success_unit_OperatorTextConcatenateLhsEmpty, "unit/OperatorTextConcatenateLhsEmpty");
+ norm!(success_unit_OperatorTextConcatenateNormalizeArguments, "unit/OperatorTextConcatenateNormalizeArguments");
+ norm!(success_unit_OperatorTextConcatenateRhsEmpty, "unit/OperatorTextConcatenateRhsEmpty");
norm!(success_unit_OperatorTextConcatenateTextText, "unit/OperatorTextConcatenateTextText");
norm!(success_unit_OperatorTimesLhsOne, "unit/OperatorTimesLhsOne");
norm!(success_unit_OperatorTimesLhsZero, "unit/OperatorTimesLhsZero");
diff --git a/dhall_core/src/text.rs b/dhall_core/src/text.rs
index ff5c441..83643d9 100644
--- a/dhall_core/src/text.rs
+++ b/dhall_core/src/text.rs
@@ -1,5 +1,4 @@
use std::iter::FromIterator;
-use std::ops::Add;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InterpolatedText<SubExpr> {
@@ -33,6 +32,16 @@ pub enum InterpolatedTextContents<SubExpr> {
Expr(SubExpr),
}
+impl<SubExpr> InterpolatedTextContents<SubExpr> {
+ pub fn is_empty(&self) -> bool {
+ use InterpolatedTextContents::{Expr, Text};
+ match self {
+ Expr(_) => false,
+ Text(s) => s.is_empty(),
+ }
+ }
+}
+
impl<SubExpr> InterpolatedText<SubExpr> {
pub fn traverse_ref<'a, SubExpr2, E, F>(
&'a self,
@@ -51,13 +60,6 @@ impl<SubExpr> InterpolatedText<SubExpr> {
})
}
- pub fn as_ref(&self) -> InterpolatedText<&SubExpr> {
- InterpolatedText {
- head: self.head.clone(),
- tail: self.tail.iter().map(|(e, s)| (e, s.clone())).collect(),
- }
- }
-
pub fn iter<'a>(
&'a self,
) -> impl Iterator<Item = InterpolatedTextContents<SubExpr>> + 'a
@@ -65,24 +67,26 @@ impl<SubExpr> InterpolatedText<SubExpr> {
SubExpr: Clone,
{
use std::iter::once;
- once(InterpolatedTextContents::Text(self.head.clone())).chain(
- self.tail.iter().flat_map(|(e, s)| {
- once(InterpolatedTextContents::Expr(SubExpr::clone(e)))
- .chain(once(InterpolatedTextContents::Text(s.clone())))
- }),
- )
+ use InterpolatedTextContents::{Expr, Text};
+ once(Text(self.head.clone()))
+ .chain(self.tail.iter().flat_map(|(e, s)| {
+ once(Expr(SubExpr::clone(e))).chain(once(Text(s.clone())))
+ }))
+ .filter(|c| !c.is_empty())
}
pub fn into_iter(
self,
) -> impl Iterator<Item = InterpolatedTextContents<SubExpr>> {
use std::iter::once;
- once(InterpolatedTextContents::Text(self.head)).chain(
- self.tail.into_iter().flat_map(|(e, s)| {
- once(InterpolatedTextContents::Expr(e))
- .chain(once(InterpolatedTextContents::Text(s)))
- }),
- )
+ use InterpolatedTextContents::{Expr, Text};
+ once(Text(self.head))
+ .chain(
+ self.tail
+ .into_iter()
+ .flat_map(|(e, s)| once(Expr(e)).chain(once(Text(s)))),
+ )
+ .filter(|c| !c.is_empty())
}
}
@@ -110,10 +114,3 @@ impl<SubExpr> FromIterator<InterpolatedTextContents<SubExpr>>
res
}
}
-
-impl<SubExpr: Clone> Add for &InterpolatedText<SubExpr> {
- type Output = InterpolatedText<SubExpr>;
- fn add(self, rhs: &InterpolatedText<SubExpr>) -> Self::Output {
- self.iter().chain(rhs.iter()).collect()
- }
-}