summaryrefslogtreecommitdiff
path: root/dhall
diff options
context:
space:
mode:
authorNadrieril2020-02-20 19:04:13 +0000
committerNadrieril2020-02-20 19:04:13 +0000
commit6642077368497583113d685d351ec93d230ffcad (patch)
tree51f42d5525bdcde81834a28b2b3742472cbac56a /dhall
parent0e07c9cd012efaeae7e1c50a3499a13aef4d2b61 (diff)
Add support for dotted field syntax
Diffstat (limited to 'dhall')
-rw-r--r--dhall/build.rs20
-rw-r--r--dhall/src/syntax/ast/span.rs3
-rw-r--r--dhall/src/syntax/text/parser.rs13
-rw-r--r--dhall/tests/parser/failure/spacing/MergeNoSpace2.txt2
-rw-r--r--dhall/tests/parser/failure/spacing/RecordTypeNoSpace.txt2
5 files changed, 16 insertions, 24 deletions
diff --git a/dhall/build.rs b/dhall/build.rs
index 88a2145..7c62083 100644
--- a/dhall/build.rs
+++ b/dhall/build.rs
@@ -375,26 +375,6 @@ fn convert_abnf_to_pest() -> std::io::Result<()> {
rules.remove("url_path");
writeln!(&mut file, "url_path = _{{ path }}")?;
- // TODO: workaround to simplify record parsing
- rules.remove("non_empty_record_type_or_literal");
- rules.remove("non_empty_record_literal");
- rules.remove("non_empty_record_type");
- writeln!(
- &mut file,
- "non_empty_record_type_or_literal = {{ non_empty_record_literal | \
- non_empty_record_type }}"
- )?;
- writeln!(
- &mut file,
- "non_empty_record_literal = {{ record_literal_entry ~ (whsp ~ ^\",\" \
- ~ whsp ~ record_literal_entry)*}}"
- )?;
- writeln!(
- &mut file,
- "non_empty_record_type = {{ record_type_entry ~ (whsp ~ ^\",\" ~ whsp \
- ~ record_type_entry)* }}"
- )?;
-
// Work around some greediness issue in the grammar.
rules.remove("missing");
writeln!(
diff --git a/dhall/src/syntax/ast/span.rs b/dhall/src/syntax/ast/span.rs
index 6d017f6..7c004c5 100644
--- a/dhall/src/syntax/ast/span.rs
+++ b/dhall/src/syntax/ast/span.rs
@@ -18,8 +18,9 @@ pub(crate) struct ParsedSpan {
pub(crate) enum Span {
/// A location in the source text
Parsed(ParsedSpan),
- /// Desugaring of duplicate fields
+ /// Desugarings
DuplicateRecordFieldsSugar,
+ DottedFieldSugar,
/// For expressions obtained from decoding binary
Decoded,
/// For expressions constructed during normalization/typecheck
diff --git a/dhall/src/syntax/text/parser.rs b/dhall/src/syntax/text/parser.rs
index f74794b..ba64a75 100644
--- a/dhall/src/syntax/text/parser.rs
+++ b/dhall/src/syntax/text/parser.rs
@@ -915,7 +915,18 @@ impl DhallParser {
fn record_literal_entry(input: ParseInput) -> ParseResult<(Label, Expr)> {
Ok(match_nodes!(input.into_children();
- [label(name), expression(expr)] => (name, expr)
+ [label(name), expression(expr)] => (name, expr),
+ [label(first_name), label(names).., expression(expr)] => {
+ // Desugar dotted field syntax into nested records
+ let expr = names.rev().fold(expr, |e, l| {
+ let map = Some((l, e)).into_iter().collect();
+ Expr::new(
+ RecordLit(map),
+ Span::DottedFieldSugar,
+ )
+ });
+ (first_name, expr)
+ },
))
}
diff --git a/dhall/tests/parser/failure/spacing/MergeNoSpace2.txt b/dhall/tests/parser/failure/spacing/MergeNoSpace2.txt
index 77314e0..96d937b 100644
--- a/dhall/tests/parser/failure/spacing/MergeNoSpace2.txt
+++ b/dhall/tests/parser/failure/spacing/MergeNoSpace2.txt
@@ -3,4 +3,4 @@
1 | merge x(y)␊
| ^---
|
- = expected missing, non_empty_list_literal, double_quote_literal, single_quote_literal, if_, merge, NaN, Some_, toMap, assert, forall, numeric_double_literal, minus_infinity_literal, plus_infinity_literal, natural_literal, integer_literal, or import_hashed
+ = expected missing, double_quote_literal, single_quote_literal, if_, merge, non_empty_list_literal, NaN, Some_, toMap, assert, forall, numeric_double_literal, minus_infinity_literal, plus_infinity_literal, natural_literal, integer_literal, or import_hashed
diff --git a/dhall/tests/parser/failure/spacing/RecordTypeNoSpace.txt b/dhall/tests/parser/failure/spacing/RecordTypeNoSpace.txt
index f6427a4..9c1eaef 100644
--- a/dhall/tests/parser/failure/spacing/RecordTypeNoSpace.txt
+++ b/dhall/tests/parser/failure/spacing/RecordTypeNoSpace.txt
@@ -3,4 +3,4 @@
1 | { x :T }␊
| ^---
|
- = expected non_empty_record_type_or_literal or empty_record_literal
+ = expected empty_record_literal or non_empty_record_type_or_literal