From c2cb7d38dfec05b6337aa5dcd0dc3068e73c9a58 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 7 Aug 2019 22:25:35 +0200 Subject: Flatten nested let bindings --- dhall-lang | 2 +- dhall/build.rs | 3 +++ dhall/src/phase/binary.rs | 46 ++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/dhall-lang b/dhall-lang index ebda6c1..95dd430 160000 --- a/dhall-lang +++ b/dhall-lang @@ -1 +1 @@ -Subproject commit ebda6c150056f4e7a801ee11f611be86ce694e8a +Subproject commit 95dd43037ce516907b0919a6cf2e8a9089b67f73 diff --git a/dhall/build.rs b/dhall/build.rs index 983fcad..29e86e3 100644 --- a/dhall/build.rs +++ b/dhall/build.rs @@ -173,6 +173,9 @@ fn main() -> std::io::Result<()> { || path == "success/unit/recordProjectionByExpression" // TODO: test is wrong || path == "success/unit/BuiltinNaturalSubtract" + // TODO: toMap + || path == "success/unit/ToMap" + || path == "success/unit/ToMapAnnotated" }, )?; diff --git a/dhall/src/phase/binary.rs b/dhall/src/phase/binary.rs index cab3c8e..5e7eb40 100644 --- a/dhall/src/phase/binary.rs +++ b/dhall/src/phase/binary.rs @@ -477,12 +477,23 @@ where ser_seq!(ser; tag(2), expr(x), expr(y)) } Pi(l, x, y) => ser_seq!(ser; tag(2), label(l), expr(x), expr(y)), - // TODO: multilet - Let(l, None, x, y) => { - ser_seq!(ser; tag(25), label(l), null(), expr(x), expr(y)) - } - Let(l, Some(t), x, y) => { - ser_seq!(ser; tag(25), label(l), expr(t), expr(x), expr(y)) + Let(_, _, _, _) => { + let (bound_e, bindings) = collect_nested_lets(e); + let count = 1 + 3 * bindings.len() + 1; + + use serde::ser::SerializeSeq; + let mut ser_seq = ser.serialize_seq(Some(count))?; + ser_seq.serialize_element(&tag(25))?; + for (l, t, v) in bindings { + ser_seq.serialize_element(&label(l))?; + match t { + Some(t) => ser_seq.serialize_element(&expr(t))?, + None => ser_seq.serialize_element(&null())?, + } + ser_seq.serialize_element(&expr(v))?; + } + ser_seq.serialize_element(&expr(bound_e))?; + ser_seq.end() } App(_, _) => { let (f, args) = collect_nested_applications(e); @@ -677,3 +688,26 @@ fn collect_nested_applications<'a, N, E>( let e = go(e, &mut vec); (e, vec) } + +type LetBinding<'a, N, E> = + (&'a Label, &'a Option>, &'a SubExpr); + +fn collect_nested_lets<'a, N, E>( + e: &'a SubExpr, +) -> (&'a SubExpr, Vec>) { + fn go<'a, N, E>( + e: &'a SubExpr, + vec: &mut Vec>, + ) -> &'a SubExpr { + match e.as_ref() { + ExprF::Let(l, t, v, e) => { + vec.push((l, t, v)); + go(e, vec) + } + _ => e, + } + } + let mut vec = vec![]; + let e = go(e, &mut vec); + (e, vec) +} -- cgit v1.2.3