From 84deb62aef8c92856e7067de1f94e3a4ebc0f8ac Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Mon, 28 Nov 2022 15:02:59 -0800 Subject: [PATCH] Work on ParseTree structure to use more bracketed structures. (#2416) This works on multiple statements to make them better for the bracketing model. Stub nodes are added in more cases of invalid syntax, simply so that the semantics has reliably structured input. Comments in parse_node_kind.def now try to show the expected parse tree structure in postorder form. This labels If, While, and For a little differently in parse nodes so that at the start of the postorder traversal, it'll already be available to semantics which structure is being processed. I need to do a little more with If in particular, but this felt like a reasonable stopping point. While this makes significant parser changes, the changes to parser_state.def are minimal, mostly naming-related. The actual flow isn't substantively changed, just a couple minor names and the new As(If|While) state which allows distinguishing IfCondition and WhileCondition. Co-authored-by: Chandler Carruth --- toolchain/parser/parse_node_kind.cpp | 4 +- toolchain/parser/parse_node_kind.def | 143 ++++++++--- toolchain/parser/parser.cpp | 229 +++++++++--------- toolchain/parser/parser.h | 43 ++-- toolchain/parser/parser_state.def | 26 +- .../basics/fail_paren_match_regression.carbon | 3 +- .../parser/testdata/basics/package.carbon | 16 +- .../parser/testdata/basics/structs.carbon | 12 +- .../parser/testdata/basics/tuples.carbon | 8 +- toolchain/parser/testdata/basics/var.carbon | 12 +- .../for/fail_colon_instead_of_in.carbon | 8 +- .../testdata/for/fail_missing_in.carbon | 12 +- .../testdata/for/fail_missing_var.carbon | 9 +- toolchain/parser/testdata/for/nested.carbon | 16 +- toolchain/parser/testdata/for/simple.carbon | 8 +- toolchain/parser/testdata/if/basic.carbon | 12 +- toolchain/parser/testdata/if/else.carbon | 16 +- .../testdata/if/fail_else_unbraced.carbon | 16 +- .../parser/testdata/if/fail_errors.carbon | 20 +- .../parser/testdata/if/fail_unbraced.carbon | 12 +- .../testdata/operators/fixity_in_var.carbon | 8 +- toolchain/parser/testdata/while/basic.carbon | 12 +- .../parser/testdata/while/fail_no_semi.carbon | 12 +- .../testdata/while/fail_unbraced.carbon | 4 +- 24 files changed, 373 insertions(+), 288 deletions(-) diff --git a/toolchain/parser/parse_node_kind.cpp b/toolchain/parser/parse_node_kind.cpp index d20c42298d8b..ae0dd8a51c30 100644 --- a/toolchain/parser/parse_node_kind.cpp +++ b/toolchain/parser/parse_node_kind.cpp @@ -36,7 +36,7 @@ auto ParseNodeKind::bracket() const -> ParseNodeKind { #include "toolchain/parser/parse_node_kind.def" }; auto bracket = Bracket[static_cast(kind_)]; - CARBON_CHECK(bracket != kind_); + CARBON_CHECK(bracket != kind_) << *this; return bracket; } @@ -48,7 +48,7 @@ auto ParseNodeKind::child_count() const -> int32_t { }; auto child_count = ChildCount[static_cast(kind_)]; // TODO: Allows TodoFixParseNode; see parse_node_kind.def. - CARBON_CHECK(child_count != -1); + CARBON_CHECK(child_count != -1) << *this; return child_count; } diff --git a/toolchain/parser/parse_node_kind.def b/toolchain/parser/parse_node_kind.def index 5d4e88829641..8a9774c95a98 100644 --- a/toolchain/parser/parse_node_kind.def +++ b/toolchain/parser/parse_node_kind.def @@ -41,49 +41,138 @@ CARBON_PARSE_NODE_KIND(Name) #endif -// Declarations. -CARBON_PARSE_NODE_KIND_CHILD_COUNT(DeclarationEnd, 0) +// The end of the file. +CARBON_PARSE_NODE_KIND_CHILD_COUNT(FileEnd, 0) + +// An empty declaration, such as `;`. CARBON_PARSE_NODE_KIND_CHILD_COUNT(EmptyDeclaration, 0) + +// A name. CARBON_PARSE_NODE_KIND_CHILD_COUNT(DeclaredName, 0) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(PackageDirective, TodoFixParseNode) +// `package`: +// PackageIntroducer +// (name) +// (library) +// PackageLibrary +// PackageApi or PackageImpl +// PackageDirective +CARBON_PARSE_NODE_KIND_CHILD_COUNT(PackageIntroducer, 0) CARBON_PARSE_NODE_KIND_CHILD_COUNT(PackageApi, 0) CARBON_PARSE_NODE_KIND_CHILD_COUNT(PackageImpl, 0) CARBON_PARSE_NODE_KIND_CHILD_COUNT(PackageLibrary, 1) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(PackageEnd, 0) +CARBON_PARSE_NODE_KIND_BRACKET(PackageDirective, PackageIntroducer) +// A code block: +// CodeBlockStart +// (statements) +// CodeBlock +CARBON_PARSE_NODE_KIND_CHILD_COUNT(CodeBlockStart, 0) +CARBON_PARSE_NODE_KIND_BRACKET(CodeBlock, CodeBlockStart) + + +// `fn`: +// FunctionIntroducer +// DeclaredName +// (parameter list) +// (expression) +// ReturnType +// FunctionDefinitionStart +// (statements) +// FunctionDefinition +// +// Or, for a declaration, FunctionDeclaration will end it where +// FunctionDefinitionStart is for a definition. CARBON_PARSE_NODE_KIND_CHILD_COUNT(FunctionIntroducer, 0) -CARBON_PARSE_NODE_KIND_BRACKET(FunctionDeclaration, FunctionIntroducer) -CARBON_PARSE_NODE_KIND_BRACKET(FunctionDefinition, FunctionDefinitionStart) +CARBON_PARSE_NODE_KIND_CHILD_COUNT(ReturnType, 1) CARBON_PARSE_NODE_KIND_BRACKET(FunctionDefinitionStart, FunctionIntroducer) -CARBON_PARSE_NODE_KIND_BRACKET(ParameterList, ParameterListStart) +CARBON_PARSE_NODE_KIND_BRACKET(FunctionDefinition, FunctionDefinitionStart) +CARBON_PARSE_NODE_KIND_BRACKET(FunctionDeclaration, FunctionIntroducer) + +// A parameter list: +// ParamertListStart +// (expressions separated by ParameterListComma) +// ParameterList CARBON_PARSE_NODE_KIND_CHILD_COUNT(ParameterListStart, 0) CARBON_PARSE_NODE_KIND_CHILD_COUNT(ParameterListComma, 0) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(PatternBinding, 2) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(ReturnType, 1) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(VariableDeclaration, TodoFixParseNode) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(VariableInitializer, 1) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(FileEnd, 0) +CARBON_PARSE_NODE_KIND_BRACKET(ParameterList, ParameterListStart) -// Statements. -CARBON_PARSE_NODE_KIND_BRACKET(CodeBlock, CodeBlockStart) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(CodeBlockStart, 0) +// A pattern binding, such as `name: Type`: +// DeclaredName +// (type expression) +// PatternBinding +CARBON_PARSE_NODE_KIND_CHILD_COUNT(PatternBinding, 2) + +// `var`: +// VariableIntroducer +// (pattern) +// (expression) +// optional VariableInitializer +// VariableDeclaration +CARBON_PARSE_NODE_KIND_CHILD_COUNT(VariableIntroducer, 0) +CARBON_PARSE_NODE_KIND_CHILD_COUNT(VariableInitializer, 1) +CARBON_PARSE_NODE_KIND_BRACKET(VariableDeclaration, VariableIntroducer) + +// An expression statement: +// (expression) +// Statement CARBON_PARSE_NODE_KIND_CHILD_COUNT(ExpressionStatement, 1) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfStatement, TodoFixParseNode) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfStatementElse, 0) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(WhileStatement, TodoFixParseNode) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(Condition, TodoFixParseNode) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(ConditionEnd, 0) -CARBON_PARSE_NODE_KIND_BRACKET(ContinueStatement, ContinueStatementStart) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(ContinueStatementStart, 0) -CARBON_PARSE_NODE_KIND_BRACKET(BreakStatement, BreakStatementStart) + +// `break`: +// BreakStatementStart +// BreakStatement +CARBON_PARSE_NODE_KIND_CHILD_COUNT(BreakStatement, 1) CARBON_PARSE_NODE_KIND_CHILD_COUNT(BreakStatementStart, 0) + +// `continue`: +// ContinueStatementStart +// ContinueStatement +CARBON_PARSE_NODE_KIND_CHILD_COUNT(ContinueStatement, 1) +CARBON_PARSE_NODE_KIND_CHILD_COUNT(ContinueStatementStart, 0) + +// `return`: +// ReturnStatementStart +// (optional expression) +// ReturnStatement CARBON_PARSE_NODE_KIND_BRACKET(ReturnStatement, ReturnStatementStart) CARBON_PARSE_NODE_KIND_CHILD_COUNT(ReturnStatementStart, 0) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(ForStatement, TodoFixParseNode) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(ForHeader, TodoFixParseNode) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(ForHeaderEnd, 0) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(ForIn, 0) + +// `for`: +// ForHeaderStart +// (var) +// ForIn (versus a normal `var`, replaces VariableDeclaration) +// (expression) +// ForHeader +// CodeBlockStart +// (statements) +// CodeBlock +// ForStatement +CARBON_PARSE_NODE_KIND_CHILD_COUNT(ForHeaderStart, 0) +CARBON_PARSE_NODE_KIND_BRACKET(ForIn, VariableIntroducer) +CARBON_PARSE_NODE_KIND_BRACKET(ForHeader, ForHeaderStart) +CARBON_PARSE_NODE_KIND_CHILD_COUNT(ForStatement, 2) + +// `if`: +// TODO: Still thinking about structure. +// IfConditionStart +// (expression) +// IfCondition +CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfConditionStart, 0) +CARBON_PARSE_NODE_KIND_BRACKET(IfCondition, IfConditionStart) +CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfStatement, TodoFixParseNode) +CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfStatementElse, 0) + +// `while`: +// WhileConditionStart +// (expression) +// WhileCondition +// CodeBlockStart +// (statements) +// CodeBlock +// WhileStatement +CARBON_PARSE_NODE_KIND_CHILD_COUNT(WhileConditionStart, 0) +CARBON_PARSE_NODE_KIND_BRACKET(WhileCondition, WhileConditionStart) +CARBON_PARSE_NODE_KIND_CHILD_COUNT(WhileStatement, 2) // Expressions. CARBON_PARSE_NODE_KIND_CHILD_COUNT(Literal, 0) diff --git a/toolchain/parser/parser.cpp b/toolchain/parser/parser.cpp index f58eacb12c10..af9934a8548a 100644 --- a/toolchain/parser/parser.cpp +++ b/toolchain/parser/parser.cpp @@ -22,6 +22,9 @@ CARBON_DIAGNOSTIC( OperatorRequiresParentheses, Error, "Parentheses are required to disambiguate operator precedence."); +CARBON_DIAGNOSTIC(ExpectedParenAfter, Error, "Expected `(` after `{0}`.", + TokenKind); + CARBON_DIAGNOSTIC(ExpectedSemiAfterExpression, Error, "Expected `;` after expression."); @@ -111,19 +114,36 @@ auto Parser::AddNode(ParseNodeKind kind, TokenizedBuffer::Token token, } } -auto Parser::ConsumeAndAddCloseParen(TokenizedBuffer::Token open_paren, - ParseNodeKind close_kind) -> bool { - if (ConsumeAndAddLeafNodeIf(TokenKind::CloseParen(), close_kind)) { - return true; +auto Parser::ConsumeAndAddOpenParen(TokenizedBuffer::Token default_token, + ParseNodeKind start_kind) -> void { + if (auto open_paren = ConsumeIf(TokenKind::OpenParen())) { + AddLeafNode(start_kind, *open_paren, /*has_error=*/false); + } else { + emitter_->Emit(*position_, ExpectedParenAfter, + tokens_->GetKind(default_token)); + AddLeafNode(start_kind, default_token, /*has_error=*/true); } +} - // TODO: Include the location of the matching open_paren in the diagnostic. - CARBON_DIAGNOSTIC(ExpectedCloseParen, Error, "Unexpected tokens before `)`."); - emitter_->Emit(*position_, ExpectedCloseParen); +auto Parser::ConsumeAndAddCloseParen(StateStackEntry state, + ParseNodeKind close_kind) -> void { + // state.token should point at the introducer, with the paren one after the + // introducer. + auto expected_paren = *(TokenizedBuffer::TokenIterator(state.token) + 1); - SkipTo(tokens_->GetMatchedClosingToken(open_paren)); - AddLeafNode(close_kind, Consume()); - return false; + if (tokens_->GetKind(expected_paren) != TokenKind::OpenParen()) { + AddNode(close_kind, state.token, state.subtree_start, /*has_error=*/true); + } else if (auto close_token = ConsumeIf(TokenKind::CloseParen())) { + AddNode(close_kind, *close_token, state.subtree_start, state.has_error); + } else { + // TODO: Include the location of the matching open_paren in the diagnostic. + CARBON_DIAGNOSTIC(ExpectedCloseParen, Error, + "Unexpected tokens before `)`."); + emitter_->Emit(*position_, ExpectedCloseParen); + + SkipTo(tokens_->GetMatchedClosingToken(expected_paren)); + AddNode(close_kind, Consume(), state.subtree_start, /*has_error=*/true); + } } auto Parser::ConsumeAndAddLeafNodeIf(TokenKind token_kind, @@ -690,7 +710,6 @@ auto Parser::HandleDeclarationLoopState() -> void { } case TokenKind::Package(): { PushState(ParserState::Package()); - ++position_; break; } case TokenKind::Semi(): { @@ -698,7 +717,7 @@ auto Parser::HandleDeclarationLoopState() -> void { break; } case TokenKind::Var(): { - PushState(ParserState::VarAsRequireSemicolon()); + PushState(ParserState::VarAsSemicolon()); break; } case TokenKind::Interface(): { @@ -1095,12 +1114,13 @@ auto Parser::HandleFunctionDefinitionFinishState() -> void { auto Parser::HandlePackageState() -> void { auto state = PopState(); + AddLeafNode(ParseNodeKind::PackageIntroducer(), Consume()); + auto exit_on_parse_error = [&]() { - if (auto semi_token = SkipPastLikelyEnd(state.token)) { - AddLeafNode(ParseNodeKind::PackageEnd(), *semi_token); - } - return AddNode(ParseNodeKind::PackageDirective(), state.token, - state.subtree_start, /*has_error=*/true); + auto semi_token = SkipPastLikelyEnd(state.token); + return AddNode(ParseNodeKind::PackageDirective(), + semi_token ? *semi_token : state.token, state.subtree_start, + /*has_error=*/true); }; if (!ConsumeAndAddLeafNodeIf(TokenKind::Identifier(), @@ -1158,8 +1178,7 @@ auto Parser::HandlePackageState() -> void { } } - if (!ConsumeAndAddLeafNodeIf(TokenKind::Semi(), - ParseNodeKind::PackageEnd())) { + if (!PositionIs(TokenKind::Semi())) { CARBON_DIAGNOSTIC(ExpectedSemiToEndPackageDirective, Error, "Expected `;` to end package directive."); emitter_->Emit(*position_, ExpectedSemiToEndPackageDirective); @@ -1167,46 +1186,41 @@ auto Parser::HandlePackageState() -> void { return; } - AddNode(ParseNodeKind::PackageDirective(), state.token, state.subtree_start, + AddNode(ParseNodeKind::PackageDirective(), Consume(), state.subtree_start, /*has_error=*/false); } -auto Parser::HandleParenConditionState() -> void { +auto Parser::HandleParenCondition(ParseNodeKind start_kind, + ParserState finish_state) -> void { auto state = PopState(); - auto open_paren = ConsumeIf(TokenKind::OpenParen()); - if (open_paren) { - state.token = *open_paren; - } else { - CARBON_DIAGNOSTIC(ExpectedParenAfter, Error, "Expected `(` after `{0}`.", - TokenKind); - emitter_->Emit(*position_, ExpectedParenAfter, - tokens_->GetKind(state.token)); - } + ConsumeAndAddOpenParen(state.token, start_kind); - // TODO: This should be adding a ConditionStart here instead of ConditionEnd - // later, so this does state modification instead of a simpler push. - state.state = ParserState::ParenConditionFinish(); + state.state = finish_state; PushState(state); PushState(ParserState::Expression()); } -auto Parser::HandleParenConditionFinishState() -> void { +auto Parser::HandleParenConditionAsIfState() -> void { + HandleParenCondition(ParseNodeKind::IfConditionStart(), + ParserState::ParenConditionFinishAsIf()); +} + +auto Parser::HandleParenConditionAsWhileState() -> void { + HandleParenCondition(ParseNodeKind::WhileConditionStart(), + ParserState::ParenConditionFinishAsWhile()); +} + +auto Parser::HandleParenConditionFinishAsIfState() -> void { auto state = PopState(); - if (tokens_->GetKind(state.token) != TokenKind::OpenParen()) { - // Don't expect a matching closing paren if there wasn't an opening paren. - // TODO: Should probably push nodes on this state in order to have the - // condition wrapped, but it wasn't before, so not doing it for consistency. - ReturnErrorOnState(); - return; - } + ConsumeAndAddCloseParen(state, ParseNodeKind::IfCondition()); +} - bool close_paren = - ConsumeAndAddCloseParen(state.token, ParseNodeKind::ConditionEnd()); +auto Parser::HandleParenConditionFinishAsWhileState() -> void { + auto state = PopState(); - return AddNode(ParseNodeKind::Condition(), state.token, state.subtree_start, - /*has_error=*/state.has_error || !close_paren); + ConsumeAndAddCloseParen(state, ParseNodeKind::WhileCondition()); } auto Parser::HandleParenExpressionState() -> void { @@ -1357,12 +1371,9 @@ auto Parser::HandleStatementState() -> void { break; } case TokenKind::For(): { - // Process the header as a child of the for so that we can get consistent - // starts. - // TODO: When reorganizing components, we can probably make this flatter. PushState(ParserState::StatementForFinish()); - ++position_; PushState(ParserState::StatementForHeader()); + ++position_; break; } case TokenKind::If(): { @@ -1374,7 +1385,7 @@ auto Parser::HandleStatementState() -> void { break; } case TokenKind::Var(): { - PushState(ParserState::VarAsRequireSemicolon()); + PushState(ParserState::VarAsSemicolon()); break; } case TokenKind::While(): { @@ -1400,28 +1411,13 @@ auto Parser::HandleStatementContinueFinishState() -> void { auto Parser::HandleStatementForHeaderState() -> void { auto state = PopState(); - auto open_paren = ConsumeIf(TokenKind::OpenParen()); - if (!open_paren) { - CARBON_DIAGNOSTIC(ExpectedParenAfter, Error, - "Expected `(` after `{0}`. Recovering from missing `(` " - "not implemented yet!", - TokenKind); - emitter_->Emit(*position_, ExpectedParenAfter, TokenKind::For()); - // TODO: A proper recovery strategy is needed here. For now, I assume - // that all brackets are properly balanced (i.e. each open bracket has a - // closing one). - // This is temporary until we come to a conclusion regarding the - // recovery tokens strategy. - ReturnErrorOnState(); - PushState(ParserState::CodeBlock()); - return; - } + ConsumeAndAddOpenParen(state.token, ParseNodeKind::ForHeaderStart()); state.state = ParserState::StatementForHeaderIn(); if (PositionIs(TokenKind::Var())) { PushState(state); - PushState(ParserState::VarAsNoSemicolon()); + PushState(ParserState::VarAsFor()); } else { CARBON_DIAGNOSTIC(ExpectedVariableDeclaration, Error, "Expected `var` declaration."); @@ -1429,6 +1425,7 @@ auto Parser::HandleStatementForHeaderState() -> void { if (auto next_in = FindNextOf({TokenKind::In()})) { SkipTo(*next_in); + ++position_; } state.has_error = true; PushState(state); @@ -1439,24 +1436,6 @@ auto Parser::HandleStatementForHeaderInState() -> void { auto state = PopState(); state.state = ParserState::StatementForHeaderFinish(); - - if (!ConsumeAndAddLeafNodeIf(TokenKind::In(), ParseNodeKind::ForIn())) { - if (auto colon = ConsumeIf(TokenKind::Colon())) { - CARBON_DIAGNOSTIC(ExpectedIn, Error, "`:` should be replaced by `in`."); - emitter_->Emit(*colon, ExpectedIn); - AddLeafNode(ParseNodeKind::ForIn(), *colon, /*has_error=*/true); - } else { - CARBON_DIAGNOSTIC(ExpectedIn, Error, - "Expected `in` after loop `var` declaration."); - emitter_->Emit(*position_, ExpectedIn); - SkipTo(tokens_->GetMatchedClosingToken(state.token)); - - state.has_error = true; - PushState(state); - return; - } - } - PushState(state); PushState(ParserState::Expression()); } @@ -1464,12 +1443,7 @@ auto Parser::HandleStatementForHeaderInState() -> void { auto Parser::HandleStatementForHeaderFinishState() -> void { auto state = PopState(); - if (!ConsumeAndAddCloseParen(state.token, ParseNodeKind::ForHeaderEnd())) { - state.has_error = true; - } - - AddNode(ParseNodeKind::ForHeader(), state.token, state.subtree_start, - state.has_error); + ConsumeAndAddCloseParen(state, ParseNodeKind::ForHeader()); PushState(ParserState::CodeBlock()); } @@ -1485,7 +1459,7 @@ auto Parser::HandleStatementIfState() -> void { PopAndDiscardState(); PushState(ParserState::StatementIfConditionFinish()); - PushState(ParserState::ParenCondition()); + PushState(ParserState::ParenConditionAsIf()); ++position_; } @@ -1572,7 +1546,7 @@ auto Parser::HandleStatementWhileState() -> void { PopAndDiscardState(); PushState(ParserState::StatementWhileConditionFinish()); - PushState(ParserState::ParenCondition()); + PushState(ParserState::ParenConditionAsWhile()); ++position_; } @@ -1591,22 +1565,25 @@ auto Parser::HandleStatementWhileBlockFinishState() -> void { state.has_error); } -auto Parser::HandleVar(bool require_semicolon) -> void { +auto Parser::HandleVar(ParserState finish_state) -> void { PopAndDiscardState(); - PushState(require_semicolon ? ParserState::VarFinishAsRequireSemicolon() - : ParserState::VarFinishAsNoSemicolon()); + // These will start at the `var`. + PushState(finish_state); PushState(ParserState::VarAfterPattern()); - ++position_; + + AddLeafNode(ParseNodeKind::VariableIntroducer(), Consume()); + + // This will start at the pattern. PushState(ParserState::PatternAsVariable()); } -auto Parser::HandleVarAsRequireSemicolonState() -> void { - HandleVar(/*require_semicolon=*/true); +auto Parser::HandleVarAsSemicolonState() -> void { + HandleVar(ParserState::VarFinishAsSemicolon()); } -auto Parser::HandleVarAsNoSemicolonState() -> void { - HandleVar(/*require_semicolon=*/false); +auto Parser::HandleVarAsForState() -> void { + HandleVar(ParserState::VarFinishAsFor()); } auto Parser::HandleVarAfterPatternState() -> void { @@ -1634,33 +1611,43 @@ auto Parser::HandleVarAfterInitializerState() -> void { state.subtree_start, state.has_error); } -auto Parser::HandleVarFinish(bool require_semicolon) -> void { +auto Parser::HandleVarFinishAsSemicolonState() -> void { auto state = PopState(); - if (require_semicolon) { - auto semi = ConsumeAndAddLeafNodeIf(TokenKind::Semi(), - ParseNodeKind::DeclarationEnd()); - if (!semi) { - emitter_->Emit(*position_, ExpectedSemiAfterExpression); - if (auto semi_token = SkipPastLikelyEnd(state.token)) { - AddLeafNode(ParseNodeKind::DeclarationEnd(), *semi_token, - /*has_error=*/true); - } else { - state.has_error = true; - } + auto end_token = state.token; + if (PositionIs(TokenKind::Semi())) { + end_token = Consume(); + } else { + emitter_->Emit(*position_, ExpectedSemiAfterExpression); + state.has_error = true; + if (auto semi_token = SkipPastLikelyEnd(state.token)) { + end_token = *semi_token; } } - - return AddNode(ParseNodeKind::VariableDeclaration(), state.token, - state.subtree_start, state.has_error); + AddNode(ParseNodeKind::VariableDeclaration(), end_token, state.subtree_start, + state.has_error); } -auto Parser::HandleVarFinishAsRequireSemicolonState() -> void { - HandleVarFinish(/*require_semicolon=*/true); -} +auto Parser::HandleVarFinishAsForState() -> void { + auto state = PopState(); -auto Parser::HandleVarFinishAsNoSemicolonState() -> void { - HandleVarFinish(/*require_semicolon=*/false); + auto end_token = state.token; + if (PositionIs(TokenKind::In())) { + end_token = Consume(); + } else if (PositionIs(TokenKind::Colon())) { + CARBON_DIAGNOSTIC(ExpectedIn, Error, "`:` should be replaced by `in`."); + emitter_->Emit(*position_, ExpectedIn); + state.has_error = true; + end_token = Consume(); + } else { + CARBON_DIAGNOSTIC(ExpectedIn, Error, + "Expected `in` after loop `var` declaration."); + emitter_->Emit(*position_, ExpectedIn); + state.has_error = true; + } + + AddNode(ParseNodeKind::ForIn(), end_token, state.subtree_start, + state.has_error); } auto Parser::HandleInterfaceIntroducerState() -> void { diff --git a/toolchain/parser/parser.h b/toolchain/parser/parser.h index 058311fe230c..fb06be8696fe 100644 --- a/toolchain/parser/parser.h +++ b/toolchain/parser/parser.h @@ -35,7 +35,13 @@ class Parser { // Possible operator fixities for errors. enum class OperatorFixity { Prefix, Infix, Postfix }; - // Supported kinds of patterns for HandlePattern. + // Possible return values for FindListToken. + enum class ListTokenKind { Comma, Close, CommaClose }; + + // Supported kinds for HandleBraceExpression. + enum class BraceExpressionKind { Unknown, Value, Type }; + + // Supported kinds for HandlePattern. enum class PatternKind { Parameter, Variable }; // Helper class for tracing state_stack_ on crashes. @@ -85,16 +91,6 @@ class Parser { static_assert(sizeof(StateStackEntry) == 12, "StateStackEntry has unexpected size!"); - // Possible return values for FindListToken. - enum class ListTokenKind { - Comma, - Close, - CommaClose, - }; - - // The kind of brace expression being evaluated. - enum class BraceExpressionKind { Unknown, Value, Type }; - Parser(ParseTree& tree, TokenizedBuffer& tokens, TokenDiagnosticEmitter& emitter); @@ -111,11 +107,17 @@ class Parser { // Returns the current position and moves past it. auto Consume() -> TokenizedBuffer::Token { return *(position_++); } + // Parses an open paren token, possibly diagnosing if necessary. Creates a + // leaf parse node of the specified start kind. The default_token is used when + // there's no open paren. + auto ConsumeAndAddOpenParen(TokenizedBuffer::Token default_token, + ParseNodeKind start_kind) -> void; + // Parses a close paren token corresponding to the given open paren token, // possibly skipping forward and diagnosing if necessary. Creates a parse node - // of the specified kind if successful. - auto ConsumeAndAddCloseParen(TokenizedBuffer::Token open_paren, - ParseNodeKind close_kind) -> bool; + // of the specified close kind. + auto ConsumeAndAddCloseParen(StateStackEntry state, ParseNodeKind close_kind) + -> void; // Composes `ConsumeIf` and `AddLeafNode`, returning false when ConsumeIf // fails. @@ -260,7 +262,11 @@ class Parser { auto HandleFunctionError(StateStackEntry state, bool skip_past_likely_end) -> void; - // Handles ParenExpressionParameterFinish(AsUnknown|AsTuple). + // Handles ParenConditionAs(If|While) + auto HandleParenCondition(ParseNodeKind start_kind, ParserState finish_state) + -> void; + + // Handles ParenExpressionParameterFinishAs(Unknown|Tuple). auto HandleParenExpressionParameterFinish(bool as_tuple) -> void; // Handles PatternAs(FunctionParameter|Variable). @@ -269,11 +275,8 @@ class Parser { // Handles the `;` after a keyword statement. auto HandleStatementKeywordFinish(ParseNodeKind node_kind) -> void; - // Handles VarAs(RequireSemicolon|NoSemicolon). - auto HandleVar(bool require_semicolon) -> void; - - // Handles VarFinishAs(RequireSemicolon|NoSemicolon). - auto HandleVarFinish(bool require_semicolon) -> void; + // Handles VarAs(Semicolon|For). + auto HandleVar(ParserState finish_state) -> void; // `clang-format` has a bug with spacing around `->` returns in macros. See // https://bugs.llvm.org/show_bug.cgi?id=48320 for details. diff --git a/toolchain/parser/parser_state.def b/toolchain/parser/parser_state.def index c302d5f3ced9..f1e9941cc639 100644 --- a/toolchain/parser/parser_state.def +++ b/toolchain/parser/parser_state.def @@ -314,14 +314,16 @@ CARBON_PARSER_STATE(Package) // // Always: // 1. Expression -// 2. ParenConditionFinish -CARBON_PARSER_STATE(ParenCondition) +// 2. ParenConditionAs(If|While)Finish +CARBON_PARSER_STATE(ParenConditionAsIf) +CARBON_PARSER_STATE(ParenConditionAsWhile) // Finishes the processing of a `(condition)` after the expression. // // Always: // (state done) -CARBON_PARSER_STATE(ParenConditionFinish) +CARBON_PARSER_STATE(ParenConditionFinishAsIf) +CARBON_PARSER_STATE(ParenConditionFinishAsWhile) // Handles the `(` of a parenthesized expression. // @@ -391,7 +393,7 @@ CARBON_PARSER_STATE(PatternFinish) // If `Return`: // 1. StatementReturn // If `Var`: -// 1. VarAsRequireSemicolon +// 1. VarAsSemicolon // If `While`: // 1. StatementWhile // Else: @@ -417,7 +419,7 @@ CARBON_PARSER_STATE(StatementContinueFinish) // If no `OpenParen`: // 1. CodeBlock // If `Var`: -// 1. VarAsNoSemicolon +// 1. VarAsFor // 2. StatementForHeaderIn // Else: // 1. StatementForHeaderIn @@ -448,7 +450,7 @@ CARBON_PARSER_STATE(StatementForFinish) // Handles `if` processing at the start. // // Always: -// 1. ParenCondition +// 1. ParenConditionAsIf // 2. StatementIfConditionFinish CARBON_PARSER_STATE(StatementIf) @@ -506,7 +508,7 @@ CARBON_PARSER_STATE(StatementScopeLoop) // Handles `while` processing. // // Always: -// 1. ParenCondition +// 1. ParenConditionAsWhile // 2. StatementWhileConditionFinish CARBON_PARSER_STATE(StatementWhile) @@ -528,9 +530,9 @@ CARBON_PARSER_STATE(StatementWhileBlockFinish) // Always: // 1. PatternAsVariable // 2. VarAfterPattern -// 3. VarFinishAs(RequireSemicolon|NoSemicolon) -CARBON_PARSER_STATE(VarAsRequireSemicolon) -CARBON_PARSER_STATE(VarAsNoSemicolon) +// 3. VarFinishAs(Semicolon|For) +CARBON_PARSER_STATE(VarAsSemicolon) +CARBON_PARSER_STATE(VarAsFor) // Handles `var` after the pattern, either followed by an initializer or the // semicolon. @@ -552,7 +554,7 @@ CARBON_PARSER_STATE(VarAfterInitializer) // // Always: // (state done) -CARBON_PARSER_STATE(VarFinishAsRequireSemicolon) -CARBON_PARSER_STATE(VarFinishAsNoSemicolon) +CARBON_PARSER_STATE(VarFinishAsSemicolon) +CARBON_PARSER_STATE(VarFinishAsFor) #undef CARBON_PARSER_STATE diff --git a/toolchain/parser/testdata/basics/fail_paren_match_regression.carbon b/toolchain/parser/testdata/basics/fail_paren_match_regression.carbon index db8b7d26ae8c..5181e1e12c93 100644 --- a/toolchain/parser/testdata/basics/fail_paren_match_regression.carbon +++ b/toolchain/parser/testdata/basics/fail_paren_match_regression.carbon @@ -5,11 +5,12 @@ // AUTOUPDATE // RUN: %{not} %{carbon-run-parser} // CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'foo'}, // CHECK:STDOUT: {kind: 'ParenExpressionEnd', text: ')'}, // CHECK:STDOUT: {kind: 'ParenExpression', text: '(', has_error: yes, subtree_size: 3}, // CHECK:STDOUT: {kind: 'VariableInitializer', text: '=', subtree_size: 4}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', has_error: yes, subtree_size: 5}, +// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', has_error: yes, subtree_size: 6}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parser/testdata/basics/package.carbon b/toolchain/parser/testdata/basics/package.carbon index 3359d09a75e9..7a0d52c80028 100644 --- a/toolchain/parser/testdata/basics/package.carbon +++ b/toolchain/parser/testdata/basics/package.carbon @@ -5,26 +5,26 @@ // AUTOUPDATE // RUN: %{carbon-run-parser} // CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'PackageApi', text: 'api'}, -// CHECK:STDOUT: {kind: 'PackageEnd', text: ';'}, -// CHECK:STDOUT: {kind: 'PackageDirective', text: 'package', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'PackageImpl', text: 'impl'}, -// CHECK:STDOUT: {kind: 'PackageEnd', text: ';'}, -// CHECK:STDOUT: {kind: 'PackageDirective', text: 'package', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'Literal', text: '"Shapes"'}, // CHECK:STDOUT: {kind: 'PackageLibrary', text: 'library', subtree_size: 2}, // CHECK:STDOUT: {kind: 'PackageApi', text: 'api'}, -// CHECK:STDOUT: {kind: 'PackageEnd', text: ';'}, -// CHECK:STDOUT: {kind: 'PackageDirective', text: 'package', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'PackageIntroducer', text: 'package'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'Geometry'}, // CHECK:STDOUT: {kind: 'Literal', text: '"Shapes"'}, // CHECK:STDOUT: {kind: 'PackageLibrary', text: 'library', subtree_size: 2}, // CHECK:STDOUT: {kind: 'PackageImpl', text: 'impl'}, -// CHECK:STDOUT: {kind: 'PackageEnd', text: ';'}, -// CHECK:STDOUT: {kind: 'PackageDirective', text: 'package', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'PackageDirective', text: ';', subtree_size: 6}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parser/testdata/basics/structs.carbon b/toolchain/parser/testdata/basics/structs.carbon index e852b39f2c5c..b4a9b96fe07c 100644 --- a/toolchain/parser/testdata/basics/structs.carbon +++ b/toolchain/parser/testdata/basics/structs.carbon @@ -5,6 +5,7 @@ // AUTOUPDATE // RUN: %{carbon-run-parser} // CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'x'}, // CHECK:STDOUT: {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'}, // CHECK:STDOUT: {kind: 'DesignatedName', text: 'a'}, @@ -30,8 +31,8 @@ // CHECK:STDOUT: {kind: 'StructFieldValue', text: '=', subtree_size: 4}, // CHECK:STDOUT: {kind: 'StructLiteral', text: '}', subtree_size: 11}, // CHECK:STDOUT: {kind: 'VariableInitializer', text: '=', subtree_size: 12}, -// CHECK:STDOUT: {kind: 'DeclarationEnd', text: ';'}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', subtree_size: 27}, +// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 27}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'y'}, // CHECK:STDOUT: {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'}, // CHECK:STDOUT: {kind: 'StructLiteral', text: '}', subtree_size: 2}, @@ -39,8 +40,8 @@ // CHECK:STDOUT: {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'}, // CHECK:STDOUT: {kind: 'StructLiteral', text: '}', subtree_size: 2}, // CHECK:STDOUT: {kind: 'VariableInitializer', text: '=', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'DeclarationEnd', text: ';'}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'z'}, // CHECK:STDOUT: {kind: 'StructLiteralOrStructTypeLiteralStart', text: '{'}, // CHECK:STDOUT: {kind: 'DesignatedName', text: 'n'}, @@ -58,8 +59,7 @@ // CHECK:STDOUT: {kind: 'StructComma', text: ','}, // CHECK:STDOUT: {kind: 'StructLiteral', text: '}', subtree_size: 7}, // CHECK:STDOUT: {kind: 'VariableInitializer', text: '=', subtree_size: 8}, -// CHECK:STDOUT: {kind: 'DeclarationEnd', text: ';'}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', subtree_size: 19}, +// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 19}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parser/testdata/basics/tuples.carbon b/toolchain/parser/testdata/basics/tuples.carbon index 71a3dcd5421d..ec123e4a18a8 100644 --- a/toolchain/parser/testdata/basics/tuples.carbon +++ b/toolchain/parser/testdata/basics/tuples.carbon @@ -5,6 +5,7 @@ // AUTOUPDATE // RUN: %{carbon-run-parser} // CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'x'}, // CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, // CHECK:STDOUT: {kind: 'TupleLiteralComma', text: ','}, @@ -18,8 +19,8 @@ // CHECK:STDOUT: {kind: 'TupleLiteralEnd', text: ')'}, // CHECK:STDOUT: {kind: 'TupleLiteral', text: '(', subtree_size: 5}, // CHECK:STDOUT: {kind: 'VariableInitializer', text: '=', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'DeclarationEnd', text: ';'}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', subtree_size: 15}, +// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 15}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'y'}, // CHECK:STDOUT: {kind: 'TupleLiteralEnd', text: ')'}, // CHECK:STDOUT: {kind: 'TupleLiteral', text: '(', subtree_size: 2}, @@ -32,8 +33,7 @@ // CHECK:STDOUT: {kind: 'TupleLiteralEnd', text: ')'}, // CHECK:STDOUT: {kind: 'TupleLiteral', text: '(', subtree_size: 10}, // CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 12}, -// CHECK:STDOUT: {kind: 'DeclarationEnd', text: ';'}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', subtree_size: 14}, +// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 14}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parser/testdata/basics/var.carbon b/toolchain/parser/testdata/basics/var.carbon index 74c8ae3f1e00..f36318a7453e 100644 --- a/toolchain/parser/testdata/basics/var.carbon +++ b/toolchain/parser/testdata/basics/var.carbon @@ -5,30 +5,30 @@ // AUTOUPDATE // RUN: %{carbon-run-parser} // CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'v'}, // CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, // CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, // CHECK:STDOUT: {kind: 'Literal', text: '0'}, // CHECK:STDOUT: {kind: 'VariableInitializer', text: '=', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'DeclarationEnd', text: ';'}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'w'}, // CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, // CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'DeclarationEnd', text: ';'}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 5}, // CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'F'}, // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 's'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'String'}, // CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, // CHECK:STDOUT: {kind: 'Literal', text: '"hello"'}, // CHECK:STDOUT: {kind: 'VariableInitializer', text: '=', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'DeclarationEnd', text: ';'}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 7}, // CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 13}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parser/testdata/for/fail_colon_instead_of_in.carbon b/toolchain/parser/testdata/for/fail_colon_instead_of_in.carbon index b0f15a512976..19252a5acfeb 100644 --- a/toolchain/parser/testdata/for/fail_colon_instead_of_in.carbon +++ b/toolchain/parser/testdata/for/fail_colon_instead_of_in.carbon @@ -10,14 +10,14 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'ForHeaderStart', text: '('}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'x'}, // CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, // CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', subtree_size: 4}, -// CHECK:STDOUT: {kind: 'ForIn', text: ':', has_error: yes}, +// CHECK:STDOUT: {kind: 'ForIn', text: ':', has_error: yes, subtree_size: 5}, // CHECK:STDOUT: {kind: 'NameReference', text: 'y'}, -// CHECK:STDOUT: {kind: 'ForHeaderEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'ForHeader', text: '(', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'ForHeader', text: ')', subtree_size: 8}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'Print'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'x'}, diff --git a/toolchain/parser/testdata/for/fail_missing_in.carbon b/toolchain/parser/testdata/for/fail_missing_in.carbon index eb5081cdb553..30eb86ebbefd 100644 --- a/toolchain/parser/testdata/for/fail_missing_in.carbon +++ b/toolchain/parser/testdata/for/fail_missing_in.carbon @@ -10,12 +10,14 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'ForHeaderStart', text: '('}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'x'}, // CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, // CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', subtree_size: 4}, -// CHECK:STDOUT: {kind: 'ForHeaderEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'ForHeader', text: '(', has_error: yes, subtree_size: 6}, +// CHECK:STDOUT: {kind: 'ForIn', text: 'var', has_error: yes, subtree_size: 5}, +// CHECK:STDOUT: {kind: 'NameReference', text: 'y'}, +// CHECK:STDOUT: {kind: 'ForHeader', text: ')', subtree_size: 8}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'Print'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'x'}, @@ -23,8 +25,8 @@ // CHECK:STDOUT: {kind: 'CallExpression', text: '(', subtree_size: 4}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 5}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'ForStatement', text: 'for', subtree_size: 14}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 20}, +// CHECK:STDOUT: {kind: 'ForStatement', text: 'for', subtree_size: 16}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 22}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parser/testdata/for/fail_missing_var.carbon b/toolchain/parser/testdata/for/fail_missing_var.carbon index 7fcf76aae532..d1903b2ec2d5 100644 --- a/toolchain/parser/testdata/for/fail_missing_var.carbon +++ b/toolchain/parser/testdata/for/fail_missing_var.carbon @@ -10,10 +10,9 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'ForIn', text: 'in'}, +// CHECK:STDOUT: {kind: 'ForHeaderStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'y'}, -// CHECK:STDOUT: {kind: 'ForHeaderEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'ForHeader', text: '(', has_error: yes, subtree_size: 4}, +// CHECK:STDOUT: {kind: 'ForHeader', text: ')', has_error: yes, subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'Print'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'x'}, @@ -21,8 +20,8 @@ // CHECK:STDOUT: {kind: 'CallExpression', text: '(', subtree_size: 4}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 5}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 7}, -// CHECK:STDOUT: {kind: 'ForStatement', text: 'for', subtree_size: 12}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 18}, +// CHECK:STDOUT: {kind: 'ForStatement', text: 'for', subtree_size: 11}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 17}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parser/testdata/for/nested.carbon b/toolchain/parser/testdata/for/nested.carbon index c299853689eb..34b4fd2d4dd8 100644 --- a/toolchain/parser/testdata/for/nested.carbon +++ b/toolchain/parser/testdata/for/nested.carbon @@ -10,23 +10,23 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'ForHeaderStart', text: '('}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'y'}, // CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, // CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', subtree_size: 4}, -// CHECK:STDOUT: {kind: 'ForIn', text: 'in'}, +// CHECK:STDOUT: {kind: 'ForIn', text: 'in', subtree_size: 5}, // CHECK:STDOUT: {kind: 'NameReference', text: 'x'}, -// CHECK:STDOUT: {kind: 'ForHeaderEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'ForHeader', text: '(', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'ForHeader', text: ')', subtree_size: 8}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, +// CHECK:STDOUT: {kind: 'ForHeaderStart', text: '('}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'z'}, // CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, // CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', subtree_size: 4}, -// CHECK:STDOUT: {kind: 'ForIn', text: 'in'}, +// CHECK:STDOUT: {kind: 'ForIn', text: 'in', subtree_size: 5}, // CHECK:STDOUT: {kind: 'NameReference', text: 'y'}, -// CHECK:STDOUT: {kind: 'ForHeaderEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'ForHeader', text: '(', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'ForHeader', text: ')', subtree_size: 8}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'Print'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'z'}, diff --git a/toolchain/parser/testdata/for/simple.carbon b/toolchain/parser/testdata/for/simple.carbon index 2f37dce30768..4f03fa8b01af 100644 --- a/toolchain/parser/testdata/for/simple.carbon +++ b/toolchain/parser/testdata/for/simple.carbon @@ -10,14 +10,14 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'ForHeaderStart', text: '('}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'x'}, // CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, // CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', subtree_size: 4}, -// CHECK:STDOUT: {kind: 'ForIn', text: 'in'}, +// CHECK:STDOUT: {kind: 'ForIn', text: 'in', subtree_size: 5}, // CHECK:STDOUT: {kind: 'NameReference', text: 'y'}, -// CHECK:STDOUT: {kind: 'ForHeaderEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'ForHeader', text: '(', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'ForHeader', text: ')', subtree_size: 8}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'Print'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'x'}, diff --git a/toolchain/parser/testdata/if/basic.carbon b/toolchain/parser/testdata/if/basic.carbon index 539b42736f68..840e7fd663f7 100644 --- a/toolchain/parser/testdata/if/basic.carbon +++ b/toolchain/parser/testdata/if/basic.carbon @@ -10,17 +10,17 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'a'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'b'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'c'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'd'}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 2}, diff --git a/toolchain/parser/testdata/if/else.carbon b/toolchain/parser/testdata/if/else.carbon index 2ad67b063a24..4025e02c17e0 100644 --- a/toolchain/parser/testdata/if/else.carbon +++ b/toolchain/parser/testdata/if/else.carbon @@ -10,13 +10,13 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'a'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'b'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'c'}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 2}, @@ -34,17 +34,17 @@ // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 2}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 4}, // CHECK:STDOUT: {kind: 'IfStatement', text: 'if', subtree_size: 24}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'x'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'f'}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 2}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 4}, // CHECK:STDOUT: {kind: 'IfStatementElse', text: 'else'}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'x'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'g'}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 2}, diff --git a/toolchain/parser/testdata/if/fail_else_unbraced.carbon b/toolchain/parser/testdata/if/fail_else_unbraced.carbon index 7e454840158b..412d75a46047 100644 --- a/toolchain/parser/testdata/if/fail_else_unbraced.carbon +++ b/toolchain/parser/testdata/if/fail_else_unbraced.carbon @@ -10,13 +10,13 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'a'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: 'if', has_error: yes}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'b'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: 'c', has_error: yes}, // CHECK:STDOUT: {kind: 'NameReference', text: 'c'}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 2}, @@ -34,17 +34,17 @@ // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 2}, // CHECK:STDOUT: {kind: 'CodeBlock', text: 'e', has_error: yes, subtree_size: 4}, // CHECK:STDOUT: {kind: 'IfStatement', text: 'if', subtree_size: 24}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'x'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'f'}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 2}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 4}, // CHECK:STDOUT: {kind: 'IfStatementElse', text: 'else'}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'x'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'g'}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 2}, diff --git a/toolchain/parser/testdata/if/fail_errors.carbon b/toolchain/parser/testdata/if/fail_errors.carbon index 5a85edf34b43..4193824bc295 100644 --- a/toolchain/parser/testdata/if/fail_errors.carbon +++ b/toolchain/parser/testdata/if/fail_errors.carbon @@ -10,28 +10,30 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'NameReference', text: 'a'}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: 'if', has_error: yes}, +// CHECK:STDOUT: {kind: 'NameReference', text: 'a'}, +// CHECK:STDOUT: {kind: 'IfCondition', text: 'if', has_error: yes, subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'IfStatement', text: 'if', has_error: yes, subtree_size: 4}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IfStatement', text: 'if', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', has_error: yes, subtree_size: 2}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 2}, // CHECK:STDOUT: {kind: 'IfStatement', text: 'if', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'b'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', has_error: yes, subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 2}, // CHECK:STDOUT: {kind: 'IfStatement', text: 'if', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'd'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '}', has_error: yes}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', has_error: yes, subtree_size: 2}, // CHECK:STDOUT: {kind: 'IfStatement', text: 'if', subtree_size: 6}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 27}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 29}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parser/testdata/if/fail_unbraced.carbon b/toolchain/parser/testdata/if/fail_unbraced.carbon index 1775d0fdeefc..97dee8b9e5da 100644 --- a/toolchain/parser/testdata/if/fail_unbraced.carbon +++ b/toolchain/parser/testdata/if/fail_unbraced.carbon @@ -11,17 +11,17 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'a'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: 'if', has_error: yes}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'b'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: 'if', has_error: yes}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'c'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: 'd', has_error: yes}, // CHECK:STDOUT: {kind: 'NameReference', text: 'd'}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 2}, diff --git a/toolchain/parser/testdata/operators/fixity_in_var.carbon b/toolchain/parser/testdata/operators/fixity_in_var.carbon index cfdf8427575d..746621f8280c 100644 --- a/toolchain/parser/testdata/operators/fixity_in_var.carbon +++ b/toolchain/parser/testdata/operators/fixity_in_var.carbon @@ -10,22 +10,22 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'q'}, // CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, // CHECK:STDOUT: {kind: 'PostfixOperator', text: '*', subtree_size: 2}, // CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 4}, // CHECK:STDOUT: {kind: 'NameReference', text: 'p'}, // CHECK:STDOUT: {kind: 'VariableInitializer', text: '=', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'DeclarationEnd', text: ';'}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 't'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'Type'}, // CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, // CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, // CHECK:STDOUT: {kind: 'PostfixOperator', text: '*', subtree_size: 2}, // CHECK:STDOUT: {kind: 'VariableInitializer', text: '=', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'DeclarationEnd', text: ';'}, -// CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 8}, // CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 22}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parser/testdata/while/basic.carbon b/toolchain/parser/testdata/while/basic.carbon index 235ccce4d8ff..bb0fa469106f 100644 --- a/toolchain/parser/testdata/while/basic.carbon +++ b/toolchain/parser/testdata/while/basic.carbon @@ -10,21 +10,21 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'WhileConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'a'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'WhileCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'b'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'BreakStatementStart', text: 'break'}, // CHECK:STDOUT: {kind: 'BreakStatement', text: ';', subtree_size: 2}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 4}, // CHECK:STDOUT: {kind: 'IfStatement', text: 'if', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'c'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'ContinueStatementStart', text: 'continue'}, // CHECK:STDOUT: {kind: 'ContinueStatement', text: ';', subtree_size: 2}, diff --git a/toolchain/parser/testdata/while/fail_no_semi.carbon b/toolchain/parser/testdata/while/fail_no_semi.carbon index da92c37d54ae..ea3fae0eaed5 100644 --- a/toolchain/parser/testdata/while/fail_no_semi.carbon +++ b/toolchain/parser/testdata/while/fail_no_semi.carbon @@ -10,21 +10,21 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'WhileConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'a'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'WhileCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'b'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'BreakStatementStart', text: 'break'}, // CHECK:STDOUT: {kind: 'BreakStatement', text: 'break', has_error: yes, subtree_size: 2}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 4}, // CHECK:STDOUT: {kind: 'IfStatement', text: 'if', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'IfConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'c'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IfCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, // CHECK:STDOUT: {kind: 'ContinueStatementStart', text: 'continue'}, // CHECK:STDOUT: {kind: 'ContinueStatement', text: 'continue', has_error: yes, subtree_size: 2}, diff --git a/toolchain/parser/testdata/while/fail_unbraced.carbon b/toolchain/parser/testdata/while/fail_unbraced.carbon index 696a8eaf9222..14f88f1f007e 100644 --- a/toolchain/parser/testdata/while/fail_unbraced.carbon +++ b/toolchain/parser/testdata/while/fail_unbraced.carbon @@ -11,9 +11,9 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'WhileConditionStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'a'}, -// CHECK:STDOUT: {kind: 'ConditionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'Condition', text: '(', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'WhileCondition', text: ')', subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: 'break', has_error: yes}, // CHECK:STDOUT: {kind: 'BreakStatementStart', text: 'break'}, // CHECK:STDOUT: {kind: 'BreakStatement', text: ';', subtree_size: 2},