Skip to content

Commit

Permalink
Add PushState overload to combine Parse::State change with `State…
Browse files Browse the repository at this point in the history
…StackEntry` (carbon-language#3485)

Shortens a common `PushState` pattern
  • Loading branch information
josh11b committed Dec 8, 2023
1 parent 6e65a30 commit b7d129b
Show file tree
Hide file tree
Showing 17 changed files with 47 additions and 87 deletions.
6 changes: 6 additions & 0 deletions toolchain/parse/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,12 @@ class Context {
<< "Excessive stack size: likely infinite loop";
}

// Pushes a constructed state onto the stack, with a different parse state.
auto PushState(StateStackEntry state_entry, State parse_state) -> void {
state_entry.state = parse_state;
PushState(state_entry);
}

// Propagates an error up the state stack, to the parent state.
auto ReturnErrorOnState() -> void { state_stack_.back().has_error = true; }

Expand Down
6 changes: 2 additions & 4 deletions toolchain/parse/handle_array_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ namespace Carbon::Parse {

auto HandleArrayExpr(Context& context) -> void {
auto state = context.PopState();
state.state = State::ArrayExprSemi;
context.AddLeafNode(NodeKind::ArrayExprStart,
context.ConsumeChecked(Lex::TokenKind::OpenSquareBracket),
state.has_error);
context.PushState(state);
context.PushState(state, State::ArrayExprSemi);
context.PushState(State::Expr);
}

Expand All @@ -33,8 +32,7 @@ auto HandleArrayExprSemi(Context& context) -> void {
context.AddNode(NodeKind::ArrayExprSemi, *semi, state.subtree_start,
state.has_error);
}
state.state = State::ArrayExprFinish;
context.PushState(state);
context.PushState(state, State::ArrayExprFinish);
if (!context.PositionIs(Lex::TokenKind::CloseSquareBracket)) {
context.PushState(State::Expr);
}
Expand Down
3 changes: 1 addition & 2 deletions toolchain/parse/handle_binding_pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ auto HandleBindingPattern(Context& context) -> void {
// Add a placeholder for the type.
context.AddLeafNode(NodeKind::InvalidParse, *context.position(),
/*has_error=*/true);
state.state = State::BindingPatternFinishAsRegular;
state.has_error = true;
context.PushState(state);
context.PushState(state, State::BindingPatternFinishAsRegular);
};

// The first item should be an identifier or `self`.
Expand Down
16 changes: 5 additions & 11 deletions toolchain/parse/handle_brace_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ namespace Carbon::Parse {

auto HandleBraceExpr(Context& context) -> void {
auto state = context.PopState();

state.state = State::BraceExprFinishAsUnknown;
context.PushState(state);
context.PushState(state, State::BraceExprFinishAsUnknown);

CARBON_CHECK(context.ConsumeAndAddLeafNodeIf(
Lex::TokenKind::OpenCurlyBrace,
Expand Down Expand Up @@ -39,9 +37,8 @@ static auto HandleBraceExprParamError(Context& context,
(is_value || is_unknown) ? llvm::StringLiteral("`.field = value`")
: llvm::StringLiteral(""));

state.state = param_finish_state;
state.has_error = true;
context.PushState(state);
context.PushState(state, param_finish_state);
}

// Handles BraceExprParamAs(Type|Value|Unknown).
Expand All @@ -54,8 +51,7 @@ static auto HandleBraceExprParam(Context& context, State after_designator_state,
return;
}

state.state = after_designator_state;
context.PushState(state);
context.PushState(state, after_designator_state);
context.PushState(State::PeriodAsStruct);
}

Expand Down Expand Up @@ -85,8 +81,7 @@ static auto HandleBraceExprParamAfterDesignator(Context& context,
{Lex::TokenKind::Equal, Lex::TokenKind::Colon, Lex::TokenKind::Comma});
if (!recovery_pos ||
context.tokens().GetKind(*recovery_pos) == Lex::TokenKind::Comma) {
state.state = param_finish_state;
context.PushState(state);
context.PushState(state, param_finish_state);
return;
}
context.SkipTo(*recovery_pos);
Expand Down Expand Up @@ -126,9 +121,8 @@ static auto HandleBraceExprParamAfterDesignator(Context& context,

// Struct type fields and value fields use the same grammar except
// that one has a `:` separator and the other has an `=` separator.
state.state = param_finish_state;
state.token = context.Consume();
context.PushState(state);
context.PushState(state, param_finish_state);
context.PushState(State::Expr);
}

Expand Down
4 changes: 1 addition & 3 deletions toolchain/parse/handle_call_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ namespace Carbon::Parse {

auto HandleCallExpr(Context& context) -> void {
auto state = context.PopState();

state.state = State::CallExprFinish;
context.PushState(state);
context.PushState(state, State::CallExprFinish);

context.AddNode(NodeKind::CallExprStart, context.Consume(),
state.subtree_start, state.has_error);
Expand Down
9 changes: 3 additions & 6 deletions toolchain/parse/handle_decl_name_and_params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@ static auto HandleDeclNameAndParams(Context& context, State after_name)

// TODO: Should handle designated names.
if (auto identifier = context.ConsumeIf(Lex::TokenKind::Identifier)) {
state.state = after_name;
context.PushState(state);
context.PushState(state, after_name);

if (context.PositionIs(Lex::TokenKind::Period)) {
context.AddLeafNode(NodeKind::IdentifierName, *identifier);
state.state = State::PeriodAsDecl;
context.PushState(state);
context.PushState(state, State::PeriodAsDecl);
} else {
context.AddLeafNode(NodeKind::IdentifierName, *identifier);
}
Expand Down Expand Up @@ -66,8 +64,7 @@ static auto HandleDeclNameAndParamsAfterName(Context& context, Params params)
if (context.PositionIs(Lex::TokenKind::Period)) {
// Continue designator processing.
context.PushState(state);
state.state = State::PeriodAsDecl;
context.PushState(state);
context.PushState(state, State::PeriodAsDecl);
return;
}

Expand Down
3 changes: 1 addition & 2 deletions toolchain/parse/handle_decl_scope_loop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,7 @@ static auto ApplyIntroducer(Context& context, Context::StateStackEntry state,
context.ReplacePlaceholderNode(state.subtree_start, introducer_kind,
context.Consume());
// Reuse state here to retain its `subtree_start`.
state.state = next_state;
context.PushState(state);
context.PushState(state, next_state);
}

// Handles `base` as a declaration.
Expand Down
21 changes: 7 additions & 14 deletions toolchain/parse/handle_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,26 +182,22 @@ auto HandleExprInPostfixLoop(Context& context) -> void {
switch (context.PositionKind()) {
case Lex::TokenKind::Period: {
context.PushState(state);
state.state = State::PeriodAsExpr;
context.PushState(state);
context.PushState(state, State::PeriodAsExpr);
break;
}
case Lex::TokenKind::MinusGreater: {
context.PushState(state);
state.state = State::ArrowExpr;
context.PushState(state);
context.PushState(state, State::ArrowExpr);
break;
}
case Lex::TokenKind::OpenParen: {
context.PushState(state);
state.state = State::CallExpr;
context.PushState(state);
context.PushState(state, State::CallExpr);
break;
}
case Lex::TokenKind::OpenSquareBracket: {
context.PushState(state);
state.state = State::IndexExpr;
context.PushState(state);
context.PushState(state, State::IndexExpr);
break;
}
default: {
Expand Down Expand Up @@ -276,8 +272,7 @@ auto HandleExprLoop(Context& context) -> void {
state.subtree_start, state.has_error);
}

state.state = State::ExprLoopForBinary;
context.PushState(state);
context.PushState(state, State::ExprLoopForBinary);
context.PushStateForExpr(operator_precedence);
} else {
context.AddNode(NodeKind::PostfixOperator, state.token, state.subtree_start,
Expand All @@ -292,19 +287,17 @@ auto HandleExprLoopForBinary(Context& context) -> void {

context.AddNode(NodeKind::InfixOperator, state.token, state.subtree_start,
state.has_error);
state.state = State::ExprLoop;
state.has_error = false;
context.PushState(state);
context.PushState(state, State::ExprLoop);
}

auto HandleExprLoopForPrefix(Context& context) -> void {
auto state = context.PopState();

context.AddNode(NodeKind::PrefixOperator, state.token, state.subtree_start,
state.has_error);
state.state = State::ExprLoop;
state.has_error = false;
context.PushState(state);
context.PushState(state, State::ExprLoop);
}

auto HandleIfExprFinishCondition(Context& context) -> void {
Expand Down
9 changes: 3 additions & 6 deletions toolchain/parse/handle_function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@ namespace Carbon::Parse {

auto HandleFunctionIntroducer(Context& context) -> void {
auto state = context.PopState();
state.state = State::FunctionAfterParams;
context.PushState(state);
context.PushState(state, State::FunctionAfterParams);
context.PushState(State::DeclNameAndParamsAsRequired, state.token);
}

auto HandleFunctionAfterParams(Context& context) -> void {
auto state = context.PopState();

// Regardless of whether there's a return type, we'll finish the signature.
state.state = State::FunctionSignatureFinish;
context.PushState(state);
context.PushState(state, State::FunctionSignatureFinish);

// If there is a return type, parse the expression before adding the return
// type node.
Expand Down Expand Up @@ -50,8 +48,7 @@ auto HandleFunctionSignatureFinish(Context& context) -> void {
state.subtree_start, state.has_error);
// Any error is recorded on the FunctionDefinitionStart.
state.has_error = false;
state.state = State::FunctionDefinitionFinish;
context.PushState(state);
context.PushState(state, State::FunctionDefinitionFinish);
context.PushState(State::StatementScopeLoop);
break;
}
Expand Down
3 changes: 1 addition & 2 deletions toolchain/parse/handle_index_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ namespace Carbon::Parse {

auto HandleIndexExpr(Context& context) -> void {
auto state = context.PopState();
state.state = State::IndexExprFinish;
context.PushState(state);
context.PushState(state, State::IndexExprFinish);
context.AddNode(NodeKind::IndexExprStart,
context.ConsumeChecked(Lex::TokenKind::OpenSquareBracket),
state.subtree_start, state.has_error);
Expand Down
6 changes: 2 additions & 4 deletions toolchain/parse/handle_let.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ auto HandleLet(Context& context) -> void {
auto state = context.PopState();

// These will start at the `let`.
state.state = State::LetFinish;
context.PushState(state);
state.state = State::LetAfterPattern;
context.PushState(state);
context.PushState(state, State::LetFinish);
context.PushState(state, State::LetAfterPattern);

// This will start at the pattern.
context.PushState(State::Pattern);
Expand Down
4 changes: 1 addition & 3 deletions toolchain/parse/handle_namespace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ namespace Carbon::Parse {

auto HandleNamespace(Context& context) -> void {
auto state = context.PopState();
state.state = State::NamespaceFinish;
context.PushState(state);

context.PushState(state, State::NamespaceFinish);
context.PushState(State::DeclNameAndParamsAsNone, state.token);
}

Expand Down
3 changes: 1 addition & 2 deletions toolchain/parse/handle_paren_condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ static auto HandleParenCondition(Context& context, NodeKind start_kind,
if (open_paren) {
state.token = *open_paren;
}
state.state = finish_state;
context.PushState(state);
context.PushState(state, finish_state);

if (!open_paren && context.PositionIs(Lex::TokenKind::OpenCurlyBrace)) {
// For an open curly, assume the condition was completely omitted.
Expand Down
12 changes: 4 additions & 8 deletions toolchain/parse/handle_paren_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@ auto HandleParenExpr(Context& context) -> void {
context.ConsumeChecked(Lex::TokenKind::OpenParen));

if (context.PositionIs(Lex::TokenKind::CloseParen)) {
state.state = State::TupleLiteralFinish;
context.PushState(state);
context.PushState(state, State::TupleLiteralFinish);
} else {
state.state = State::ParenExprFinish;
context.PushState(state);
context.PushState(state, State::ParenExprFinish);
context.PushState(State::ExprAfterOpenParenFinish);
context.PushState(State::Expr);
}
Expand All @@ -37,14 +35,12 @@ auto HandleExprAfterOpenParenFinish(Context& context) -> void {
auto finish_state = context.PopState();
CARBON_CHECK(finish_state.state == State::ParenExprFinish)
<< "Unexpected parent state, found: " << finish_state.state;
finish_state.state = State::TupleLiteralFinish;
context.PushState(finish_state);
context.PushState(finish_state, State::TupleLiteralFinish);

// If the comma is not immediately followed by a close paren, push handlers
// for the next tuple element.
if (list_token_kind != Context::ListTokenKind::CommaClose) {
state.state = State::TupleLiteralElementFinish;
context.PushState(state);
context.PushState(state, State::TupleLiteralElementFinish);
context.PushState(State::Expr);
}
}
Expand Down
17 changes: 5 additions & 12 deletions toolchain/parse/handle_statement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,7 @@ auto HandleStatementForHeader(Context& context) -> void {

auto HandleStatementForHeaderIn(Context& context) -> void {
auto state = context.PopState();

state.state = State::StatementForHeaderFinish;
context.PushState(state);
context.PushState(state, State::StatementForHeaderFinish);
context.PushState(State::Expr);
}

Expand Down Expand Up @@ -151,9 +149,7 @@ auto HandleStatementIf(Context& context) -> void {

auto HandleStatementIfConditionFinish(Context& context) -> void {
auto state = context.PopState();

state.state = State::StatementIfThenBlockFinish;
context.PushState(state);
context.PushState(state, State::StatementIfThenBlockFinish);
context.PushState(State::CodeBlock);
}

Expand All @@ -162,8 +158,7 @@ auto HandleStatementIfThenBlockFinish(Context& context) -> void {

if (context.ConsumeAndAddLeafNodeIf(Lex::TokenKind::Else,
NodeKind::IfStatementElse)) {
state.state = State::StatementIfElseBlockFinish;
context.PushState(state);
context.PushState(state, State::StatementIfElseBlockFinish);
// `else if` is permitted as a special case.
context.PushState(context.PositionIs(Lex::TokenKind::If)
? State::StatementIf
Expand All @@ -182,8 +177,7 @@ auto HandleStatementIfElseBlockFinish(Context& context) -> void {

auto HandleStatementReturn(Context& context) -> void {
auto state = context.PopState();
state.state = State::StatementReturnFinish;
context.PushState(state);
context.PushState(state, State::StatementReturnFinish);

context.AddLeafNode(NodeKind::ReturnStatementStart, context.Consume());

Expand Down Expand Up @@ -227,8 +221,7 @@ auto HandleStatementWhile(Context& context) -> void {
auto HandleStatementWhileConditionFinish(Context& context) -> void {
auto state = context.PopState();

state.state = State::StatementWhileBlockFinish;
context.PushState(state);
context.PushState(state, State::StatementWhileBlockFinish);
context.PushState(State::CodeBlock);
}

Expand Down
6 changes: 2 additions & 4 deletions toolchain/parse/handle_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ namespace Carbon::Parse {
static auto HandleTypeAfterIntroducer(Context& context,
State after_params_state) -> void {
auto state = context.PopState();
state.state = after_params_state;
context.PushState(state);
context.PushState(state, after_params_state);
context.PushState(State::DeclNameAndParamsAsOptional, state.token);
}

Expand Down Expand Up @@ -53,8 +52,7 @@ static auto HandleTypeAfterParams(Context& context, NodeKind decl_kind,
return;
}

state.state = definition_finish_state;
context.PushState(state);
context.PushState(state, definition_finish_state);
context.PushState(State::DeclScopeLoop);
context.AddNode(definition_start_kind, context.Consume(), state.subtree_start,
state.has_error);
Expand Down
Loading

0 comments on commit b7d129b

Please sign in to comment.