diff options
-rw-r--r-- | dhall/src/normalize.rs | 25 | ||||
-rw-r--r-- | dhall_core/src/text.rs | 51 |
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() - } -} |