Skip to content

Commit

Permalink
lambda expressions: support capture syntax through cpp20
Browse files Browse the repository at this point in the history
  • Loading branch information
jdrouhard committed Sep 20, 2024
1 parent 30f973c commit 0fc8c8c
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 8 deletions.
37 changes: 35 additions & 2 deletions grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ module.exports = grammar(C, {
[$.expression, $._declarator],
[$.expression, $.structured_binding_declarator],
[$.expression, $._declarator, $.type_specifier],
[$.expression, $.identifier_parameter_pack_expansion],
[$.expression, $._lambda_capture_identifier],
[$.expression, $._lambda_capture],
[$.expression, $.structured_binding_declarator, $._lambda_capture_identifier],
[$.structured_binding_declarator, $._lambda_capture_identifier],
[$.parameter_list, $.argument_list],
[$.type_specifier, $.call_expression],
[$._declaration_specifiers, $._constructor_specifiers],
Expand Down Expand Up @@ -1094,17 +1099,40 @@ module.exports = grammar(C, {
'[',
choice(
$.lambda_default_capture,
commaSep($.expression),
commaSep($._lambda_capture),
seq(
$.lambda_default_capture,
',', commaSep1($.expression),
',', commaSep1($._lambda_capture),
),
),
']',
)),

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

_lambda_capture_identifier: $ => seq(
optional('&'),
choice(
$.identifier,
$.qualified_identifier,
alias($.identifier_parameter_pack_expansion, $.parameter_pack_expansion),
),
),

lambda_capture_initializer: $ => seq(
optional('&'),
optional('...'),
field('left', $.identifier),
'=',
field('right', $.expression),
),

_lambda_capture: $ => choice(
seq(optional('*'), $.this),
$._lambda_capture_identifier,
$.lambda_capture_initializer,
),

_fold_operator: _ => choice(...FOLD_OPERATORS),
_binary_fold_operator: _ => choice(...FOLD_OPERATORS.map((operator) => seq(field('operator', operator), '...', operator))),

Expand Down Expand Up @@ -1144,6 +1172,11 @@ module.exports = grammar(C, {
'...',
),

identifier_parameter_pack_expansion: $ => seq(
field('pattern', $.identifier),
'...',
),

sizeof_expression: ($, original) => prec.right(PREC.SIZEOF, choice(
original,
seq(
Expand Down
100 changes: 94 additions & 6 deletions test/corpus/expressions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -278,22 +278,30 @@ auto f = [&](int x) -> bool {
return true;
};

auto g = [x, y](int z) {
auto f = [x, y](int z) {
return false;
};

auto h = [] {
auto f = [] {
return false;
};

auto i = [] <typename T> () {
auto f = [] <typename T> () {
return T();
};

auto i = [] <typename T> requires Hashable<T> {
auto f = [] <typename T> requires Hashable<T> {
return T();
};

auto f = [... args = std::forward<Args>(args)](auto &&func) mutable {
return std::invoke(std::forward<decltype(func)>(func), std::forward<Args>(args)...);
};

auto f = [&arg, &...etc = etc] {};

auto f = [=, *this, &args...] {};

--------------------------------------------------------------------------------

(translation_unit
Expand Down Expand Up @@ -380,7 +388,87 @@ auto i = [] <typename T> requires Hashable<T> {
(return_statement
(call_expression
(identifier)
(argument_list))))))))
(argument_list)))))))
(declaration
(placeholder_type_specifier
(auto))
(init_declarator
(identifier)
(lambda_expression
(lambda_capture_specifier
(lambda_capture_initializer
(identifier)
(call_expression
(qualified_identifier
(namespace_identifier)
(template_function
(identifier)
(template_argument_list
(type_descriptor
(type_identifier)))))
(argument_list
(identifier)))))
(abstract_function_declarator
(parameter_list
(parameter_declaration
(placeholder_type_specifier
(auto))
(reference_declarator
(identifier))))
(type_qualifier))
(compound_statement
(return_statement
(call_expression
(qualified_identifier
(namespace_identifier)
(identifier))
(argument_list
(call_expression
(qualified_identifier
(namespace_identifier)
(template_function
(identifier)
(template_argument_list
(type_descriptor
(decltype
(identifier))))))
(argument_list
(identifier)))
(parameter_pack_expansion
(call_expression
(qualified_identifier
(namespace_identifier)
(template_function
(identifier)
(template_argument_list
(type_descriptor
(type_identifier)))))
(argument_list
(identifier)))))))))))
(declaration
(placeholder_type_specifier
(auto))
(init_declarator
(identifier)
(lambda_expression
(lambda_capture_specifier
(identifier)
(lambda_capture_initializer
(identifier)
(identifier)))
(compound_statement))))
(declaration
(placeholder_type_specifier
(auto))
(init_declarator
(identifier)
(lambda_expression
(lambda_capture_specifier
(lambda_default_capture)
(this)
(parameter_pack_expansion
(identifier)))
(compound_statement)))))

================================================================================
Nested template calls
Expand Down Expand Up @@ -1555,4 +1643,4 @@ template <typename... Args> void negateValues(Args... args) {
(unary_expression
(identifier)))
(string_literal
(string_content))))))))))
(string_content))))))))))

0 comments on commit 0fc8c8c

Please sign in to comment.