summaryrefslogtreecommitdiff
path: root/dhall/src/parser.rs
diff options
context:
space:
mode:
authorNadrieril2019-03-05 00:32:55 +0100
committerNadrieril2019-03-05 00:32:55 +0100
commit9c0a29fcad5b92c2f850f7b2bb8c228ec3f167fc (patch)
tree9ea7cf4bd88a09caa29d5a9276ee2cddcf227e54 /dhall/src/parser.rs
parent421a4a69a838aa8de7a02c651c3f830eaff1df6a (diff)
Parse more of the AST
Diffstat (limited to '')
-rw-r--r--dhall/src/parser.rs87
1 files changed, 87 insertions, 0 deletions
diff --git a/dhall/src/parser.rs b/dhall/src/parser.rs
index c4f4ce2..32923e4 100644
--- a/dhall/src/parser.rs
+++ b/dhall/src/parser.rs
@@ -13,6 +13,7 @@ use crate::core::{bx, Expr, Builtin, Const, V};
pub fn parse_expr_lalrpop(s: &str) -> Result<BoxExpr, lalrpop_util::ParseError<usize, Tok, LexicalError>> {
grammar::ExprParser::new().parse(Lexer::new(s))
+ // Ok(bx(Expr::BoolLit(false)))
}
pub type ParseError = pest::error::Error<Rule>;
@@ -158,6 +159,14 @@ macro_rules! named {
);
}
+macro_rules! named_rule {
+ ($name:ident<$o:ty>; $submac:ident!( $($args:tt)* )) => (
+ named!($name<$o>; match_rule!(
+ Rule::$name => $submac!( $($args)* ),
+ ));
+ );
+}
+
macro_rules! match_children {
(@collect, $pairs:expr, ($($args:tt)*), $body:expr, ($($acc:tt)*), ($x:ident : $ty:ident, $($rest:tt)*)) => {
match_children!(@collect, $pairs, ($($args)*), $body, ($($acc)*, $x), ($($rest)*))
@@ -301,6 +310,8 @@ named!(eoi<()>; plain_value!(()));
named!(str<&'a str>; with_captured_str!(s; { s.trim() }));
+named!(raw_str<&'a str>; with_captured_str!(s; s));
+
named!(natural<usize>; with_raw_pair!(pair; {
pair.as_str().trim()
.parse()
@@ -333,7 +344,46 @@ named!(partial_record_entries<(Rule, BoxExpr<'a>, BTreeMap<&'a str, ParsedExpr<'
)
);
+named_rule!(union_type_entry<(&'a str, BoxExpr<'a>)>;
+ match_children!((name: str, expr: expression) => (name, expr))
+);
+
+named_rule!(union_type_entries<BTreeMap<&'a str, ParsedExpr<'a>>>;
+ match_children!((entries*: union_type_entry) => {
+ let mut map: BTreeMap<&str, ParsedExpr> = BTreeMap::new();
+ for (n, e) in entries {
+ map.insert(n, *e);
+ }
+ map
+ })
+);
+
+named_rule!(non_empty_union_type_or_literal<(Option<(&'a str, BoxExpr<'a>)>, BTreeMap<&'a str, ParsedExpr<'a>>)>;
+ match_children!(
+ (label: str, e: expression, entries: union_type_entries) => {
+ (Some((label, e)), entries)
+ },
+ (l: str, e: expression, rest: non_empty_union_type_or_literal) => {
+ let (x, mut entries) = rest;
+ entries.insert(l, *e);
+ (x, entries)
+ },
+ (l: str, e: expression) => {
+ let mut entries = BTreeMap::new();
+ entries.insert(l, *e);
+ (None, entries)
+ },
+ )
+);
+
+named_rule!(empty_union_type<()>; plain_value!(()));
+
named!(expression<BoxExpr<'a>>; match_rule!(
+ Rule::double_quote_literal =>
+ match_children!((strs*: raw_str) => {
+ bx(Expr::TextLit(strs.collect()))
+ }),
+
Rule::natural_literal_raw => map!(natural; |n| bx(Expr::NaturalLit(n))),
Rule::integer_literal_raw => map!(integer; |n| bx(Expr::IntegerLit(n))),
@@ -376,6 +426,25 @@ named!(expression<BoxExpr<'a>>; match_rule!(
bx(Expr::Pi("_", typ, body))
}),
+ Rule::merge_expression =>
+ match_children!((x: expression, y: expression, z?: expression) => {
+ bx(Expr::Merge(x, y, z))
+ }),
+
+ Rule::empty_collection =>
+ match_children!((x: str, y: expression) => {
+ match x {
+ "Optional" => bx(Expr::OptionalLit(Some(y), vec![])),
+ "List" => bx(Expr::ListLit(Some(y), vec![])),
+ _ => unreachable!(),
+ }
+ }),
+
+ Rule::non_empty_optional =>
+ match_children!((x: expression, _y: str, z: expression) => {
+ bx(Expr::OptionalLit(Some(z), vec![*x]))
+ }),
+
Rule::annotated_expression => binop!(Expr::Annot),
Rule::import_alt_expression => binop!(Expr::ImportAlt),
Rule::or_expression => binop!(Expr::BoolOr),
@@ -409,6 +478,24 @@ named!(expression<BoxExpr<'a>>; match_rule!(
}
}),
+ Rule::union_type_or_literal =>
+ match_children!(
+ (_e: empty_union_type) => {
+ bx(Expr::Union(BTreeMap::new()))
+ },
+ (x: non_empty_union_type_or_literal) => {
+ match x {
+ (Some((l, e)), entries) => bx(Expr::UnionLit(l, e, entries)),
+ (None, entries) => bx(Expr::Union(entries)),
+ }
+ },
+ ),
+ Rule::non_empty_list_literal_raw =>
+ match_children!((items*: expression) => {
+ bx(Expr::ListLit(None, items.map(|x| *x).collect()))
+ }),
+
+
_ => with_rule!(rule;
match_children!((exprs*: expression) => {
let rulename = format!("{:?}", rule);