From 845abbb0404ac15cefeca8b6ac32d9b3f93e5987 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 21 Mar 2019 16:36:46 +0100 Subject: Represent Optional literals more faithfully --- dhall_core/src/core.rs | 10 ++++++---- dhall_core/src/parser.rs | 44 ++++++++++++++++++++++++++++---------------- 2 files changed, 34 insertions(+), 20 deletions(-) (limited to 'dhall_core') diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs index 1d733aa..52fc0cf 100644 --- a/dhall_core/src/core.rs +++ b/dhall_core/src/core.rs @@ -195,9 +195,10 @@ pub enum Expr { EmptyListLit(SubExpr), /// [x, y, z] NEListLit(Vec>), - /// `OptionalLit t [e] ~ [e] : Optional t` - /// `OptionalLit t [] ~ [] : Optional t` - OptionalLit(Option>, Option>), + /// None t + EmptyOptionalLit(SubExpr), + /// Some e + NEOptionalLit(SubExpr), /// `Record [(k1, t1), (k2, t2)] ~ { k1 : t1, k2 : t1 }` RecordType(BTreeMap>), /// `RecordLit [(k1, v1), (k2, v2)] ~ { k1 = v1, k2 = v2 }` @@ -346,7 +347,8 @@ where BinOp(o, x, y) => BinOp(*o, map(x), map(y)), EmptyListLit(t) => EmptyListLit(map(t)), NEListLit(es) => NEListLit(vec(es)), - OptionalLit(t, es) => OptionalLit(opt(t), opt(es)), + EmptyOptionalLit(t) => EmptyOptionalLit(map(t)), + NEOptionalLit(e) => NEOptionalLit(map(e)), RecordType(kts) => RecordType(btmap(kts)), RecordLit(kvs) => RecordLit(btmap(kvs)), UnionType(kts) => UnionType(btmap(kts)), diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs index 3310bb9..b07094d 100644 --- a/dhall_core/src/parser.rs +++ b/dhall_core/src/parser.rs @@ -123,10 +123,10 @@ macro_rules! match_pair { match_pair!(@make_child_match, ($($vars)*), ($($outer_acc)*), ($($acc)*, ParsedValue::$ty($x)), ($($rest_of_match)*) => $body, $($rest)*) }; (@make_child_match, ($($vars:tt)*), ($($outer_acc:tt)*), (, $($acc:tt)*), ($(,)*) => $body:expr, $($rest:tt)*) => { - match_pair!(@make_matches, ($($vars)*), ([$($acc)*] => { $body }, $($outer_acc)*), $($rest)*) + match_pair!(@make_matches, ($($vars)*), ($($outer_acc)* [$($acc)*] => { $body },), $($rest)*) }; (@make_child_match, ($($vars:tt)*), ($($outer_acc:tt)*), (), ($(,)*) => $body:expr, $($rest:tt)*) => { - match_pair!(@make_matches, ($($vars)*), ([] => { $body }, $($outer_acc)*), $($rest)*) + match_pair!(@make_matches, ($($vars)*), ($($outer_acc)* [] => { $body },), $($rest)*) }; (@make_matches, ($($vars:tt)*), ($($acc:tt)*), [$($args:tt)*] => $body:expr, $($rest:tt)*) => { @@ -469,17 +469,17 @@ make_parser! { rule!(Optional<()>; raw_pair!(_) => ()); rule!(empty_collection as expression; children!( - [List(_), expression(y)] => { - bx(Expr::EmptyListLit(y)) + [List(_), expression(t)] => { + bx(Expr::EmptyListLit(t)) }, - [Optional(_), expression(y)] => { - bx(Expr::OptionalLit(Some(y), None)) + [Optional(_), expression(t)] => { + bx(Expr::EmptyOptionalLit(t)) }, )); rule!(non_empty_optional as expression; children!( - [expression(x), Optional(_), expression(z)] => { - bx(Expr::OptionalLit(Some(z), Some(x))) + [expression(x), Optional(_), expression(t)] => { + rc(Expr::Annot(rc(Expr::NEOptionalLit(x)), t)) } )); @@ -557,24 +557,36 @@ make_parser! { )); rule!(annotated_expression as expression; children!( + [expression(e)] => e, [expression(e), expression(annot)] => { bx(Expr::Annot(e, annot)) }, - [expression(e)] => e, )); rule!(application_expression as expression; children!( - [expression(first), expression(rest..)] => { - let rest: Vec<_> = rest.collect(); - if rest.is_empty() { - first - } else { - bx(Expr::App(first, rest)) + [expression(e)] => e, + [expression(first), expression(second)] => { + match first.as_ref() { + Expr::Builtin(Builtin::OptionalNone) => + bx(Expr::EmptyOptionalLit(second)), + Expr::Builtin(Builtin::OptionalSome) => + bx(Expr::NEOptionalLit(second)), + _ => bx(Expr::App(first, vec![second])), } - } + }, + [expression(first), expression(second), expression(rest..)] => { + match first.as_ref() { + Expr::Builtin(Builtin::OptionalNone) => + bx(Expr::App(bx(Expr::EmptyOptionalLit(second)), rest.collect())), + Expr::Builtin(Builtin::OptionalSome) => + bx(Expr::App(bx(Expr::NEOptionalLit(second)), rest.collect())), + _ => bx(Expr::App(first, std::iter::once(second).chain(rest).collect())), + } + }, )); rule!(selector_expression_raw as expression; children!( + [expression(e)] => e, [expression(first), selector_raw(rest..)] => { rest.fold(first, |acc, e| bx(Expr::Field(acc, e))) } -- cgit v1.2.3