diff options
m--------- | dhall-lang | 0 | ||||
-rw-r--r-- | dhall/src/binary.rs | 2 | ||||
-rw-r--r-- | dhall_core/src/parser.rs | 57 | ||||
-rw-r--r-- | dhall_core/src/printer.rs | 10 | ||||
-rw-r--r-- | dhall_generated_parser/src/dhall.pest.visibility | 4 |
5 files changed, 44 insertions, 29 deletions
diff --git a/dhall-lang b/dhall-lang -Subproject 1c8335d9362342c64d3b4ffaa2afac0eecdff20 +Subproject 7e3721f1a535e4be79af39b2b6d86ee7ce43887 diff --git a/dhall/src/binary.rs b/dhall/src/binary.rs index 7ded3a5..cadd456 100644 --- a/dhall/src/binary.rs +++ b/dhall/src/binary.rs @@ -30,7 +30,7 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result<ParsedExpr, DecodeError> { "Type" => Const(Const::Type), "Kind" => Const(Const::Kind), "Sort" => Const(Const::Sort), - s => Var(V(Label::from(s), 0)), + _ => Err(DecodeError::WrongFormatError("builtin".to_owned()))?, }, }, U64(n) => Var(V(Label::from("_"), *n as usize)), diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs index ba15bae..8f9957a 100644 --- a/dhall_core/src/parser.rs +++ b/dhall_core/src/parser.rs @@ -308,12 +308,12 @@ make_parser! { rule!(quoted_label<Label>; captured_str!(s) => Label::from(s.trim().to_owned()) ); - rule!(label<Label>; children!( - [simple_label(l)] => l, - [quoted_label(l)] => l, + rule!(any_label<(Label, bool)>; children!( + [simple_label(l)] => (l, false), + [quoted_label(l)] => (l, true), )); rule!(nonreserved_label<Label>; children!( - [label(l)] => { + [simple_label(l)] => { if crate::Builtin::parse(&String::from(&l)).is_some() { Err( "Builtin names are not allowed as bound variables".to_string() @@ -321,6 +321,9 @@ make_parser! { } l }, + [quoted_label(l)] => { + l + }, )); rule!(double_quote_literal<ParsedText<'a>>; children!( @@ -772,12 +775,12 @@ make_parser! { )); rule!(selector<Either<Label, Vec<Label>>>; children!( - [label(l)] => Either::Left(l), + [any_label((l, _))] => Either::Left(l), [labels(ls)] => Either::Right(ls), )); rule!(labels<Vec<Label>>; children!( - [label(ls)..] => ls.collect(), + [any_label(ls)..] => ls.map(|(l, _)| l).collect(), )); rule!(primitive_expression<ParsedExpr<'a>> as expression; span; children!( @@ -790,21 +793,31 @@ make_parser! { )); rule!(identifier<ParsedExpr<'a>> as expression; span; children!( - [label(l), natural_literal(idx)] => { + // Quoted label + [any_label((l, true)), natural_literal(idx)] => { + let name = String::from(&l); + spanned(span, Var(V(l, idx))) + }, + [any_label((l, true))] => { + let name = String::from(&l); + spanned(span, Var(V(l, 0))) + }, + // Unquoted label; could be a builtin + [any_label((l, false)), natural_literal(idx)] => { let name = String::from(&l); spanned(span, match crate::Builtin::parse(name.as_str()) { - Some(b) => Builtin(b), + Some(_) => Err( + "Builtin names cannot have an index".to_string() + )?, None => match name.as_str() { - "True" => BoolLit(true), - "False" => BoolLit(false), - "Type" => Const(crate::Const::Type), - "Kind" => Const(crate::Const::Kind), - "Sort" => Const(crate::Const::Sort), + "True" | "False" | "Type" | "Kind" | "Sort" => Err( + "Builtin names cannot have an index".to_string() + )?, _ => Var(V(l, idx)), } }) }, - [label(l)] => { + [any_label((l, false))] => { let name = String::from(&l); spanned(span, match crate::Builtin::parse(name.as_str()) { Some(b) => Builtin(b), @@ -830,12 +843,12 @@ make_parser! { rule!(non_empty_record_type_or_literal<ParsedExpr<'a>> as expression; span; children!( - [label(first_label), non_empty_record_type(rest)] => { + [any_label((first_label, _)), non_empty_record_type(rest)] => { let (first_expr, mut map) = rest; map.insert(first_label, rc(first_expr)); spanned(span, RecordType(map)) }, - [label(first_label), non_empty_record_literal(rest)] => { + [any_label((first_label, _)), non_empty_record_literal(rest)] => { let (first_expr, mut map) = rest; map.insert(first_label, rc(first_expr)); spanned(span, RecordLit(map)) @@ -850,7 +863,7 @@ make_parser! { )); rule!(record_type_entry<(Label, ParsedSubExpr<'a>)>; children!( - [label(name), expression(expr)] => (name, rc(expr)) + [any_label((name, _)), expression(expr)] => (name, rc(expr)) )); rule!(non_empty_record_literal @@ -861,7 +874,7 @@ make_parser! { )); rule!(record_literal_entry<(Label, ParsedSubExpr<'a>)>; children!( - [label(name), expression(expr)] => (name, rc(expr)) + [any_label((name, _)), expression(expr)] => (name, rc(expr)) )); rule!(union_type_or_literal<ParsedExpr<'a>> as expression; span; children!( @@ -882,10 +895,10 @@ make_parser! { <(Option<(Label, ParsedSubExpr<'a>)>, BTreeMap<Label, Option<ParsedSubExpr<'a>>>)>; children!( - [label(l), union_literal_variant_value((e, entries))] => { + [any_label((l, _)), union_literal_variant_value((e, entries))] => { (Some((l, e)), entries) }, - [label(l), union_type_or_literal_variant_type((e, rest))] => { + [any_label((l, _)), union_type_or_literal_variant_type((e, rest))] => { let (x, mut entries) = rest; entries.insert(l, e); (x, entries) @@ -901,8 +914,8 @@ make_parser! { )); rule!(union_type_entry<(Label, Option<ParsedSubExpr<'a>>)>; children!( - [label(name), expression(expr)] => (name, Some(rc(expr))), - [label(name)] => (name, None), + [any_label((name, _)), expression(expr)] => (name, Some(rc(expr))), + [any_label((name, _))] => (name, None), )); // TODO: unary union variants diff --git a/dhall_core/src/printer.rs b/dhall_core/src/printer.rs index c4bad71..8b37b0f 100644 --- a/dhall_core/src/printer.rs +++ b/dhall_core/src/printer.rs @@ -326,12 +326,14 @@ impl Display for NaiveDouble { impl Display for Label { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + // TODO: distinguish between reserved and nonreserved locations for quoting builtins let s = String::from(self); - let is_keyword = |s| match s { - "let" | "in" | "if" | "then" | "else" => true, - _ => false, + let is_reserved = match s.as_str() { + "let" | "in" | "if" | "then" | "else" | "Type" | "Kind" + | "Sort" | "True" | "False" => true, + _ => crate::Builtin::parse(&s).is_some(), }; - if s.chars().all(|c| c.is_ascii_alphanumeric()) && !is_keyword(&s) { + if !is_reserved && s.chars().all(|c| c.is_ascii_alphanumeric()) { write!(f, "{}", s) } else { write!(f, "`{}`", s) diff --git a/dhall_generated_parser/src/dhall.pest.visibility b/dhall_generated_parser/src/dhall.pest.visibility index c3f7540..bb0210d 100644 --- a/dhall_generated_parser/src/dhall.pest.visibility +++ b/dhall_generated_parser/src/dhall.pest.visibility @@ -16,9 +16,9 @@ simple_label # quoted_label_char quoted_label -label +# label nonreserved_label -# any_label +any_label double_quote_chunk double_quote_escaped double_quote_char |