From 82b08fa01b0980e7998760fe3cbba50c855ce454 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 9 May 2019 01:20:35 +0200 Subject: Update dhall-lang submodule --- README.md | 2 +- dhall-lang | 2 +- dhall/src/phase/normalize.rs | 36 ++++++++++++------- dhall/src/phase/typecheck.rs | 16 +++++++-- dhall_syntax/src/core/text.rs | 12 +++++++ dhall_syntax/src/parser.rs | 83 +++++++++++++++++++++++++++++-------------- 6 files changed, 107 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 68f157a..3212b2e 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ This is still quite unstable so use at your own risk. Documentation is severely - Parsing: 100% - Imports: 10% -- Normalization: 83% +- Normalization: 99% - Typechecking: 83% You can see what's missing from the commented out tests in `dhall/src/normalize.rs` and `dhall/src/typecheck.rs`. diff --git a/dhall-lang b/dhall-lang index 4349094..f12c7b5 160000 --- a/dhall-lang +++ b/dhall-lang @@ -1 +1 @@ -Subproject commit 43490948b89dc8ed1a8d2d4d89edc962f6852248 +Subproject commit f12c7b5c37b9667162255d9562c811896965effd diff --git a/dhall/src/phase/normalize.rs b/dhall/src/phase/normalize.rs index 048c25e..5672bc4 100644 --- a/dhall/src/phase/normalize.rs +++ b/dhall/src/phase/normalize.rs @@ -838,18 +838,20 @@ mod spec_tests { norm!(success_prelude_Text_concat_1, "prelude/Text/concat/1"); norm!(success_prelude_Text_concatMap_0, "prelude/Text/concatMap/0"); norm!(success_prelude_Text_concatMap_1, "prelude/Text/concatMap/1"); - // norm!(success_prelude_Text_concatMapSep_0, "prelude/Text/concatMapSep/0"); - // norm!(success_prelude_Text_concatMapSep_1, "prelude/Text/concatMapSep/1"); - // norm!(success_prelude_Text_concatSep_0, "prelude/Text/concatSep/0"); - // norm!(success_prelude_Text_concatSep_1, "prelude/Text/concatSep/1"); - // norm!(success_prelude_Text_show_0, "prelude/Text/show/0"); - // norm!(success_prelude_Text_show_1, "prelude/Text/show/1"); - // norm!(success_remoteSystems, "remoteSystems"); + norm!(success_prelude_Text_concatMapSep_0, "prelude/Text/concatMapSep/0"); + norm!(success_prelude_Text_concatMapSep_1, "prelude/Text/concatMapSep/1"); + norm!(success_prelude_Text_concatSep_0, "prelude/Text/concatSep/0"); + norm!(success_prelude_Text_concatSep_1, "prelude/Text/concatSep/1"); + norm!(success_prelude_Text_show_0, "prelude/Text/show/0"); + norm!(success_prelude_Text_show_1, "prelude/Text/show/1"); + norm!(success_remoteSystems, "remoteSystems"); norm!(success_simple_doubleShow, "simple/doubleShow"); norm!(success_simple_enum, "simple/enum"); norm!(success_simple_integerShow, "simple/integerShow"); // norm!(success_simple_integerToDouble, "simple/integerToDouble"); + norm!(success_simple_letAvoidCapture, "simple/letAvoidCapture"); + norm!(success_simple_letenum, "simple/letenum"); norm!(success_simple_letlet, "simple/letlet"); norm!(success_simple_listBuild, "simple/listBuild"); norm!(success_simple_multiLine, "simple/multiLine"); @@ -860,6 +862,7 @@ mod spec_tests { norm!(success_simple_optionalBuild, "simple/optionalBuild"); norm!(success_simple_optionalBuildFold, "simple/optionalBuildFold"); norm!(success_simple_optionalFold, "simple/optionalFold"); + norm!(success_simple_simpleAddition, "simple/simpleAddition"); norm!(success_simple_sortOperator, "simple/sortOperator"); norm!(success_simplifications_and, "simplifications/and"); norm!(success_simplifications_eq, "simplifications/eq"); @@ -867,6 +870,7 @@ mod spec_tests { norm!(success_simplifications_ne, "simplifications/ne"); norm!(success_simplifications_or, "simplifications/or"); + norm!(success_unit_BareInterpolation, "unit/BareInterpolation"); norm!(success_unit_Bool, "unit/Bool"); norm!(success_unit_Double, "unit/Double"); norm!(success_unit_DoubleLiteral, "unit/DoubleLiteral"); @@ -978,6 +982,8 @@ mod spec_tests { norm!(success_unit_OperatorPlusRhsZero, "unit/OperatorPlusRhsZero"); norm!(success_unit_OperatorTextConcatenateLhsEmpty, "unit/OperatorTextConcatenateLhsEmpty"); norm!(success_unit_OperatorTextConcatenateLhsNonEmpty, "unit/OperatorTextConcatenateLhsNonEmpty"); + norm!(success_unit_OperatorTextConcatenateRhsEmpty, "unit/OperatorTextConcatenateRhsEmpty"); + norm!(success_unit_OperatorTextConcatenateRhsNonEmpty, "unit/OperatorTextConcatenateRhsNonEmpty"); norm!(success_unit_OperatorTextConcatenateTextText, "unit/OperatorTextConcatenateTextText"); norm!(success_unit_OperatorTimesLhsOne, "unit/OperatorTimesLhsOne"); norm!(success_unit_OperatorTimesLhsZero, "unit/OperatorTimesLhsZero"); @@ -1037,10 +1043,14 @@ mod spec_tests { norm!(success_unit_UnionTypeNormalizeArguments, "unit/UnionTypeNormalizeArguments"); norm!(success_unit_Variable, "unit/Variable"); - alpha_norm!(alpha_success_unit_FunctionBindingUnderscore, "unit/FunctionBindingUnderscore"); - alpha_norm!(alpha_success_unit_FunctionBindingX, "unit/FunctionBindingX"); - alpha_norm!(alpha_success_unit_FunctionNestedBindingX, "unit/FunctionNestedBindingX"); - alpha_norm!(alpha_success_unit_FunctionTypeBindingUnderscore, "unit/FunctionTypeBindingUnderscore"); - alpha_norm!(alpha_success_unit_FunctionTypeBindingX, "unit/FunctionTypeBindingX"); - alpha_norm!(alpha_success_unit_FunctionTypeNestedBindingX, "unit/FunctionTypeNestedBindingX"); + alpha_norm!(regression_preludeBoolFold, "regression/preludeBoolFold"); + alpha_norm!(unit_FunctionBindingUnderscore, "unit/FunctionBindingUnderscore"); + alpha_norm!(unit_FunctionBindingX, "unit/FunctionBindingX"); + alpha_norm!(unit_FunctionNestedBindingX, "unit/FunctionNestedBindingX"); + alpha_norm!(unit_FunctionNestedBindingXX, "unit/FunctionNestedBindingXX"); + // alpha_norm!(unit_FunctionNestedBindingXXFree, "unit/FunctionNestedBindingXXFree"); + alpha_norm!(unit_FunctionNestedBindingXY, "unit/FunctionNestedBindingXY"); + alpha_norm!(unit_FunctionTypeBindingUnderscore, "unit/FunctionTypeBindingUnderscore"); + alpha_norm!(unit_FunctionTypeBindingX, "unit/FunctionTypeBindingX"); + alpha_norm!(unit_FunctionTypeNestedBindingX, "unit/FunctionTypeNestedBindingX"); } diff --git a/dhall/src/phase/typecheck.rs b/dhall/src/phase/typecheck.rs index fa37379..265ce08 100644 --- a/dhall/src/phase/typecheck.rs +++ b/dhall/src/phase/typecheck.rs @@ -1007,6 +1007,7 @@ mod spec_tests { tc_failure!(tc_failure_combineMixedRecords, "combineMixedRecords"); // tc_failure!(tc_failure_duplicateFields, "duplicateFields"); tc_failure!(tc_failure_hurkensParadox, "hurkensParadox"); + // tc_failure!(tc_failure_importBoundary, "importBoundary"); tc_failure!(tc_failure_mixedUnions, "mixedUnions"); tc_failure!(tc_failure_preferMixedRecords, "preferMixedRecords"); tc_failure!(tc_failure_unit_FunctionApplicationArgumentNotMatch, "unit/FunctionApplicationArgumentNotMatch"); @@ -1039,6 +1040,7 @@ mod spec_tests { tc_failure!(tc_failure_unit_OperatorEqualNotBool, "unit/OperatorEqualNotBool"); tc_failure!(tc_failure_unit_OperatorListConcatenateLhsNotList, "unit/OperatorListConcatenateLhsNotList"); tc_failure!(tc_failure_unit_OperatorListConcatenateListsNotMatch, "unit/OperatorListConcatenateListsNotMatch"); + tc_failure!(tc_failure_unit_OperatorListConcatenateNotListsButMatch, "unit/OperatorListConcatenateNotListsButMatch"); tc_failure!(tc_failure_unit_OperatorListConcatenateRhsNotList, "unit/OperatorListConcatenateRhsNotList"); tc_failure!(tc_failure_unit_OperatorNotEqualNotBool, "unit/OperatorNotEqualNotBool"); tc_failure!(tc_failure_unit_OperatorOrNotBool, "unit/OperatorOrNotBool"); @@ -1083,8 +1085,8 @@ mod spec_tests { tc_failure!(tc_failure_unit_UnionTypeNotType, "unit/UnionTypeNotType"); tc_failure!(tc_failure_unit_VariableFree, "unit/VariableFree"); - // ti_success!(ti_success_simple_alternativesAreTypes, "simple/alternativesAreTypes"); - // ti_success!(ti_success_simple_kindParameter, "simple/kindParameter"); + ti_success!(ti_success_simple_alternativesAreTypes, "simple/alternativesAreTypes"); + ti_success!(ti_success_simple_kindParameter, "simple/kindParameter"); ti_success!(ti_success_unit_Bool, "unit/Bool"); ti_success!(ti_success_unit_Double, "unit/Double"); ti_success!(ti_success_unit_DoubleLiteral, "unit/DoubleLiteral"); @@ -1157,6 +1159,10 @@ mod spec_tests { ti_success!(ti_success_unit_OptionalBuild, "unit/OptionalBuild"); ti_success!(ti_success_unit_OptionalFold, "unit/OptionalFold"); ti_success!(ti_success_unit_RecordEmpty, "unit/RecordEmpty"); + ti_success!(ti_success_unit_RecordNestedKind, "unit/RecordNestedKind"); + ti_success!(ti_success_unit_RecordNestedKindLike, "unit/RecordNestedKindLike"); + ti_success!(ti_success_unit_RecordNestedType, "unit/RecordNestedType"); + ti_success!(ti_success_unit_RecordNestedTypeLike, "unit/RecordNestedTypeLike"); ti_success!(ti_success_unit_RecordOneKind, "unit/RecordOneKind"); ti_success!(ti_success_unit_RecordOneType, "unit/RecordOneType"); ti_success!(ti_success_unit_RecordOneValue, "unit/RecordOneValue"); @@ -1170,15 +1176,20 @@ mod spec_tests { ti_success!(ti_success_unit_RecordType, "unit/RecordType"); ti_success!(ti_success_unit_RecordTypeEmpty, "unit/RecordTypeEmpty"); ti_success!(ti_success_unit_RecordTypeKind, "unit/RecordTypeKind"); + ti_success!(ti_success_unit_RecordTypeKindLike, "unit/RecordTypeKindLike"); + ti_success!(ti_success_unit_RecordTypeNestedKind, "unit/RecordTypeNestedKind"); + ti_success!(ti_success_unit_RecordTypeNestedKindLike, "unit/RecordTypeNestedKindLike"); ti_success!(ti_success_unit_RecordTypeType, "unit/RecordTypeType"); // ti_success!(ti_success_unit_RecursiveRecordMergeLhsEmpty, "unit/RecursiveRecordMergeLhsEmpty"); // ti_success!(ti_success_unit_RecursiveRecordMergeRecursively, "unit/RecursiveRecordMergeRecursively"); + // ti_success!(ti_success_unit_RecursiveRecordMergeRecursivelyKinds, "unit/RecursiveRecordMergeRecursivelyKinds"); // ti_success!(ti_success_unit_RecursiveRecordMergeRecursivelyTypes, "unit/RecursiveRecordMergeRecursivelyTypes"); // ti_success!(ti_success_unit_RecursiveRecordMergeRhsEmpty, "unit/RecursiveRecordMergeRhsEmpty"); // ti_success!(ti_success_unit_RecursiveRecordMergeTwo, "unit/RecursiveRecordMergeTwo"); // ti_success!(ti_success_unit_RecursiveRecordMergeTwoKinds, "unit/RecursiveRecordMergeTwoKinds"); // ti_success!(ti_success_unit_RecursiveRecordMergeTwoTypes, "unit/RecursiveRecordMergeTwoTypes"); // ti_success!(ti_success_unit_RecursiveRecordTypeMergeRecursively, "unit/RecursiveRecordTypeMergeRecursively"); + // ti_success!(ti_success_unit_RecursiveRecordTypeMergeRecursivelyKinds, "unit/RecursiveRecordTypeMergeRecursivelyKinds"); // ti_success!(ti_success_unit_RecursiveRecordTypeMergeRecursivelyTypes, "unit/RecursiveRecordTypeMergeRecursivelyTypes"); // ti_success!(ti_success_unit_RecursiveRecordTypeMergeRhsEmpty, "unit/RecursiveRecordTypeMergeRhsEmpty"); // ti_success!(ti_success_unit_RecursiveRecordTypeMergeTwo, "unit/RecursiveRecordTypeMergeTwo"); @@ -1199,6 +1210,7 @@ mod spec_tests { ti_success!(ti_success_unit_Type, "unit/Type"); ti_success!(ti_success_unit_TypeAnnotation, "unit/TypeAnnotation"); ti_success!(ti_success_unit_TypeAnnotationSort, "unit/TypeAnnotationSort"); + ti_success!(ti_success_unit_UnionConstructorEmptyField, "unit/UnionConstructorEmptyField"); ti_success!(ti_success_unit_UnionConstructorField, "unit/UnionConstructorField"); ti_success!(ti_success_unit_UnionOne, "unit/UnionOne"); ti_success!(ti_success_unit_UnionTypeEmpty, "unit/UnionTypeEmpty"); diff --git a/dhall_syntax/src/core/text.rs b/dhall_syntax/src/core/text.rs index 83643d9..e79a86b 100644 --- a/dhall_syntax/src/core/text.rs +++ b/dhall_syntax/src/core/text.rs @@ -43,6 +43,18 @@ impl InterpolatedTextContents { } impl InterpolatedText { + pub fn head(&self) -> &str { + &self.head + } + + pub fn head_mut(&mut self) -> &mut String { + &mut self.head + } + + pub fn is_empty(&self) -> bool { + self.head.is_empty() && self.tail.is_empty() + } + pub fn traverse_ref<'a, SubExpr2, E, F>( &'a self, mut f: F, diff --git a/dhall_syntax/src/parser.rs b/dhall_syntax/src/parser.rs index 51dbfd2..607d19c 100644 --- a/dhall_syntax/src/parser.rs +++ b/dhall_syntax/src/parser.rs @@ -319,6 +319,47 @@ fn can_be_shortcutted(rule: Rule) -> bool { } } +// Trim the shared indent off of a vec of lines, as defined by the Dhall semantics of multiline +// literals. +fn trim_indent(lines: &mut Vec) { + let is_indent = |c: char| c == ' ' || c == '\t'; + + // There is at least one line so this is safe + let last_line_head = lines.last().unwrap().head(); + let indent_chars = last_line_head + .char_indices() + .take_while(|(_, c)| is_indent(*c)); + let mut min_indent_idx = match indent_chars.last() { + Some((i, _)) => i, + // If there is no indent char, then no indent needs to be stripped + None => return, + }; + + for line in lines.iter() { + // Ignore empty lines + if line.is_empty() { + continue; + } + // Take chars from line while they match the current minimum indent. + let indent_chars = last_line_head[0..=min_indent_idx] + .char_indices() + .zip(line.head().chars()) + .take_while(|((_, c1), c2)| c1 == c2); + match indent_chars.last() { + Some(((i, _), _)) => min_indent_idx = i, + // If there is no indent char, then no indent needs to be stripped + None => return, + }; + } + + // Remove the shared indent from non-empty lines + for line in lines.iter_mut() { + if !line.is_empty() { + line.head_mut().replace_range(0..=min_indent_idx, ""); + } + } +} + make_parser! { token_rule!(EOI<()>); @@ -378,38 +419,37 @@ make_parser! { rule!(single_quote_literal; children!( [single_quote_continue(lines)] => { - let space = InterpolatedTextContents::Text(" ".to_owned()); - let newline = InterpolatedTextContents::Text("\n".to_owned()); - let min_indent = lines - .iter() - .map(|l| { - l.iter().rev().take_while(|c| **c == space).count() - }) - .min() - .unwrap(); + let newline: ParsedText = "\n".to_string().into(); - lines + let mut lines: Vec = lines .into_iter() .rev() - .map(|mut l| { l.split_off(l.len() - min_indent); l }) - .intersperse(vec![newline]) - .flat_map(|x| x.into_iter().rev()) + .map(|l| l.into_iter().rev().collect::()) + .collect(); + + trim_indent(&mut lines); + + lines + .into_iter() + .intersperse(newline) + .flat_map(|x| x.into_iter()) .collect::() } )); rule!(single_quote_char<&'a str>; captured_str!(s) => s ); - rule!(escaped_quote_pair<&'a str>; + rule!(escaped_quote_pair<&'a str> as single_quote_char; captured_str!(_) => "''" ); - rule!(escaped_interpolation<&'a str>; + rule!(escaped_interpolation<&'a str> as single_quote_char; captured_str!(_) => "${" ); rule!(interpolation; children!( [expression(e)] => e )); + // Returns a vec of lines in reversed order, where each line is also in reversed order. rule!(single_quote_continue>>; children!( [interpolation(c), single_quote_continue(lines)] => { let c = InterpolatedTextContents::Expr(c); @@ -417,24 +457,13 @@ make_parser! { lines.last_mut().unwrap().push(c); lines }, - [escaped_quote_pair(c), single_quote_continue(lines)] => { - let c = InterpolatedTextContents::Text(c.to_owned()); - let mut lines = lines; - lines.last_mut().unwrap().push(c); - lines - }, - [escaped_interpolation(c), single_quote_continue(lines)] => { - let c = InterpolatedTextContents::Text(c.to_owned()); - let mut lines = lines; - lines.last_mut().unwrap().push(c); - lines - }, [single_quote_char("\n"), single_quote_continue(lines)] => { let mut lines = lines; lines.push(vec![]); lines }, [single_quote_char(c), single_quote_continue(lines)] => { + // TODO: don't allocate for every char let c = InterpolatedTextContents::Text(c.to_owned()); let mut lines = lines; lines.last_mut().unwrap().push(c); -- cgit v1.2.3