Skip to content

Commit f6535b5

Browse files
committed
Track expression-list paren tokens (not just positions), see comment thread for #193
This commit paves the way for in the future (not now) possibly experimenting with allowing expression-list to have braces, if it's important to provide explicit initializer-list expression syntax (mostly for function arguments)
1 parent c048a15 commit f6535b5

8 files changed

+62
-58
lines changed

regression-tests/test-results/clang-12/pure2-cpp1-multitoken-fundamental-types.cpp.output

Whitespace-only changes.

regression-tests/test-results/gcc-10/pure2-cpp1-multitoken-fundamental-types.cpp.output

Whitespace-only changes.

regression-tests/test-results/msvc-2022/pure2-cpp1-multitoken-fundamental-types.cpp.output

-1
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
pure2-bounds-safety-pointer-arithmetic-error.cpp2...
22
pure2-bounds-safety-pointer-arithmetic-error.cpp2(15,13): error: 'delete' and owning raw pointers are not supported in Cpp2
33
pure2-bounds-safety-pointer-arithmetic-error.cpp2(15,13): error: - use unique.new<T>, shared.new<T>, or gc.new<T> instead (in that order)
4-
pure2-bounds-safety-pointer-arithmetic-error.cpp2(15,16): error: expected ; at end of statement (at 'first')
5-
pure2-bounds-safety-pointer-arithmetic-error.cpp2(15,16): error: invalid statement in compound-statement (at 'first')
6-
pure2-bounds-safety-pointer-arithmetic-error.cpp2(15,16): error: invalid while loop body (at 'first')
7-
pure2-bounds-safety-pointer-arithmetic-error.cpp2(17,1): error: unexpected text at end of Cpp2 code section (at '}')
4+
pure2-bounds-safety-pointer-arithmetic-error.cpp2(9,25): error: invalid while loop body (at '{')
5+
pure2-bounds-safety-pointer-arithmetic-error.cpp2(3,3): error: ill-formed initializer (at '{')
6+
pure2-bounds-safety-pointer-arithmetic-error.cpp2(2,1): error: unexpected text at end of Cpp2 code section (at 'main')
87
pure2-bounds-safety-pointer-arithmetic-error.cpp2(1,0): error: parse failed for section starting here
98

regression-tests/test-results/run-tests.bat

-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
@echo off
2-
REM This is intended to be run in the /test-results directory
3-
REM A copy is in the parent directory just for convenience in case of accidental deletion.
4-
REM
52
del *.cpp *.output
63
copy ..\*.cpp2 .
74
set count=0

source/cppfront.cpp

+7-15
Original file line numberDiff line numberDiff line change
@@ -2108,12 +2108,7 @@ class cppfront
21082108
{
21092109
auto add_parens = should_add_expression_list_parens() && !n.inside_initializer;
21102110
if (add_parens) {
2111-
if (n.expressions.empty()) {
2112-
printer.print_cpp2( "{", n.position());
2113-
}
2114-
else {
2115-
printer.print_cpp2( "(", n.position());
2116-
}
2111+
printer.print_cpp2( *n.open_paren, n.position());
21172112
}
21182113

21192114
auto first = true;
@@ -2163,12 +2158,7 @@ class cppfront
21632158
}
21642159

21652160
if (add_parens) {
2166-
if (n.expressions.empty()) {
2167-
printer.print_cpp2( "}", n.position());
2168-
}
2169-
else {
2170-
printer.print_cpp2( ")", n.position());
2171-
}
2161+
printer.print_cpp2( *n.close_paren, n.position());
21722162
}
21732163
// We want to consume only one of these
21742164
consumed_expression_list_parens();
@@ -2346,7 +2336,8 @@ class cppfront
23462336
printer.print_cpp2( "{\n", n.position() );
23472337
}
23482338
else {
2349-
printer.print_cpp2( "(", n.pos_open_paren );
2339+
assert(n.open_paren);
2340+
printer.print_cpp2( "(", n.open_paren->position() );
23502341
}
23512342

23522343
// So we don't get cute about text-aligning the first parameter when it's on a new line
@@ -2372,8 +2363,9 @@ class cppfront
23722363
else {
23732364
// Position heuristic (aka hack): Avoid emitting extra whitespace before )
23742365
// beyond column 10
2375-
auto col = std::min( n.pos_close_paren.colno, colno_t{10} );
2376-
printer.print_cpp2( ")", { n.pos_close_paren.lineno, col } );
2366+
assert(n.close_paren);
2367+
auto col = std::min( n.close_paren->position().colno, colno_t{10});
2368+
printer.print_cpp2( ")", { n.close_paren->position().lineno, col});
23772369
}
23782370

23792371
in_parameter_list = false;

source/lex.h

