From 58f30a0ce9e8bb0dde99edcbbaf8e1b7757e2ee6 Mon Sep 17 00:00:00 2001
From: David Li <li.davidm96@gmail.com>
Date: Sun, 5 Nov 2017 21:32:18 -0500
Subject: Parse empty records/function parameter lists

---
 src/taiga.lalrpop | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

(limited to 'src')

diff --git a/src/taiga.lalrpop b/src/taiga.lalrpop
index 0144aad..afa6433 100644
--- a/src/taiga.lalrpop
+++ b/src/taiga.lalrpop
@@ -7,21 +7,30 @@ pub Program: ast::Program = {
     Expression => ast::Program(<>),
 };
 
-RecordFields: Vec<WithLocation<ast::RecordField>> = {
-    <l: @L> <n:Name> ":" <v:Name> <r: @R> "," <rest: RecordFields> => {
+FieldList: Vec<WithLocation<ast::RecordField>> = {
+    <l: @L> <n:Name> ":" <v:Name> <r: @R> "," <rest: FieldList> => {
         let mut rest = rest;
         rest.push(WithLocation::new(ast::RecordField::new(n, v), l, r));
         rest
     },
     <l: @L> <n:Name> ":" <v:Name> <r: @R> "," => vec![WithLocation::new(ast::RecordField::new(n, v), l, r)],
     <l: @L> <n:Name> ":" <v:Name> <r: @R> => vec![WithLocation::new(ast::RecordField::new(n, v), l, r)],
-    "" => vec![],
+};
+
+RecordFields: WithLocation<Vec<WithLocation<ast::RecordField>>> = {
+    <l: @L> "{" <v: FieldList> "}" <r: @R> => WithLocation::new(v, l, r),
+    <l: @L> "{" "}" <r: @R> => WithLocation::new(vec![], l, r),
+};
+
+Parameters: WithLocation<Vec<WithLocation<ast::RecordField>>> = {
+    <l: @L> "(" <v: FieldList> ")" <r: @R> => WithLocation::new(v, l, r),
+    <l: @L> "(" ")" <r: @R> => WithLocation::new(vec![], l, r),
 };
 
 Ty: WithLocation<ast::Ty> = {
     <Name> => <>.map(|v| ast::Ty::Name(v)),
     "array" "of" <Name> => <>.map(|v| ast::Ty::Array(Box::new(ast::Ty::Name(v)))),
-    <l: @L> "{" <v: RecordFields> "}" <r: @R> => WithLocation::new(ast::Ty::Record(v), l, r),
+    <RecordFields> => <>.map(|v| ast::Ty::Record(v)),
 };
 
 Declaration: Box<WithLocation<ast::Declaration>> = {
@@ -31,10 +40,10 @@ Declaration: Box<WithLocation<ast::Declaration>> = {
         Box::new(WithLocation::new(ast::Declaration::new_var(name, None, exp), l, r)),
     <l: @L> "type" <name: Name> "=" <ty: Ty> <r: @R> =>
         Box::new(WithLocation::new(ast::Declaration::new_ty(name, ty), l, r)),
-    <l: @L> "function" <name: Name> "(" <params: RecordFields> ")" "=" <body: Expression> <r: @R> =>
-        Box::new(WithLocation::new(ast::Declaration::new_fun(name, params, None, body), l, r)),
-    <l: @L> "function" <name: Name> "(" <params: RecordFields> ")" ":" <ty: Ty> "=" <body: Expression> <r: @R> =>
-        Box::new(WithLocation::new(ast::Declaration::new_fun(name, params, Some(ty), body), l, r)),
+    <l: @L> "function" <name: Name> <params: Parameters> "=" <body: Expression> <r: @R> =>
+        Box::new(WithLocation::new(ast::Declaration::new_fun(name, params.value, None, body), l, r)),
+    <l: @L> "function" <name: Name> <params: Parameters> ":" <ty: Ty> "=" <body: Expression> <r: @R> =>
+        Box::new(WithLocation::new(ast::Declaration::new_fun(name, params.value, Some(ty), body), l, r)),
 };
 
 DeclarationsList: Vec<WithLocation<ast::Declaration>> = {
-- 
cgit v1.2.3