summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNadrieril2019-12-22 19:02:18 +0000
committerNadrieril2019-12-22 19:02:18 +0000
commite294450e1e76491e96019b8a3695463e09d1739b (patch)
tree01ef89cdc8c20960636bd9c2f46828c0a95f9427
parent54d7e61ad40682ee24e36288980ee4164ea87c34 (diff)
Implement parsing for record completion
m---------dhall-lang0
-rw-r--r--dhall/build.rs16
-rw-r--r--dhall/src/dhall.pest.visibility2
-rw-r--r--dhall/src/semantics/phase/normalize.rs1
-rw-r--r--dhall/src/semantics/phase/typecheck.rs1
-rw-r--r--dhall/src/syntax/ast/expr.rs2
-rw-r--r--dhall/src/syntax/ast/visitor.rs7
-rw-r--r--dhall/src/syntax/binary/decode.rs5
-rw-r--r--dhall/src/syntax/binary/encode.rs3
-rw-r--r--dhall/src/syntax/text/parser.rs19
-rw-r--r--dhall/src/syntax/text/printer.rs20
11 files changed, 68 insertions, 8 deletions
diff --git a/dhall-lang b/dhall-lang
-Subproject b760b4183c8c589e3572a7f9e049d60e69ca53d
+Subproject e95d863766356c3b5a299c1db1c299df7a31529
diff --git a/dhall/build.rs b/dhall/build.rs
index e06f9b3..ec06ece 100644
--- a/dhall/build.rs
+++ b/dhall/build.rs
@@ -267,6 +267,9 @@ fn generate_tests() -> std::io::Result<()> {
|| path == "unit/RightBiasedMergeEquivalentArguments"
|| path == "unit/NestedRecordProjection"
|| path == "unit/NestedRecordProjectionByType"
+ // TODO: record completion
+ || path == "simple/completion"
+ || path == "unit/Completion"
}),
input_type: FileType::Text,
output_type: Some(FileType::Text),
@@ -299,6 +302,9 @@ fn generate_tests() -> std::io::Result<()> {
|| path == "unit/ToMapAnnotated"
|| path == "unit/ToMapInferTypeFromRecord"
|| path == "simple/toMapEmptyNormalizeAnnotation"
+ // TODO: record completion
+ || path == "simple/completion"
+ || path == "unit/Completion"
}),
input_type: FileType::Text,
output_type: Some(FileType::Text),
@@ -322,6 +328,11 @@ fn generate_tests() -> std::io::Result<()> {
|| path == "unit/NonRecordToMap"
|| path == "unit/ToMapEmptyInvalidAnnotation"
|| path == "unit/ToMapWrongKind"
+ // TODO: record completion
+ || path == "unit/CompletionMissingRequiredField"
+ || path == "unit/CompletionWithWrongDefaultType"
+ || path == "unit/CompletionWithWrongFieldName"
+ || path == "unit/CompletionWithWrongOverridenType"
}),
input_type: FileType::Text,
output_type: None,
@@ -345,6 +356,11 @@ fn generate_tests() -> std::io::Result<()> {
|| path == "unit/NonRecordToMap"
|| path == "unit/ToMapEmptyInvalidAnnotation"
|| path == "unit/ToMapWrongKind"
+ // TODO: record completion
+ || path == "unit/CompletionMissingRequiredField"
+ || path == "unit/CompletionWithWrongDefaultType"
+ || path == "unit/CompletionWithWrongFieldName"
+ || path == "unit/CompletionWithWrongOverridenType"
}),
input_type: FileType::Text,
output_type: None,
diff --git a/dhall/src/dhall.pest.visibility b/dhall/src/dhall.pest.visibility
index 17c1edc..41aa833 100644
--- a/dhall/src/dhall.pest.visibility
+++ b/dhall/src/dhall.pest.visibility
@@ -91,6 +91,7 @@ prefer
lambda
forall
arrow
+# complete
# exponent
numeric_double_literal
minus_infinity_literal
@@ -161,6 +162,7 @@ equivalent_expression
application_expression
first_application_expression
# import_expression
+completion_expression
selector_expression
selector
labels
diff --git a/dhall/src/semantics/phase/normalize.rs b/dhall/src/semantics/phase/normalize.rs
index d81a910..65384c2 100644
--- a/dhall/src/semantics/phase/normalize.rs
+++ b/dhall/src/semantics/phase/normalize.rs
@@ -741,6 +741,7 @@ pub(crate) fn normalize_one_layer(
ExprKind::ProjectionByExpr(_, _) => {
unimplemented!("selection by expression")
}
+ ExprKind::Completion(_, _) => unimplemented!("record completion"),
ExprKind::Merge(ref handlers, ref variant, _) => {
let handlers_borrow = handlers.as_whnf();
diff --git a/dhall/src/semantics/phase/typecheck.rs b/dhall/src/semantics/phase/typecheck.rs
index 856f5c3..c9834e1 100644
--- a/dhall/src/semantics/phase/typecheck.rs
+++ b/dhall/src/semantics/phase/typecheck.rs
@@ -792,6 +792,7 @@ fn type_last_layer(
))
}
ProjectionByExpr(_, _) => unimplemented!("selection by expression"),
+ Completion(_, _) => unimplemented!("record completion"),
};
Ok(match ret {
diff --git a/dhall/src/syntax/ast/expr.rs b/dhall/src/syntax/ast/expr.rs
index 48c48d8..fe49448 100644
--- a/dhall/src/syntax/ast/expr.rs
+++ b/dhall/src/syntax/ast/expr.rs
@@ -163,6 +163,8 @@ pub enum ExprKind<SubExpr, Embed> {
Projection(SubExpr, DupTreeSet<Label>),
/// `e.(t)`
ProjectionByExpr(SubExpr, SubExpr),
+ /// `x::y`
+ Completion(SubExpr, SubExpr),
/// `./some/path`
Import(Import<SubExpr>),
/// Embeds the result of resolving an import
diff --git a/dhall/src/syntax/ast/visitor.rs b/dhall/src/syntax/ast/visitor.rs
index b557995..424048b 100644
--- a/dhall/src/syntax/ast/visitor.rs
+++ b/dhall/src/syntax/ast/visitor.rs
@@ -164,6 +164,9 @@ where
ProjectionByExpr(e, x) => {
ProjectionByExpr(v.visit_subexpr(e)?, v.visit_subexpr(x)?)
}
+ Completion(e, x) => {
+ Completion(v.visit_subexpr(e)?, v.visit_subexpr(x)?)
+ }
Assert(e) => Assert(v.visit_subexpr(e)?),
Import(i) => Import(i.traverse_ref(|e| v.visit_subexpr(e))?),
Embed(a) => Embed(v.visit_embed(a)?),
@@ -281,6 +284,10 @@ where
v.visit_subexpr(e)?;
v.visit_subexpr(x)?;
}
+ Completion(x, y) => {
+ v.visit_subexpr(x)?;
+ v.visit_subexpr(y)?;
+ }
Assert(e) => v.visit_subexpr(e)?,
Import(i) => i.traverse_mut(|e| v.visit_subexpr(e))?,
Embed(a) => v.visit_embed(a)?,
diff --git a/dhall/src/syntax/binary/decode.rs b/dhall/src/syntax/binary/decode.rs
index 254ab07..c18deb5 100644
--- a/dhall/src/syntax/binary/decode.rs
+++ b/dhall/src/syntax/binary/decode.rs
@@ -98,6 +98,11 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result<DecodedExpr, DecodeError> {
let l = Label::from(l.as_str());
Pi(l, x, y)
}
+ [U64(3), U64(13), x, y] => {
+ let x = cbor_value_to_dhall(&x)?;
+ let y = cbor_value_to_dhall(&y)?;
+ Completion(x, y)
+ }
[U64(3), U64(n), x, y] => {
let x = cbor_value_to_dhall(&x)?;
let y = cbor_value_to_dhall(&y)?;
diff --git a/dhall/src/syntax/binary/encode.rs b/dhall/src/syntax/binary/encode.rs
index 25a545c..867fc9c 100644
--- a/dhall/src/syntax/binary/encode.rs
+++ b/dhall/src/syntax/binary/encode.rs
@@ -164,6 +164,9 @@ where
ProjectionByExpr(x, y) => {
ser_seq!(ser; tag(10), expr(x), vec![expr(y)])
}
+ Completion(x, y) => {
+ ser_seq!(ser; tag(3), tag(13), expr(x), expr(y))
+ }
Import(import) => serialize_import(ser, import),
Embed(_) => unimplemented!(
"An expression with resolved imports cannot be binary-encoded"
diff --git a/dhall/src/syntax/text/parser.rs b/dhall/src/syntax/text/parser.rs
index 832472b..fe34aee 100644
--- a/dhall/src/syntax/text/parser.rs
+++ b/dhall/src/syntax/text/parser.rs
@@ -766,6 +766,25 @@ impl DhallParser {
}
#[alias(expression, shortcut = true)]
+ fn completion_expression(input: ParseInput) -> ParseResult<Expr> {
+ Ok(match_nodes!(input.children();
+ [expression(e)] => e,
+ [expression(first), expression(rest)..] => {
+ rest.fold(
+ first,
+ |acc, e| {
+ spanned_union(
+ acc.span(),
+ e.span(),
+ Completion(acc, e),
+ )
+ }
+ )
+ },
+ ))
+ }
+
+ #[alias(expression, shortcut = true)]
fn selector_expression(input: ParseInput) -> ParseResult<Expr> {
Ok(match_nodes!(input.children();
[expression(e)] => e,
diff --git a/dhall/src/syntax/text/printer.rs b/dhall/src/syntax/text/printer.rs
index dff3479..759e7e6 100644
--- a/dhall/src/syntax/text/printer.rs
+++ b/dhall/src/syntax/text/printer.rs
@@ -64,6 +64,7 @@ impl<E: Display + Clone> UnspannedExpr<E> {
Field(a, b) => Field(a.phase(Primitive), b),
Projection(e, ls) => Projection(e.phase(Primitive), ls),
ProjectionByExpr(a, b) => ProjectionByExpr(a.phase(Primitive), b),
+ Completion(a, b) => Completion(a.phase(Primitive), b.phase(Primitive)),
e => e,
}
}
@@ -89,7 +90,7 @@ impl<E: Display + Clone> UnspannedExpr<E> {
// Precedence is magically handled by the ordering of BinOps.
ExprKind::BinOp(op, _, _) => phase > PrintPhase::BinOp(*op),
ExprKind::App(_, _) => phase > PrintPhase::App,
- Field(_, _) | Projection(_, _) | ProjectionByExpr(_, _) => {
+ Field(_, _) | Projection(_, _) | ProjectionByExpr(_, _) | Completion(_, _) => {
phase > PrintPhase::Import
}
_ => false,
@@ -189,13 +190,6 @@ impl<SE: Display + Clone, E: Display> Display for ExprKind<SE, E> {
Field(a, b) => {
write!(f, "{}.{}", a, b)?;
}
- Projection(e, ls) => {
- write!(f, "{}.", e)?;
- fmt_list("{ ", ", ", " }", ls, f, Display::fmt)?;
- }
- ProjectionByExpr(a, b) => {
- write!(f, "{}.({})", a, b)?;
- }
Var(a) => a.fmt(f)?,
Const(k) => k.fmt(f)?,
Builtin(v) => v.fmt(f)?,
@@ -224,6 +218,16 @@ impl<SE: Display + Clone, E: Display> Display for ExprKind<SE, E> {
}
Ok(())
})?,
+ Projection(e, ls) => {
+ write!(f, "{}.", e)?;
+ fmt_list("{ ", ", ", " }", ls, f, Display::fmt)?;
+ }
+ ProjectionByExpr(a, b) => {
+ write!(f, "{}.({})", a, b)?;
+ }
+ Completion(a, b) => {
+ write!(f, "{}::{}", a, b)?;
+ }
Import(a) => a.fmt(f)?,
Embed(a) => a.fmt(f)?,
}