Skip to content

Commit 515a74f

Browse files
committed
Allow trailing commas in lists
See also #115, and the comment there that goes with this commit: #115 (comment)
1 parent ad8ce13 commit 515a74f

14 files changed

+107
-12
lines changed

regression-tests/pure2-bugfix-for-parameter-decl-list-error.cpp2

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
f: (a, b, ) a + b;
2+
3+
g: <T, U, > (a: T, b: U) a + b;
4+
5+
doubler: (a: int,) -> (i : int,) = {
6+
i = a * 2;
7+
}
8+
9+
vals: @struct type = { i: int; }
10+
11+
main: () -> int = {
12+
(copy a := 42,) while false { a++; }
13+
_ = g(1, 2,);
14+
15+
grouping: std::vector = (0, 1, 2,);
16+
17+
array: std::array = (0, 1, 2,);
18+
19+
_ = array;
20+
_ = grouping;
21+
}

regression-tests/test-results/clang-12/pure2-trailing-commas.cpp.execution

Whitespace-only changes.

regression-tests/test-results/clang-12/pure2-trailing-commas.cpp.output

Whitespace-only changes.

regression-tests/test-results/gcc-10/pure2-trailing-commas.cpp.execution

Whitespace-only changes.

regression-tests/test-results/gcc-10/pure2-trailing-commas.cpp.output

Whitespace-only changes.

regression-tests/test-results/gcc-13/pure2-trailing-commas.cpp.execution

Whitespace-only changes.

regression-tests/test-results/gcc-13/pure2-trailing-commas.cpp.output

Whitespace-only changes.

regression-tests/test-results/msvc-2022/pure2-trailing-commas.cpp.execution

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pure2-trailing-commas.cpp

regression-tests/test-results/pure2-bugfix-for-parameter-decl-list-error.cpp2.output

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
2+
#define CPP2_IMPORT_STD Yes
3+
4+
//=== Cpp2 type declarations ====================================================
5+
6+
7+
#include "cpp2util.h"
8+
9+
#line 1 "pure2-trailing-commas.cpp2"
10+
11+
#line 9 "pure2-trailing-commas.cpp2"
12+
class vals;
13+
14+
15+
//=== Cpp2 type definitions and function declarations ===========================
16+
17+
#line 1 "pure2-trailing-commas.cpp2"
18+
[[nodiscard]] auto f(auto const& a, auto const& b) -> auto;
19+
20+
#line 3 "pure2-trailing-commas.cpp2"
21+
template<typename T, typename U> [[nodiscard]] auto g(T const& a, U const& b) -> auto;
22+
using doubler_ret = int;
23+
24+
25+
#line 5 "pure2-trailing-commas.cpp2"
26+
[[nodiscard]] auto doubler(cpp2::impl::in<int> a) -> doubler_ret;
27+
28+
#line 9 "pure2-trailing-commas.cpp2"
29+
class vals {public: int i; };
30+
31+
[[nodiscard]] auto main() -> int;
32+
33+
//=== Cpp2 function definitions =================================================
34+
35+
#line 1 "pure2-trailing-commas.cpp2"
36+
[[nodiscard]] auto f(auto const& a, auto const& b) -> auto { return a + b; }
37+
38+
#line 3 "pure2-trailing-commas.cpp2"
39+
template<typename T, typename U> [[nodiscard]] auto g(T const& a, U const& b) -> auto { return a + b; }
40+
41+
#line 5 "pure2-trailing-commas.cpp2"
42+
[[nodiscard]] auto doubler(cpp2::impl::in<int> a) -> doubler_ret{
43+
cpp2::impl::deferred_init<int> i;
44+
#line 6 "pure2-trailing-commas.cpp2"
45+
i.construct(a * 2);
46+
return std::move(i.value()); }
47+
48+
#line 11 "pure2-trailing-commas.cpp2"
49+
[[nodiscard]] auto main() -> int{
50+
{
51+
auto a{42};
52+
#line 12 "pure2-trailing-commas.cpp2"
53+
while( false ) {++a; }
54+
}
55+
#line 13 "pure2-trailing-commas.cpp2"
56+
static_cast<void>(g(1, 2));
57+
58+
std::vector grouping {0, 1, 2};
59+
60+
std::array array {0, 1, 2};
61+
62+
static_cast<void>(std::move(array));
63+
static_cast<void>(std::move(grouping));
64+
}
65+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pure2-trailing-commas.cpp2... ok (all Cpp2, passes safety checks)
2+

source/parse.h

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6360,6 +6360,12 @@ class parser
63606360
// and see if there are more...
63616361
while (curr().type() == lexeme::Comma) {
63626362
next();
6363+
6364+
// Allow a trailing comma in the list
6365+
if (curr().type() == lexeme::RightParen) {
6366+
break;
6367+
}
6368+
63636369
pass = passing_style::in;
63646370
if (auto dir = to_passing_style(curr());
63656371
dir == passing_style::out
@@ -6377,6 +6383,7 @@ class parser
63776383
}
63786384
n->expressions.push_back( { pass, std::move(expr) } );
63796385
}
6386+
63806387
return n;
63816388
}
63826389

@@ -7809,11 +7816,9 @@ class parser
78097816
auto param = std::make_unique<parameter_declaration_node>();
78107817

78117818
auto count = 1;
7812-
auto expect_another_param_decl = false;
78137819

78147820
while ((param = parameter_declaration(is_returns, is_named, is_template, is_statement)) != nullptr)
78157821
{
7816-
expect_another_param_decl = false;
78177822
param->ordinal = count;
78187823
++count;
78197824

@@ -7830,6 +7835,17 @@ class parser
78307835
if (curr().type() == closer) {
78317836
break;
78327837
}
7838+
7839+
// Allow a trailing comma in the list
7840+
else if (
7841+
curr().type() == lexeme::Comma
7842+
&& peek(1)->type() == closer
7843+
)
7844+
{
7845+
next();
7846+
break;
7847+
}
7848+
78337849
else if (curr().type() != lexeme::Comma) {
78347850
if (is_statement) {
78357851
pos = start_pos; // backtrack
@@ -7840,14 +7856,9 @@ class parser
78407856
return {};
78417857
}
78427858

7843-
expect_another_param_decl = true;
78447859
next();
78457860
}
78467861

7847-
if (expect_another_param_decl) {
7848-
error("invalid parameter list: a comma must be followed by another parameter", true, {}, true);
7849-
}
7850-
78517862
if (curr().type() != closer) {
78527863
if (is_statement) {
78537864
pos = start_pos; // backtrack

0 commit comments

Comments
 (0)