mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-11-10 12:28:25 +00:00
Lex and parse support for ... statements and expand. (#7832)
No support for `each` yet, but this should be enough that we can try out an implementation approach supporting expanding a statement across elements of a tuple without building "real" variadics. Assisted-by: Claude via Antigravity
This commit is contained in:
1 parent
ae5d1efd13
commit
2ec4bab59b
12 files changed
+958
-430
No files matched your search
@@ -0,0 +1,25 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include "toolchain/check/context.h"
|
||||
#include "toolchain/check/handle.h"
|
||||
|
||||
namespace Carbon::Check {
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::PackExpansionStartId node_id)
|
||||
-> bool {
|
||||
return context.TODO(node_id, "HandlePackExpansionStart");
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::PackExpansionStatementId node_id)
|
||||
-> bool {
|
||||
return context.TODO(node_id, "HandlePackExpansionStatement");
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::PrefixOperatorExpandId node_id)
|
||||
-> bool {
|
||||
return context.TODO(node_id, "HandlePrefixOperatorExpand");
|
||||
}
|
||||
|
||||
} // namespace Carbon::Check
|
||||
@@ -468,6 +468,7 @@ class NodeStack {
|
||||
case Parse::NodeKind::LetInitializer:
|
||||
case Parse::NodeKind::LetIntroducer:
|
||||
case Parse::NodeKind::NamedConstraintIntroducer:
|
||||
case Parse::NodeKind::PackExpansionStart:
|
||||
case Parse::NodeKind::RefBindingName:
|
||||
case Parse::NodeKind::RuntimeBindingName:
|
||||
case Parse::NodeKind::ReturnStatementStart:
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/primitives.carbon
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/variadics/pack_expansion.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/variadics/pack_expansion.carbon
|
||||
|
||||
// --- fail_todo_pack_expansion_statement.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_todo_pack_expansion_statement.carbon:[[@LINE+4]]:3: error: semantics TODO: `HandlePackExpansionStart` [SemanticsTodo]
|
||||
// CHECK:STDERR: ... F();
|
||||
// CHECK:STDERR: ^~~
|
||||
// CHECK:STDERR:
|
||||
... F();
|
||||
}
|
||||
|
||||
// --- fail_todo_expand.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F(x: (i32, i32)) {
|
||||
// CHECK:STDERR: fail_todo_expand.carbon:[[@LINE+4]]:3: error: semantics TODO: `HandlePrefixOperatorExpand` [SemanticsTodo]
|
||||
// CHECK:STDERR: expand x;
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
expand x;
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lex/testdata/periods.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lex/testdata/periods.carbon
|
||||
// CHECK:STDOUT: - filename: periods.carbon
|
||||
// CHECK:STDOUT: tokens:
|
||||
|
||||
. .. ... .... ...... ...expand
|
||||
// CHECK:STDOUT: - { index: 1, kind: "Period", line: {{ *}}[[@LINE-1]], column: 1, indent: 1, spelling: ".", has_leading_space: true }
|
||||
// CHECK:STDOUT: - { index: 2, kind: "Period", line: {{ *}}[[@LINE-2]], column: 3, indent: 1, spelling: ".", has_leading_space: true }
|
||||
// CHECK:STDOUT: - { index: 3, kind: "Period", line: {{ *}}[[@LINE-3]], column: 4, indent: 1, spelling: "." }
|
||||
// CHECK:STDOUT: - { index: 4, kind: "PeriodPeriodPeriod", line: {{ *}}[[@LINE-4]], column: 6, indent: 1, spelling: "...", has_leading_space: true }
|
||||
// CHECK:STDOUT: - { index: 5, kind: "PeriodPeriodPeriod", line: {{ *}}[[@LINE-5]], column: 10, indent: 1, spelling: "...", has_leading_space: true }
|
||||
// CHECK:STDOUT: - { index: 6, kind: "Period", line: {{ *}}[[@LINE-6]], column: 13, indent: 1, spelling: "." }
|
||||
// CHECK:STDOUT: - { index: 7, kind: "PeriodPeriodPeriod", line: {{ *}}[[@LINE-7]], column: 15, indent: 1, spelling: "...", has_leading_space: true }
|
||||
// CHECK:STDOUT: - { index: 8, kind: "PeriodPeriodPeriod", line: {{ *}}[[@LINE-8]], column: 18, indent: 1, spelling: "..." }
|
||||
// CHECK:STDOUT: - { index: 9, kind: "PeriodPeriodPeriod", line: {{ *}}[[@LINE-9]], column: 22, indent: 1, spelling: "...", has_leading_space: true }
|
||||
// CHECK:STDOUT: - { index: 10, kind: "Expand", line: {{ *}}[[@LINE-10]], column: 25, indent: 1, spelling: "expand" }
|
||||
@@ -60,6 +60,8 @@ CARBON_SYMBOL_TOKEN(GreaterGreaterEqual, ">>=")
|
||||
CARBON_SYMBOL_TOKEN(LessEqualGreater, "<=>")
|
||||
CARBON_SYMBOL_TOKEN(LessLessEqual, "<<=")
|
||||
CARBON_SYMBOL_TOKEN(MinusGreaterQuestion,"->?")
|
||||
CARBON_TOKEN_WITH_VIRTUAL_NODE(
|
||||
CARBON_SYMBOL_TOKEN(PeriodPeriodPeriod, "..."))
|
||||
|
||||
CARBON_SYMBOL_TOKEN(AmpEqual, "&=")
|
||||
CARBON_SYMBOL_TOKEN(CaretEqual, "^=")
|
||||
@@ -189,6 +191,7 @@ CARBON_KEYWORD_TOKEN(Cpp, "Cpp")
|
||||
CARBON_KEYWORD_TOKEN(Default, "default")
|
||||
CARBON_KEYWORD_TOKEN(Else, "else")
|
||||
CARBON_KEYWORD_TOKEN(Eval, "eval")
|
||||
CARBON_KEYWORD_TOKEN(Expand, "expand")
|
||||
CARBON_KEYWORD_TOKEN(Extend, "extend")
|
||||
CARBON_KEYWORD_TOKEN(Extern, "extern")
|
||||
CARBON_KEYWORD_TOKEN(False, "false")
|
||||
|
||||
@@ -51,6 +51,12 @@ auto HandleStatement(Context& context) -> void {
|
||||
context.PushState(StateKind::MatchIntroducer);
|
||||
break;
|
||||
}
|
||||
case Lex::TokenKind::PeriodPeriodPeriod: {
|
||||
context.PushState(StateKind::StatementPackExpansionFinish);
|
||||
context.AddLeafNode(NodeKind::PackExpansionStart, context.Consume());
|
||||
context.PushState(StateKind::Statement);
|
||||
break;
|
||||
}
|
||||
#define CARBON_PARSE_NODE_KIND(Name)
|
||||
#define CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Name) case Lex::TokenKind::Name:
|
||||
#include "toolchain/parse/node_kind.def"
|
||||
@@ -228,6 +234,13 @@ auto HandleStatementReturnFinish(Context& context) -> void {
|
||||
HandleStatementKeywordFinish(context, NodeKind::ReturnStatement);
|
||||
}
|
||||
|
||||
auto HandleStatementPackExpansionFinish(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
|
||||
context.AddNode(NodeKind::PackExpansionStatement, state.token,
|
||||
state.has_error);
|
||||
}
|
||||
|
||||
auto HandleStatementScopeLoop(Context& context) -> void {
|
||||
// This maintains the current state until we're at the end of the scope.
|
||||
|
||||
|
||||
@@ -286,6 +286,9 @@ CARBON_PARSE_NODE_KIND_STATEMENT(WhileConditionStart)
|
||||
CARBON_PARSE_NODE_KIND_STATEMENT(WhileCondition)
|
||||
CARBON_PARSE_NODE_KIND_STATEMENT(WhileStatement)
|
||||
|
||||
CARBON_PARSE_NODE_KIND_STATEMENT(PackExpansionStart)
|
||||
CARBON_PARSE_NODE_KIND_STATEMENT(PackExpansionStatement)
|
||||
|
||||
CARBON_PARSE_NODE_KIND_EXPRESSION(IndexExprStart)
|
||||
CARBON_PARSE_NODE_KIND_EXPRESSION(IndexExpr)
|
||||
|
||||
@@ -337,6 +340,7 @@ CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(UnsignedIntTypeLiteral,
|
||||
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Amp)
|
||||
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Caret)
|
||||
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Const)
|
||||
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Expand)
|
||||
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Not)
|
||||
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Minus)
|
||||
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(MinusMinus)
|
||||
|
||||
@@ -149,6 +149,7 @@ auto PrecedenceGroup::ForLeading(Lex::TokenKind kind)
|
||||
switch (kind) {
|
||||
case Lex::TokenKind::Star:
|
||||
case Lex::TokenKind::Amp:
|
||||
case Lex::TokenKind::Expand:
|
||||
return PrecedenceGroup(TermPrefix);
|
||||
|
||||
case Lex::TokenKind::Not:
|
||||
@@ -249,6 +250,7 @@ auto PrecedenceGroup::ForTrailing(Lex::TokenKind kind, bool infix)
|
||||
|
||||
// Prefix-only operators.
|
||||
case Lex::TokenKind::Const:
|
||||
case Lex::TokenKind::Expand:
|
||||
case Lex::TokenKind::MinusMinus:
|
||||
case Lex::TokenKind::Not:
|
||||
case Lex::TokenKind::Partial:
|
||||
|
||||
+442
-430
File diff suppressed because it is too large.
Load diff
+196
@@ -0,0 +1,196 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/variadics/expand.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/variadics/expand.carbon
|
||||
|
||||
// --- basic.carbon
|
||||
|
||||
var a: auto = expand x;
|
||||
|
||||
// --- precedence.carbon
|
||||
|
||||
// `expand` has the same precedence as prefix `*`.
|
||||
var a: auto = expand x.y;
|
||||
var b: auto = expand x.(0);
|
||||
var c: auto = expand F();
|
||||
var d: auto = expand x + 1;
|
||||
var e: auto = expand x * 2;
|
||||
var f: auto = expand *x;
|
||||
var g: auto = *expand x;
|
||||
var h: auto = expand expand x;
|
||||
var i: auto = -expand x;
|
||||
|
||||
// --- fail_under_not.carbon
|
||||
|
||||
// Like prefix `*`, `expand` requires parentheses under `not`.
|
||||
// CHECK:STDERR: fail_under_not.carbon:[[@LINE+4]]:19: error: parentheses are required around this unary `expand` operator [UnaryOperatorRequiresParentheses]
|
||||
// CHECK:STDERR: var a: auto = not expand x;
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR:
|
||||
var a: auto = not expand x;
|
||||
|
||||
// --- fail_as_postfix.carbon
|
||||
|
||||
// CHECK:STDERR: fail_as_postfix.carbon:[[@LINE+4]]:17: error: `var` declarations must end with a `;` [ExpectedDeclSemi]
|
||||
// CHECK:STDERR: var a: auto = x expand;
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR:
|
||||
var a: auto = x expand;
|
||||
|
||||
// CHECK:STDOUT: - filename: basic.carbon
|
||||
// CHECK:STDOUT: ╭─FileStart ''
|
||||
// CHECK:STDOUT: │ ╭─VariableIntroducer 'var'
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameNotBeforeSignature 'a'
|
||||
// CHECK:STDOUT: │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ ├─AutoTypeLiteral 'auto'
|
||||
// CHECK:STDOUT: │ │ ╭─VarBindingPattern ':'
|
||||
// CHECK:STDOUT: │ ├─VariablePattern 'var'
|
||||
// CHECK:STDOUT: │ ├─VariableInitializer '='
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ ├─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: ├─VariableDecl ';'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
// CHECK:STDOUT: (root)
|
||||
// CHECK:STDOUT: - filename: precedence.carbon
|
||||
// CHECK:STDOUT: ╭─FileStart ''
|
||||
// CHECK:STDOUT: │ ╭─VariableIntroducer 'var'
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameNotBeforeSignature 'a'
|
||||
// CHECK:STDOUT: │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ ├─AutoTypeLiteral 'auto'
|
||||
// CHECK:STDOUT: │ │ ╭─VarBindingPattern ':'
|
||||
// CHECK:STDOUT: │ ├─VariablePattern 'var'
|
||||
// CHECK:STDOUT: │ ├─VariableInitializer '='
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ │ ├─IdentifierNameNotBeforeSignature 'y'
|
||||
// CHECK:STDOUT: │ │ ╭─MemberAccessExpr '.'
|
||||
// CHECK:STDOUT: │ ├─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: ├─VariableDecl ';'
|
||||
// CHECK:STDOUT: │ ╭─VariableIntroducer 'var'
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameNotBeforeSignature 'b'
|
||||
// CHECK:STDOUT: │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ ├─AutoTypeLiteral 'auto'
|
||||
// CHECK:STDOUT: │ │ ╭─VarBindingPattern ':'
|
||||
// CHECK:STDOUT: │ ├─VariablePattern 'var'
|
||||
// CHECK:STDOUT: │ ├─VariableInitializer '='
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ │ │ ╭─ParenExprStart '('
|
||||
// CHECK:STDOUT: │ │ │ ├─IntLiteral '0'
|
||||
// CHECK:STDOUT: │ │ ├─ParenExpr ')'
|
||||
// CHECK:STDOUT: │ │ ╭─MemberAccessExpr '.'
|
||||
// CHECK:STDOUT: │ ├─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: ├─VariableDecl ';'
|
||||
// CHECK:STDOUT: │ ╭─VariableIntroducer 'var'
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameNotBeforeSignature 'c'
|
||||
// CHECK:STDOUT: │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ ├─AutoTypeLiteral 'auto'
|
||||
// CHECK:STDOUT: │ │ ╭─VarBindingPattern ':'
|
||||
// CHECK:STDOUT: │ ├─VariablePattern 'var'
|
||||
// CHECK:STDOUT: │ ├─VariableInitializer '='
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameExpr 'F'
|
||||
// CHECK:STDOUT: │ │ ╭─CallExprStart '('
|
||||
// CHECK:STDOUT: │ │ ╭─CallExpr ')'
|
||||
// CHECK:STDOUT: │ ├─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: ├─VariableDecl ';'
|
||||
// CHECK:STDOUT: │ ╭─VariableIntroducer 'var'
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameNotBeforeSignature 'd'
|
||||
// CHECK:STDOUT: │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ ├─AutoTypeLiteral 'auto'
|
||||
// CHECK:STDOUT: │ │ ╭─VarBindingPattern ':'
|
||||
// CHECK:STDOUT: │ ├─VariablePattern 'var'
|
||||
// CHECK:STDOUT: │ ├─VariableInitializer '='
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ │ ╭─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: │ │ ├─IntLiteral '1'
|
||||
// CHECK:STDOUT: │ ├─InfixOperatorPlus '+'
|
||||
// CHECK:STDOUT: ├─VariableDecl ';'
|
||||
// CHECK:STDOUT: │ ╭─VariableIntroducer 'var'
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameNotBeforeSignature 'e'
|
||||
// CHECK:STDOUT: │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ ├─AutoTypeLiteral 'auto'
|
||||
// CHECK:STDOUT: │ │ ╭─VarBindingPattern ':'
|
||||
// CHECK:STDOUT: │ ├─VariablePattern 'var'
|
||||
// CHECK:STDOUT: │ ├─VariableInitializer '='
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ │ ╭─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: │ │ ├─IntLiteral '2'
|
||||
// CHECK:STDOUT: │ ├─InfixOperatorStar '*'
|
||||
// CHECK:STDOUT: ├─VariableDecl ';'
|
||||
// CHECK:STDOUT: │ ╭─VariableIntroducer 'var'
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameNotBeforeSignature 'f'
|
||||
// CHECK:STDOUT: │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ ├─AutoTypeLiteral 'auto'
|
||||
// CHECK:STDOUT: │ │ ╭─VarBindingPattern ':'
|
||||
// CHECK:STDOUT: │ ├─VariablePattern 'var'
|
||||
// CHECK:STDOUT: │ ├─VariableInitializer '='
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ │ ╭─PrefixOperatorStar '*'
|
||||
// CHECK:STDOUT: │ ├─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: ├─VariableDecl ';'
|
||||
// CHECK:STDOUT: │ ╭─VariableIntroducer 'var'
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameNotBeforeSignature 'g'
|
||||
// CHECK:STDOUT: │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ ├─AutoTypeLiteral 'auto'
|
||||
// CHECK:STDOUT: │ │ ╭─VarBindingPattern ':'
|
||||
// CHECK:STDOUT: │ ├─VariablePattern 'var'
|
||||
// CHECK:STDOUT: │ ├─VariableInitializer '='
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ │ ╭─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: │ ├─PrefixOperatorStar '*'
|
||||
// CHECK:STDOUT: ├─VariableDecl ';'
|
||||
// CHECK:STDOUT: │ ╭─VariableIntroducer 'var'
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameNotBeforeSignature 'h'
|
||||
// CHECK:STDOUT: │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ ├─AutoTypeLiteral 'auto'
|
||||
// CHECK:STDOUT: │ │ ╭─VarBindingPattern ':'
|
||||
// CHECK:STDOUT: │ ├─VariablePattern 'var'
|
||||
// CHECK:STDOUT: │ ├─VariableInitializer '='
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ │ ╭─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: │ ├─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: ├─VariableDecl ';'
|
||||
// CHECK:STDOUT: │ ╭─VariableIntroducer 'var'
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameNotBeforeSignature 'i'
|
||||
// CHECK:STDOUT: │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ ├─AutoTypeLiteral 'auto'
|
||||
// CHECK:STDOUT: │ │ ╭─VarBindingPattern ':'
|
||||
// CHECK:STDOUT: │ ├─VariablePattern 'var'
|
||||
// CHECK:STDOUT: │ ├─VariableInitializer '='
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ │ ╭─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: │ ├─PrefixOperatorMinus '-'
|
||||
// CHECK:STDOUT: ├─VariableDecl ';'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
// CHECK:STDOUT: (root)
|
||||
// CHECK:STDOUT: - filename: fail_under_not.carbon
|
||||
// CHECK:STDOUT: ╭─FileStart ''
|
||||
// CHECK:STDOUT: │ ╭─VariableIntroducer 'var'
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameNotBeforeSignature 'a'
|
||||
// CHECK:STDOUT: │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ ├─AutoTypeLiteral 'auto'
|
||||
// CHECK:STDOUT: │ │ ╭─VarBindingPattern ':'
|
||||
// CHECK:STDOUT: │ ├─VariablePattern 'var'
|
||||
// CHECK:STDOUT: │ ├─VariableInitializer '='
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ │ ╭─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: │ ├─PrefixOperatorNot 'not'
|
||||
// CHECK:STDOUT: ├─VariableDecl ';'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
// CHECK:STDOUT: (root)
|
||||
// CHECK:STDOUT: - filename: fail_as_postfix.carbon
|
||||
// CHECK:STDOUT: ╭─FileStart ''
|
||||
// CHECK:STDOUT: │ ╭─VariableIntroducer 'var'
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameNotBeforeSignature 'a'
|
||||
// CHECK:STDOUT: │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ ├─AutoTypeLiteral 'auto'
|
||||
// CHECK:STDOUT: │ │ ╭─VarBindingPattern ':'
|
||||
// CHECK:STDOUT: │ ├─VariablePattern 'var'
|
||||
// CHECK:STDOUT: │ ├─VariableInitializer '='
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: ├─VariableDecl ';' has_error
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
// CHECK:STDOUT: (root)
|
||||
@@ -0,0 +1,197 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/variadics/pack_expansion_statement.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/variadics/pack_expansion_statement.carbon
|
||||
|
||||
// --- expr_statement.carbon
|
||||
|
||||
fn F() {
|
||||
... G(expand x);
|
||||
}
|
||||
|
||||
// --- var_statement.carbon
|
||||
|
||||
fn F() {
|
||||
... var y: auto = expand x;
|
||||
}
|
||||
|
||||
// --- compound_statements.carbon
|
||||
|
||||
fn F() {
|
||||
... if (expand c) {
|
||||
G(expand x);
|
||||
} else {
|
||||
H(expand y);
|
||||
}
|
||||
... while (expand c) {}
|
||||
... return;
|
||||
}
|
||||
|
||||
// --- nested.carbon
|
||||
|
||||
fn F() {
|
||||
... ... G(expand x);
|
||||
}
|
||||
|
||||
// --- fail_missing_statement.carbon
|
||||
|
||||
fn F() {
|
||||
...
|
||||
// CHECK:STDERR: fail_missing_statement.carbon:[[@LINE+4]]:1: error: expected expression [ExpectedExpr]
|
||||
// CHECK:STDERR: }
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
}
|
||||
|
||||
// --- fail_missing_semi.carbon
|
||||
|
||||
fn F() {
|
||||
... G()
|
||||
// CHECK:STDERR: fail_missing_semi.carbon:[[@LINE+4]]:1: error: expected `;` after expression statement [ExpectedExprSemi]
|
||||
// CHECK:STDERR: }
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: - filename: expr_statement.carbon
|
||||
// CHECK:STDOUT: ╭─FileStart ''
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'F'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')'
|
||||
// CHECK:STDOUT: │ ╭─FunctionDefinitionStart '{'
|
||||
// CHECK:STDOUT: │ │ ╭─PackExpansionStart '...'
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameExpr 'G'
|
||||
// CHECK:STDOUT: │ │ │ ╭─CallExprStart '('
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ │ │ ├─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: │ │ │ ╭─CallExpr ')'
|
||||
// CHECK:STDOUT: │ │ ├─ExprStatement ';'
|
||||
// CHECK:STDOUT: │ ├─PackExpansionStatement '...'
|
||||
// CHECK:STDOUT: ├─FunctionDefinition '}'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
// CHECK:STDOUT: (root)
|
||||
// CHECK:STDOUT: - filename: var_statement.carbon
|
||||
// CHECK:STDOUT: ╭─FileStart ''
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'F'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')'
|
||||
// CHECK:STDOUT: │ ╭─FunctionDefinitionStart '{'
|
||||
// CHECK:STDOUT: │ │ ╭─PackExpansionStart '...'
|
||||
// CHECK:STDOUT: │ │ │ ╭─VariableIntroducer 'var'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'y'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─AutoTypeLiteral 'auto'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─VarBindingPattern ':'
|
||||
// CHECK:STDOUT: │ │ │ ├─VariablePattern 'var'
|
||||
// CHECK:STDOUT: │ │ │ ├─VariableInitializer '='
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ │ │ ├─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: │ │ ├─VariableDecl ';'
|
||||
// CHECK:STDOUT: │ ├─PackExpansionStatement '...'
|
||||
// CHECK:STDOUT: ├─FunctionDefinition '}'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
// CHECK:STDOUT: (root)
|
||||
// CHECK:STDOUT: - filename: compound_statements.carbon
|
||||
// CHECK:STDOUT: ╭─FileStart ''
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'F'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')'
|
||||
// CHECK:STDOUT: │ ╭─FunctionDefinitionStart '{'
|
||||
// CHECK:STDOUT: │ │ ╭─PackExpansionStart '...'
|
||||
// CHECK:STDOUT: │ │ │ ╭─IfConditionStart '('
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'c'
|
||||
// CHECK:STDOUT: │ │ │ ├─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: │ │ │ ╭─IfCondition ')'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─CodeBlockStart '{'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─IdentifierNameExpr 'G'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─CallExprStart '('
|
||||
// CHECK:STDOUT: │ │ │ │ │ │ ╭─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ├─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─CallExpr ')'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─ExprStatement ';'
|
||||
// CHECK:STDOUT: │ │ │ ├─CodeBlock '}'
|
||||
// CHECK:STDOUT: │ │ │ ├─IfStatementElse 'else'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─CodeBlockStart '{'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─IdentifierNameExpr 'H'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─CallExprStart '('
|
||||
// CHECK:STDOUT: │ │ │ │ │ │ ╭─IdentifierNameExpr 'y'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ├─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─CallExpr ')'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─ExprStatement ';'
|
||||
// CHECK:STDOUT: │ │ │ ├─CodeBlock '}'
|
||||
// CHECK:STDOUT: │ │ ├─IfStatement 'if'
|
||||
// CHECK:STDOUT: │ ├─PackExpansionStatement '...'
|
||||
// CHECK:STDOUT: │ │ ╭─PackExpansionStart '...'
|
||||
// CHECK:STDOUT: │ │ │ ╭─WhileConditionStart '('
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'c'
|
||||
// CHECK:STDOUT: │ │ │ ├─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: │ │ │ ╭─WhileCondition ')'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─CodeBlockStart '{'
|
||||
// CHECK:STDOUT: │ │ │ ├─CodeBlock '}'
|
||||
// CHECK:STDOUT: │ │ ├─WhileStatement 'while'
|
||||
// CHECK:STDOUT: │ ├─PackExpansionStatement '...'
|
||||
// CHECK:STDOUT: │ │ ╭─PackExpansionStart '...'
|
||||
// CHECK:STDOUT: │ │ │ ╭─ReturnStatementStart 'return'
|
||||
// CHECK:STDOUT: │ │ ├─ReturnStatement ';'
|
||||
// CHECK:STDOUT: │ ├─PackExpansionStatement '...'
|
||||
// CHECK:STDOUT: ├─FunctionDefinition '}'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
// CHECK:STDOUT: (root)
|
||||
// CHECK:STDOUT: - filename: nested.carbon
|
||||
// CHECK:STDOUT: ╭─FileStart ''
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'F'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')'
|
||||
// CHECK:STDOUT: │ ╭─FunctionDefinitionStart '{'
|
||||
// CHECK:STDOUT: │ │ ╭─PackExpansionStart '...'
|
||||
// CHECK:STDOUT: │ │ │ ╭─PackExpansionStart '...'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameExpr 'G'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─CallExprStart '('
|
||||
// CHECK:STDOUT: │ │ │ │ │ ╭─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ │ │ │ ├─PrefixOperatorExpand 'expand'
|
||||
// CHECK:STDOUT: │ │ │ │ ╭─CallExpr ')'
|
||||
// CHECK:STDOUT: │ │ │ ├─ExprStatement ';'
|
||||
// CHECK:STDOUT: │ │ ├─PackExpansionStatement '...'
|
||||
// CHECK:STDOUT: │ ├─PackExpansionStatement '...'
|
||||
// CHECK:STDOUT: ├─FunctionDefinition '}'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
// CHECK:STDOUT: (root)
|
||||
// CHECK:STDOUT: - filename: fail_missing_statement.carbon
|
||||
// CHECK:STDOUT: ╭─FileStart ''
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'F'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')'
|
||||
// CHECK:STDOUT: │ ╭─FunctionDefinitionStart '{'
|
||||
// CHECK:STDOUT: │ │ ╭─PackExpansionStart '...'
|
||||
// CHECK:STDOUT: │ │ │ ╭─InvalidParse '}' has_error
|
||||
// CHECK:STDOUT: │ │ ├─ExprStatement '...' has_error
|
||||
// CHECK:STDOUT: │ ├─PackExpansionStatement '...'
|
||||
// CHECK:STDOUT: ├─FunctionDefinition '}'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
// CHECK:STDOUT: (root)
|
||||
// CHECK:STDOUT: - filename: fail_missing_semi.carbon
|
||||
// CHECK:STDOUT: ╭─FileStart ''
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'F'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')'
|
||||
// CHECK:STDOUT: │ ╭─FunctionDefinitionStart '{'
|
||||
// CHECK:STDOUT: │ │ ╭─PackExpansionStart '...'
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameExpr 'G'
|
||||
// CHECK:STDOUT: │ │ │ ╭─CallExprStart '('
|
||||
// CHECK:STDOUT: │ │ │ ╭─CallExpr ')'
|
||||
// CHECK:STDOUT: │ │ ├─ExprStatement ')' has_error
|
||||
// CHECK:STDOUT: │ ├─PackExpansionStatement '...'
|
||||
// CHECK:STDOUT: ├─FunctionDefinition '}'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
// CHECK:STDOUT: (root)
|
||||
@@ -954,6 +954,25 @@ struct WhileStatement {
|
||||
CodeBlockId body;
|
||||
};
|
||||
|
||||
// The start of a pack expansion: `...`. This marks the beginning of the
|
||||
// expanded region.
|
||||
using PackExpansionStart =
|
||||
LeafNode<NodeKind::PackExpansionStart, Lex::PeriodPeriodPeriodTokenIndex>;
|
||||
|
||||
// A statement pack expansion: `... statement`.
|
||||
struct PackExpansionStatement {
|
||||
static constexpr auto Kind = NodeKind::PackExpansionStatement.Define(
|
||||
{.category = NodeCategory::Statement,
|
||||
.bracketed_by = PackExpansionStart::Kind,
|
||||
.child_count = 2});
|
||||
|
||||
PackExpansionStartId start;
|
||||
AnyStatementId body;
|
||||
// This is a virtual token. The `...` token is owned by the
|
||||
// PackExpansionStart node.
|
||||
Lex::PeriodPeriodPeriodTokenIndex token;
|
||||
};
|
||||
|
||||
using MatchConditionStart =
|
||||
LeafNode<NodeKind::MatchConditionStart, Lex::OpenParenTokenIndex>;
|
||||
|
||||
|
||||
Reference in new issue
Block a user