+19-10
Original file line numberDiff line numberDiff line change
@@ -96,27 +96,35 @@ enum class lexeme : std::int8_t {
9696
Keyword,
9797
Cpp1MultiKeyword,
9898
Cpp2FixedType,
99-
Identifier
99+
Identifier,
100+
None = 127
100101
};
101102

102-
auto is_literal(lexeme l) {
103+
auto is_literal(lexeme l) -> bool {
103104
switch (l) {
104-
break;case lexeme::FloatLiteral:
105-
case lexeme::BinaryLiteral:
106-
case lexeme::DecimalLiteral:
107-
case lexeme::HexadecimalLiteral:
108-
case lexeme::StringLiteral:
105+
break;case lexeme::FloatLiteral:
106+
case lexeme::BinaryLiteral:
107+
case lexeme::DecimalLiteral:
108+
case lexeme::HexadecimalLiteral:
109+
case lexeme::StringLiteral:
109110
case lexeme::CharacterLiteral: return true;
110111
break;default: return false;
111112
}
112113
}
113114

114-
// TODO: Remove the duplication above/below with a variadic macro,
115-
// but for now it's simpler just to write it out
115+
auto close_paren_type(lexeme l) -> lexeme {
116+
switch (l) {
117+
break;case lexeme::LeftBrace: return lexeme::RightBrace;
118+
break;case lexeme::LeftBracket: return lexeme::RightBracket;
119+
break;case lexeme::LeftParen: return lexeme::RightParen;
120+
break;default: return lexeme::None;
121+
}
122+
}
123+
116124

117125
template<typename T>
118126
requires std::is_same_v<T, std::string>
119-
auto as(lexeme l)
127+
auto as(lexeme l) -> std::string
120128
{
121129
switch (l) {
122130
break;case lexeme::SlashEq: return "SlashEq";
@@ -181,6 +189,7 @@ auto as(lexeme l)
181189
break;case lexeme::Cpp1MultiKeyword: return "Cpp1MultiKeyword";
182190
break;case lexeme::Cpp2FixedType: return "Cpp2FixedType";
183191
break;case lexeme::Identifier: return "Identifier";
192+
break;case lexeme::None: return "(NONE)";
184193
break;default: return "INTERNAL-ERROR";
185194
}
186195
};

source/parse.h

+33-25
Original file line numberDiff line numberDiff line change
@@ -256,9 +256,9 @@ auto to_string_view(passing_style pass) -> std::string_view {
256256

257257
struct expression_list_node
258258
{
259-
source_position open_paren = {};
260-
source_position close_paren = {};
261-
bool inside_initializer = false;
259+
token const* open_paren = {};
260+
token const* close_paren = {};
261+
bool inside_initializer = false;
262262

263263
struct term {
264264
passing_style pass = {};
@@ -277,8 +277,8 @@ struct expression_list_node
277277
auto position() const -> source_position
278278
{
279279
// Make sure this got set
280-
assert (open_paren != source_position());
281-
return open_paren;
280+
assert (open_paren);
281+
return open_paren->position();
282282
}
283283

284284
auto visit(auto& v, int depth) -> void
@@ -910,8 +910,8 @@ auto compound_statement_node::visit(auto& v, int depth) -> void
910910

911911
struct parameter_declaration_node
912912
{
913-
source_position pos;
914-
passing_style pass = passing_style::in;
913+
source_position pos = {};
914+
passing_style pass = passing_style::in;
915915

916916
enum class modifier { none=0, implicit, virtual_, override_, final_ };
917917
modifier mod = modifier::none;
@@ -926,14 +926,15 @@ struct parameter_declaration_node
926926

927927
struct parameter_declaration_list_node
928928
{
929-
source_position pos_open_paren;
930-
source_position pos_close_paren;
929+
token const* open_paren = {};
930+
token const* close_paren = {};
931931

932932
std::vector<std::unique_ptr<parameter_declaration_node>> parameters;
933933

934934
auto position() const -> source_position
935935
{
936-
return pos_open_paren;
936+
assert(open_paren);
937+
return open_paren->position();
937938
}
938939

939940
auto visit(auto& v, int depth) -> void
@@ -1507,6 +1508,7 @@ class parser
15071508
//G id-expression
15081509
//G literal
15091510
//G '(' expression-list ')'
1511+
//G '{' expression-list '}'
15101512
//G unnamed-declaration
15111513
//G
15121514
auto primary_expression()
@@ -1539,23 +1541,28 @@ class parser
15391541
return n;
15401542
}
15411543

1542-
if (curr().type() == lexeme::LeftParen)
1544+
if (curr().type() == lexeme::LeftParen
1545+
// If in the future (not now) we want to experiment with braced-expressions
1546+
// || curr().type() == lexeme::LeftBrace
1547+
)
15431548
{
15441549
bool inside_initializer = (peek(-1)->type() == lexeme::Assignment);
1545-
auto open_paren = curr().position();
1550+
auto open_paren = &curr();
1551+
auto close = close_paren_type(open_paren->type());
1552+
auto close_text = [&] () -> std::string { if (close == lexeme::RightParen) { return ")"; } return "}"; }();
15461553
next();
15471554
auto expr_list = expression_list(open_paren, inside_initializer);
15481555
if (!expr_list) {
15491556
error("unexpected text - ( is not followed by an expression-list");
15501557
next();
15511558
return {};
15521559
}
1553-
if (curr().type() != lexeme::RightParen) {
1554-
error("unexpected text - expression-list is not terminated by )");
1560+
if (curr().type() != close_paren_type(open_paren->type())) {
1561+
error("unexpected text - expression-list is not terminated by " + close_text);
15551562
next();
15561563
return {};
15571564
}
1558-
expr_list->close_paren = curr().position();
1565+
expr_list->close_paren = &curr();
15591566
next();
15601567
n->expr = std::move(expr_list);
15611568
return n;
@@ -1656,7 +1663,7 @@ class parser
16561663

16571664
if (term.op->type() == lexeme::LeftBracket)
16581665
{
1659-
term.expr_list = expression_list(term.op->position());
1666+
term.expr_list = expression_list(term.op);
16601667
if (!term.expr_list) {
16611668
error("subscript expression [ ] must not be empty");
16621669
return {};
@@ -1665,13 +1672,13 @@ class parser
16651672
error("unexpected text - [ is not properly matched by ]");
16661673
return {};
16671674
}
1668-
term.expr_list->close_paren = curr().position();
1675+
term.expr_list->close_paren = &curr();
16691676
term.op_close = &curr();
16701677
next();
16711678
}
16721679
else if (term.op->type() == lexeme::LeftParen)
16731680
{
1674-
term.expr_list = expression_list(term.op->position());
1681+
term.expr_list = expression_list(term.op);
16751682
if (!term.expr_list) {
16761683
error("( is not followed by a valid expression list");
16771684
return {};
@@ -1680,7 +1687,7 @@ class parser
16801687
error("unexpected text - ( is not properly matched by )");
16811688
return {};
16821689
}
1683-
term.expr_list->close_paren = curr().position();
1690+
term.expr_list->close_paren = &curr();
16841691
term.op_close = &curr();
16851692
next();
16861693
}
@@ -2008,7 +2015,7 @@ class parser
20082015
//G parameter-direction? expression
20092016
//G expression-list ',' expression
20102017
//G
2011-
auto expression_list(source_position open_paren, bool inside_initializer = false) -> std::unique_ptr<expression_list_node> {
2018+
auto expression_list(token const* open_paren, bool inside_initializer = false) -> std::unique_ptr<expression_list_node> {
20122019
auto pass = passing_style::in;
20132020
auto n = std::make_unique<expression_list_node>();
20142021
n->open_paren = open_paren;
@@ -2391,7 +2398,6 @@ class parser
23912398
// it doesn't destabilize any regression tests
23922399
)
23932400
{
2394-
error("expected ; at end of statement");
23952401
return {};
23962402
}
23972403
if (curr().type() == lexeme::Semicolon) {
@@ -2848,7 +2854,6 @@ class parser
28482854
}
28492855

28502856
else {
2851-
//next();
28522857
return {};
28532858
}
28542859
}
@@ -2870,6 +2875,9 @@ class parser
28702875

28712876
auto n = std::make_unique<compound_statement_node>();
28722877

2878+
// Remember current position, in case this isn't a valid statement
2879+
auto start_pos = pos;
2880+
28732881
// In the case where this is a declaration initializer with
28742882
// = {
28752883
// on the same line, we want to remember our start position
@@ -2886,7 +2894,7 @@ class parser
28862894
while (curr().type() != lexeme::RightBrace) {
28872895
auto s = statement(true);
28882896
if (!s) {
2889-
error("invalid statement in compound-statement");
2897+
pos = start_pos; // backtrack
28902898
return {};
28912899
}
28922900
n->statements.push_back( std::move(s) );
@@ -3011,7 +3019,7 @@ class parser
30113019
}
30123020

30133021
auto n = std::make_unique<parameter_declaration_list_node>();
3014-
n->pos_open_paren = curr().position();
3022+
n->open_paren = &curr();
30153023
next();
30163024

30173025
auto param = std::make_unique<parameter_declaration_node>();
@@ -3035,7 +3043,7 @@ class parser
30353043
return {};
30363044
}
30373045

3038-
n->pos_close_paren = curr().position();
3046+
n->close_paren = &curr();
30393047
next();
30403048
return n;
30413049
}

0 commit comments

Comments
 (0)