Skip to content

Commit 774b373

Browse files
committed
fix: lower (nested) _braced-init-list_ (argument)
1 parent c5feb42 commit 774b373

7 files changed

+159
-9
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
point: @value type = {
2+
public x: int = 0;
3+
public y: int = 0;
4+
operator=: (implicit out this, x_: int, y_: int) = {
5+
x = x_;
6+
y = y_;
7+
}
8+
}
9+
10+
check: (p: point) p;
11+
12+
main: () = {
13+
assert(check((17, 29)).x == 17);
14+
assert(check((17, 29)).y == 29);
15+
16+
board: std::array<std::array<u8, 3>, 3> = ((
17+
('O', 'X', 'O'),
18+
(' ', ('X'), 'X'),
19+
('X', 'O', 'O')
20+
));
21+
assert(board[0] == :std::array<u8, 3> = ('O', 'X', 'O'));
22+
assert(board[1] == :std::array<u8, 3> = (' ', 'X', 'X'));
23+
assert(board[2] == :std::array<u8, 3> = ('X', 'O', 'O'));
24+
25+
// Still parentheses (for now?)
26+
assert((:std::vector = (17, 29)).size() == 2);
27+
}

regression-tests/test-results/mixed-default-arguments.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ auto cxx2(cpp2::impl::in<int> x, cpp2::impl::in<std::string> y) -> void{
3333
#line 9 "mixed-default-arguments.cpp2"
3434
auto main() -> int{
3535
cxx(1, "test");
36-
cxx({}, {});
36+
cxx({ }, { });
3737
cxx2(1, "test");
38-
cxx2({}, {});
38+
cxx2({ }, { });
3939
}
4040

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
2+
#define CPP2_IMPORT_STD Yes
3+
4+
//=== Cpp2 type declarations ====================================================
5+
6+
7+
#include "cpp2util.h"
8+
9+
#line 1 "pure2-bugfix-for-nested-lists.cpp2"
10+
class point;
11+
#line 2 "pure2-bugfix-for-nested-lists.cpp2"
12+
13+
14+
//=== Cpp2 type definitions and function declarations ===========================
15+
16+
#line 1 "pure2-bugfix-for-nested-lists.cpp2"
17+
class point {
18+
#line 2 "pure2-bugfix-for-nested-lists.cpp2"
19+
public: int x {0};
20+
public: int y {0};
21+
public: point(cpp2::impl::in<int> x_, cpp2::impl::in<int> y_);
22+
public: [[nodiscard]] auto operator<=>(point const& that) const& -> std::strong_ordering = default;
23+
public: point(point const& that);
24+
25+
public: auto operator=(point const& that) -> point& ;
26+
public: point(point&& that) noexcept;
27+
public: auto operator=(point&& that) noexcept -> point& ;
28+
public: explicit point();
29+
30+
#line 8 "pure2-bugfix-for-nested-lists.cpp2"
31+
};
32+
33+
[[nodiscard]] auto check(cpp2::impl::in<point> p) -> auto;
34+
35+
auto main() -> int;
36+
37+
//=== Cpp2 function definitions =================================================
38+
39+
#line 1 "pure2-bugfix-for-nested-lists.cpp2"
40+
41+
#line 4 "pure2-bugfix-for-nested-lists.cpp2"
42+
point::point(cpp2::impl::in<int> x_, cpp2::impl::in<int> y_)
43+
: x{ x_ }
44+
, y{ y_ }{
45+
46+
#line 7 "pure2-bugfix-for-nested-lists.cpp2"
47+
}
48+
49+
50+
point::point(point const& that)
51+
: x{ that.x }
52+
, y{ that.y }{}
53+
54+
auto point::operator=(point const& that) -> point& {
55+
x = that.x;
56+
y = that.y;
57+
return *this;}
58+
point::point(point&& that) noexcept
59+
: x{ std::move(that).x }
60+
, y{ std::move(that).y }{}
61+
auto point::operator=(point&& that) noexcept -> point& {
62+
x = std::move(that).x;
63+
y = std::move(that).y;
64+
return *this;}
65+
point::point(){}
66+
#line 10 "pure2-bugfix-for-nested-lists.cpp2"
67+
[[nodiscard]] auto check(cpp2::impl::in<point> p) -> auto { return p; }
68+
69+
#line 12 "pure2-bugfix-for-nested-lists.cpp2"
70+
auto main() -> int{
71+
if (cpp2::cpp2_default.is_active() && !(check({ 17, 29 }).x == 17) ) { cpp2::cpp2_default.report_violation(""); }
72+
if (cpp2::cpp2_default.is_active() && !(check({ 17, 29 }).y == 29) ) { cpp2::cpp2_default.report_violation(""); }
73+
74+
std::array<std::array<cpp2::u8,3>,3> board {{ {
75+
'O', 'X', 'O' }, {
76+
' ', { 'X' }, 'X' }, {
77+
'X', 'O', 'O' } }};
78+
79+
if (cpp2::cpp2_default.is_active() && !(CPP2_ASSERT_IN_BOUNDS_LITERAL(board, 0) == std::array<cpp2::u8,3>{'O', 'X', 'O'}) ) { cpp2::cpp2_default.report_violation(""); }
80+
if (cpp2::cpp2_default.is_active() && !(CPP2_ASSERT_IN_BOUNDS_LITERAL(board, 1) == std::array<cpp2::u8,3>{' ', 'X', 'X'}) ) { cpp2::cpp2_default.report_violation(""); }
81+
if (cpp2::cpp2_default.is_active() && !(CPP2_ASSERT_IN_BOUNDS_LITERAL(cpp2::move(board), 2) == std::array<cpp2::u8,3>{'X', 'O', 'O'}) ) { cpp2::cpp2_default.report_violation(""); }
82+
83+
// Still parentheses (for now?)
84+
if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(size)((std::vector{17, 29})) == 2) ) { cpp2::cpp2_default.report_violation(""); }
85+
}
86+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pure2-bugfix-for-nested-lists.cpp2... ok (all Cpp2, passes safety checks)
2+

