Skip to content

Commit 0fc8c8c

Browse files
committed
lambda expressions: support capture syntax through cpp20
1 parent 30f973c commit 0fc8c8c

File tree

2 files changed

+129
-8
lines changed

2 files changed

+129
-8
lines changed

grammar.js

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ module.exports = grammar(C, {
7878
[$.expression, $._declarator],
7979
[$.expression, $.structured_binding_declarator],
8080
[$.expression, $._declarator, $.type_specifier],
81+
[$.expression, $.identifier_parameter_pack_expansion],
82+
[$.expression, $._lambda_capture_identifier],
83+
[$.expression, $._lambda_capture],
84+
[$.expression, $.structured_binding_declarator, $._lambda_capture_identifier],
85+
[$.structured_binding_declarator, $._lambda_capture_identifier],
8186
[$.parameter_list, $.argument_list],
8287
[$.type_specifier, $.call_expression],
8388
[$._declaration_specifiers, $._constructor_specifiers],
@@ -1094,17 +1099,40 @@ module.exports = grammar(C, {
10941099
'[',
10951100
choice(
10961101
$.lambda_default_capture,
1097-
commaSep($.expression),
1102+
commaSep($._lambda_capture),
10981103
seq(
10991104
$.lambda_default_capture,
1100-
',', commaSep1($.expression),
1105+
',', commaSep1($._lambda_capture),
11011106
),
11021107
),
11031108
']',
11041109
)),
11051110

11061111
lambda_default_capture: _ => choice('=', '&'),
11071112

1113+
_lambda_capture_identifier: $ => seq(
1114+
optional('&'),
1115+
choice(
1116+
$.identifier,
1117+
$.qualified_identifier,
1118+
alias($.identifier_parameter_pack_expansion, $.parameter_pack_expansion),
1119+
),
1120+
),
1121+
1122+
lambda_capture_initializer: $ => seq(
1123+
optional('&'),
1124+
optional('...'),
1125+
field('left', $.identifier),
1126+
'=',
1127+
field('right', $.expression),
1128+
),
1129+
1130+
_lambda_capture: $ => choice(
1131+
seq(optional('*'), $.this),
1132+
$._lambda_capture_identifier,
1133+
$.lambda_capture_initializer,
1134+
),
1135+
11081136
_fold_operator: _ => choice(...FOLD_OPERATORS),
11091137
_binary_fold_operator: _ => choice(...FOLD_OPERATORS.map((operator) => seq(field('operator', operator), '...', operator))),
11101138

@@ -1144,6 +1172,11 @@ module.exports = grammar(C, {
11441172
'...',
11451173
),
11461174

1175+
identifier_parameter_pack_expansion: $ => seq(
1176+
field('pattern', $.identifier),
1177+
'...',
1178+
),
1179+
11471180
sizeof_expression: ($, original) => prec.right(PREC.SIZEOF, choice(
11481181
original,
11491182
seq(

test/corpus/expressions.txt

Lines changed: 94 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -278,22 +278,30 @@ auto f = [&](int x) -> bool {
278278
return true;
279279
};
280280

281-
auto g = [x, y](int z) {
281+
auto f = [x, y](int z) {
282282
return false;
283283
};
284284

285-
auto h = [] {
285+
auto f = [] {
286286
return false;
287287
};
288288

289-
auto i = [] <typename T> () {
289+
auto f = [] <typename T> () {
290290
return T();
291291
};
292292

293-
auto i = [] <typename T> requires Hashable<T> {
293+
auto f = [] <typename T> requires Hashable<T> {
294294
return T();
295295
};
296296

297+
auto f = [... args = std::forward<Args>(args)](auto &&func) mutable {
298+
return std::invoke(std::forward<decltype(func)>(func), std::forward<Args>(args)...);
299+
};
300+
301+
auto f = [&arg, &...etc = etc] {};
302+
303+
auto f = [=, *this, &args...] {};
304+
297305
--------------------------------------------------------------------------------
298306

299307
(translation_unit
@@ -380,7 +388,87 @@ auto i = [] <typename T> requires Hashable<T> {
380388
(return_statement
381389
(call_expression
382390
(identifier)
383-
(argument_list))))))))
391+
(argument_list)))))))
392+
(declaration
393+
(placeholder_type_specifier
394+
(auto))
395+
(init_declarator
396+
(identifier)
397+
(lambda_expression
398+
(lambda_capture_specifier
399+
(lambda_capture_initializer
400+
(identifier)
401+
(call_expression
402+
(qualified_identifier
403+
(namespace_identifier)
404+
(template_function
405+
(identifier)
406+
(template_argument_list
407+
(type_descriptor
408+
(type_identifier)))))
409+
(argument_list
410+
(identifier)))))
411+
(abstract_function_declarator
412+
(parameter_list
413+
(parameter_declaration
414+
(placeholder_type_specifier
415+
(auto))
416+
(reference_declarator
417+
(identifier))))
418+
(type_qualifier))
419+
(compound_statement
420+
(return_statement
421+
(call_expression
422+
(qualified_identifier
423+
(namespace_identifier)
424+
(identifier))
425+
(argument_list
426+
(call_expression
427+
(qualified_identifier
428+
(namespace_identifier)
429+
(template_function
430+
(identifier)
431+
(template_argument_list
432+
(type_descriptor
433+
(decltype
434+
(identifier))))))
435+
(argument_list
436+
(identifier)))
437+
(parameter_pack_expansion
438+
(call_expression
439+
(qualified_identifier
440+
(namespace_identifier)
441+
(template_function
442+
(identifier)
443+
(template_argument_list
444+
(type_descriptor
445+
(type_identifier)))))
446+
(argument_list
447+
(identifier)))))))))))
448+
(declaration
449+
(placeholder_type_specifier
450+
(auto))
451+
(init_declarator
452+
(identifier)
453+
(lambda_expression
454+
(lambda_capture_specifier
455+
(identifier)
456+
(lambda_capture_initializer
457+
(identifier)
458+
(identifier)))
459+
(compound_statement))))
460+
(declaration
461+
(placeholder_type_specifier
462+
(auto))
463+
(init_declarator
464+
(identifier)
465+
(lambda_expression
466+
(lambda_capture_specifier
467+
(lambda_default_capture)
468+
(this)
469+
(parameter_pack_expansion
470+
(identifier)))
471+
(compound_statement)))))
384472

385473
================================================================================
386474
Nested template calls
@@ -1555,4 +1643,4 @@ template <typename... Args> void negateValues(Args... args) {
15551643
(unary_expression
15561644
(identifier)))
15571645
(string_literal
1558-
(string_content))))))))))
1646+
(string_content))))))))))

0 commit comments

Comments
 (0)