summaryrefslogtreecommitdiff
path: root/dhall
diff options
context:
space:
mode:
authorNadrieril Feneanar2020-03-04 22:41:41 +0000
committerGitHub2020-03-04 22:41:41 +0000
commit2ca97e97f1718141d826a78ab3da8197b2d55c69 (patch)
tree906e09e2686356c91a3a2ea4c373ad99827c7c13 /dhall
parent5f720252a00bf2a45fef7f4c0855b79bd3932600 (diff)
parentd5874d9dcedc15eaccb942cc8f45f26b2335ed2d (diff)
Merge pull request #133 from basile-henry/record-projection-by-expression
Record projection by expression
Diffstat (limited to '')
-rw-r--r--dhall/build.rs9
-rw-r--r--dhall/src/semantics/nze/normalize.rs37
-rw-r--r--dhall/src/syntax/ast/expr.rs2
3 files changed, 36 insertions, 12 deletions
diff --git a/dhall/build.rs b/dhall/build.rs
index 3ac2901..d9bceeb 100644
--- a/dhall/build.rs
+++ b/dhall/build.rs
@@ -281,13 +281,6 @@ fn generate_tests() -> std::io::Result<()> {
path == "simple/integerToDouble"
// Too slow
|| path == "remoteSystems"
- // TODO: projection by expression
- || path == "unit/RecordProjectionByTypeEmpty"
- || path == "unit/RecordProjectionByTypeNonEmpty"
- || path == "unit/RecordProjectionByTypeNormalizeProjection"
- || path == "unit/RecordProjectionByTypeWithinFieldSelection"
- || path == "unit/RecursiveRecordMergeWithinFieldSelection1"
- || path == "unit/NestedRecordProjectionByType"
// TODO: fix Double/show
|| path == "prelude/JSON/number/1"
// TODO: doesn't typecheck
@@ -298,8 +291,8 @@ fn generate_tests() -> std::io::Result<()> {
|| path == "simplifications/rightBiasedMergeWithinRecordProjectionWithinFieldSelection1"
|| path == "simplifications/rightBiasedMergeWithinRecursiveRecordMergeWithinFieldselection"
|| path == "simplifications/issue661"
- || path == "unit/RecordProjectionWithinFieldSelection"
|| path == "unit/RecursiveRecordMergeWithinFieldSelection0"
+ || path == "unit/RecursiveRecordMergeWithinFieldSelection1"
|| path == "unit/RecursiveRecordMergeWithinFieldSelection2"
|| path == "unit/RecursiveRecordMergeWithinFieldSelection3"
}),
diff --git a/dhall/src/semantics/nze/normalize.rs b/dhall/src/semantics/nze/normalize.rs
index 604db8f..dedd659 100644
--- a/dhall/src/semantics/nze/normalize.rs
+++ b/dhall/src/semantics/nze/normalize.rs
@@ -372,11 +372,42 @@ pub(crate) fn normalize_one_layer(expr: ExprKind<Nir>, env: &NzEnv) -> NirKind {
},
_ => Ret::Expr(expr),
},
+ PartialExpr(ExprKind::Projection(v2, _)) => {
+ return normalize_one_layer(
+ ExprKind::Field(v2.clone(), l.clone()),
+ env,
+ )
+ }
_ => Ret::Expr(expr),
},
- ExprKind::ProjectionByExpr(_, _) => {
- unimplemented!("selection by expression")
- }
+
+ ExprKind::ProjectionByExpr(ref v, ref t) => match dbg!(v).kind() {
+ RecordLit(kvs) => match dbg!(t).kind() {
+ RecordType(kts) => Ret::NirKind(RecordLit(
+ kts.iter()
+ .filter_map(|(l, _)| {
+ kvs.get(l).map(|x| (l.clone(), x.clone()))
+ })
+ .collect(),
+ )),
+ _ => Ret::Expr(expr),
+ },
+ _ => match dbg!(t).kind() {
+ RecordType(kts) => {
+ use crate::syntax::map::DupTreeSet;
+ use std::iter::FromIterator;
+
+ let ts = DupTreeSet::from_iter(
+ kts.iter().map(|(l, _)| l.clone()),
+ );
+ return normalize_one_layer(
+ ExprKind::Projection(v.clone(), ts),
+ env,
+ );
+ }
+ _ => Ret::Expr(expr),
+ },
+ },
ExprKind::Merge(ref handlers, ref variant, _) => {
match handlers.kind() {
diff --git a/dhall/src/syntax/ast/expr.rs b/dhall/src/syntax/ast/expr.rs
index ce0a3d2..bb1a5b3 100644
--- a/dhall/src/syntax/ast/expr.rs
+++ b/dhall/src/syntax/ast/expr.rs
@@ -178,7 +178,7 @@ pub enum ExprKind<SubExpr> {
Field(SubExpr, Label),
/// `e.{ x, y, z }`
Projection(SubExpr, DupTreeSet<Label>),
- /// `e.(t)`
+ /// `e.(s)`
ProjectionByExpr(SubExpr, SubExpr),
/// `x::y`
Completion(SubExpr, SubExpr),