regression-tests/test-results/pure2-hashable.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ return ret;
6666

6767
mystruct::mystruct(auto&& i_, auto&& j_, auto&& k_)
6868
requires (std::is_convertible_v<CPP2_TYPEOF(i_), std::add_const_t<cpp2::i32>&> && std::is_convertible_v<CPP2_TYPEOF(j_), std::add_const_t<std::string>&> && std::is_convertible_v<CPP2_TYPEOF(k_), std::add_const_t<cpp2::u64>&>)
69-
: base{ (1) }
69+
: base{ { 1 } }
7070
, i{ CPP2_FORWARD(i_) }
7171
, j{ CPP2_FORWARD(j_) }
7272
, k{ CPP2_FORWARD(k_) }{}

source/parse.h

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6296,9 +6296,9 @@ class parser
62966296
// Next should be an expression-list followed by a ')'
62976297
// If not, then this wasn't a call expression so backtrack to
62986298
// the '(' which will be part of the next grammar production
6299-
is_inside_call_expr = true;
6300-
term.expr_list = expression_list(term.op, lexeme::RightParen);
6301-
is_inside_call_expr = false;
6299+
is_inside_call_expr = true;
6300+
term.expr_list = expression_list(term.op, lexeme::RightParen, true);
6301+
is_inside_call_expr = false;
63026302

63036303
if (
63046304
term.expr_list
@@ -6842,8 +6842,28 @@ class parser
68426842
return n;
68436843
}
68446844

6845+
auto add_expression = [&](expression_list_node::term t) {
6846+
std::function<void(expression_list_node::term&)> mark_nested_inside_initializer{
6847+
[&](expression_list_node::term& u) {
6848+
if (
6849+
inside_initializer
6850+
&& u.expr->is_expression_list()
6851+
)
6852+
{
6853+
auto l = const_cast<expression_list_node*>(u.expr->get_expression_list());
6854+
l->inside_initializer = true;
6855+
for (auto& e : l->expressions) {
6856+
mark_nested_inside_initializer(e);
6857+
}
6858+
}
6859+
}
6860+
};
6861+
mark_nested_inside_initializer(t);
6862+
n->expressions.push_back(std::move(t));
6863+
};
6864+
68456865
// Otherwise remember the first expression
6846-
n->expressions.push_back( { pass, std::move(x) } );
6866+
add_expression( { pass, std::move(x) } );
68476867
// and see if there are more...
68486868
while (curr().type() == lexeme::Comma) {
68496869
next();
@@ -6859,7 +6879,7 @@ class parser
68596879
error("invalid text in expression list", true, {}, true);
68606880
return {};
68616881
}
6862-
n->expressions.push_back( { pass, std::move(expr) } );
6882+
add_expression( { pass, std::move(expr) } );
68636883
}
68646884

68656885
return n;

source/to_cpp1.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4114,7 +4114,22 @@ class cppfront
41144114

41154115
assert(x.expr);
41164116
current_args.push_back( {x.pass} );
4117-
emit(*x.expr);
4117+
// In a nested expression-list in an initializer, we can
4118+
// take over direct control of emitting it without needing to
4119+
// go through the whole grammar, and surround it with braces
4120+
if (
4121+
n.inside_initializer
4122+
&& x.expr->is_expression_list()
4123+
)
4124+
{
4125+
printer.print_cpp2( "{ ", n.position() );
4126+
emit(*x.expr->get_expression_list(), false);
4127+
printer.print_cpp2( " }", n.position() );
4128+
}
4129+
// Otherwise, just emit the general expression as usual
4130+
else {
4131+
emit(*x.expr);
4132+
}
41184133
current_args.pop_back();
41194134

41204135
if (is_out) {

0 commit comments

Comments
 (0)