Improve the parsing of row types
@@ -242,17 +242,33 @@ subType : Types = {
<Ident> => Types(AbsType::Var(<>)),
"#" <SpTerm<RichTerm>> => Types(AbsType::Flat(<>)),
"(" <Types> ")" => <>,
- "(" "|" <r:(<Ident> ",")*> "|" <rest: Ident?> ")" =>
- r.iter().fold(
+ "(" "|" <r:(<Ident> ",")*> <last: (<Ident>)?>"|" <rest: Ident?> ")" =>
+ r.into_iter()
+ .chain(last.into_iter())
+ // As we build row types as a linked list via a fold on the original
+ // iterator, the order of identifiers is reversed. This not a big deal
+ // but it's less confusing to the user to print them in the original
+ // order for error reporting.
+ .rev()
+ .fold(
Types(
match rest {
Some(id) => AbsType::Var(id),
None => AbsType::RowEmpty(),
}
),
- |t, i| Types(AbsType::RowExtend(i.clone(), None, Box::new(t)))),
- "{" "|" <r:(<Ident> ":" <Types> ",")*> "|" <rest: Ident?> "}" =>
- r.iter().fold(
+ |t, i| Types(AbsType::RowExtend(i, None, Box::new(t)))
+ ),
+ "{" "|" <r:(<Ident> ":" <Types> ",")*> <last:(<Ident> ":" <Types>)?> "|"
+ <rest: Ident?> "}" =>
+ r.into_iter()
+ .chain(last.into_iter())
+ // As we build row types as a linked list via a fold on the original
+ // iterator, the order of identifiers is reversed. This not a big deal
+ // but it's less confusing to the user to print them in the original
+ // order for error reporting.
+ .rev()
+ .fold(
Types(
match rest {
Some(id) => AbsType::Var(id),
@@ -261,11 +277,12 @@ subType : Types = {
),
|t, i_ty| {
let (i, ty) = i_ty;
- Types(AbsType::RowExtend(i.clone(), Some(Box::new(ty.clone())), Box::new(t)))
- }),
+ Types(AbsType::RowExtend(i, Some(Box::new(ty)), Box::new(t)))
+ }
+ ),
"<" <subType> ">" => Types(AbsType::Enum(Box::new(<>))),
"{" <subType> "}" => Types(AbsType::StaticRecord(Box::new(<>))),
- "{" "_" ":" <subType> "}" => Types(AbsType::DynRecord(Box::new(<>))),
+ "{" "_" ":" <Types> "}" => Types(AbsType::DynRecord(Box::new(<>))),
};
extern {
