mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-03 22:02:51 +01:00
Refactor state construction and change how the decl loop makes state. (#3467)
Building on #3463. The PushState+PopState to construct a state feels worth cleanup. The rest is just kind of making it easier to do without adding another PushState overload.
This commit is contained in:
@@ -77,6 +77,18 @@ static auto HandleUnrecognizedDecl(Context& context, int32_t subtree_start)
|
||||
FinishAndSkipInvalidDecl(context, subtree_start);
|
||||
}
|
||||
|
||||
// Replaces the introducer placeholder node, and pushes the introducer state for
|
||||
// processing.
|
||||
static auto ApplyIntroducer(Context& context, Context::StateStackEntry state,
|
||||
NodeKind introducer_kind, State next_state)
|
||||
-> void {
|
||||
context.ReplacePlaceholderNode(state.subtree_start, introducer_kind,
|
||||
context.Consume());
|
||||
// Reuse state here to retain its `subtree_start`.
|
||||
state.state = next_state;
|
||||
context.PushState(state);
|
||||
}
|
||||
|
||||
// Handles `base` as a declaration.
|
||||
static auto HandleBaseAsDecl(Context& context, Context::StateStackEntry state)
|
||||
-> void {
|
||||
@@ -84,11 +96,7 @@ static auto HandleBaseAsDecl(Context& context, Context::StateStackEntry state)
|
||||
// it's followed by a colon, it's an introducer (`extend base: BaseType;`).
|
||||
// Otherwise it's an error.
|
||||
if (context.PositionIs(Lex::TokenKind::Colon, Lookahead::NextToken)) {
|
||||
context.ReplacePlaceholderNode(state.subtree_start,
|
||||
NodeKind::BaseIntroducer, context.Consume());
|
||||
// Reuse state here to retain its `subtree_start`
|
||||
state.state = State::BaseDecl;
|
||||
context.PushState(state);
|
||||
ApplyIntroducer(context, state, NodeKind::BaseIntroducer, State::BaseDecl);
|
||||
context.PushState(State::Expr);
|
||||
context.AddLeafNode(NodeKind::BaseColon, context.Consume());
|
||||
} else {
|
||||
@@ -109,26 +117,19 @@ static auto HandleBaseAsDecl(Context& context, Context::StateStackEntry state)
|
||||
// to a state to parse the rest of the declaration.
|
||||
static auto TryHandleAsDecl(Context& context, Context::StateStackEntry state,
|
||||
bool saw_modifier) -> bool {
|
||||
auto introducer = [&](NodeKind node_kind, State next_state) {
|
||||
context.ReplacePlaceholderNode(state.subtree_start, node_kind,
|
||||
context.Consume());
|
||||
// Reuse state here to retain its `subtree_start`.
|
||||
state.state = next_state;
|
||||
context.PushState(state);
|
||||
};
|
||||
|
||||
switch (context.PositionKind()) {
|
||||
case Lex::TokenKind::Base: {
|
||||
HandleBaseAsDecl(context, state);
|
||||
return true;
|
||||
}
|
||||
case Lex::TokenKind::Class: {
|
||||
introducer(NodeKind::ClassIntroducer, State::TypeAfterIntroducerAsClass);
|
||||
ApplyIntroducer(context, state, NodeKind::ClassIntroducer,
|
||||
State::TypeAfterIntroducerAsClass);
|
||||
return true;
|
||||
}
|
||||
case Lex::TokenKind::Constraint: {
|
||||
introducer(NodeKind::NamedConstraintIntroducer,
|
||||
State::TypeAfterIntroducerAsNamedConstraint);
|
||||
ApplyIntroducer(context, state, NodeKind::NamedConstraintIntroducer,
|
||||
State::TypeAfterIntroducerAsNamedConstraint);
|
||||
return true;
|
||||
}
|
||||
case Lex::TokenKind::Extend: {
|
||||
@@ -137,7 +138,8 @@ static auto TryHandleAsDecl(Context& context, Context::StateStackEntry state,
|
||||
return true;
|
||||
}
|
||||
case Lex::TokenKind::Fn: {
|
||||
introducer(NodeKind::FunctionIntroducer, State::FunctionIntroducer);
|
||||
ApplyIntroducer(context, state, NodeKind::FunctionIntroducer,
|
||||
State::FunctionIntroducer);
|
||||
return true;
|
||||
}
|
||||
case Lex::TokenKind::Impl: {
|
||||
@@ -146,20 +148,22 @@ static auto TryHandleAsDecl(Context& context, Context::StateStackEntry state,
|
||||
return true;
|
||||
}
|
||||
case Lex::TokenKind::Interface: {
|
||||
introducer(NodeKind::InterfaceIntroducer,
|
||||
State::TypeAfterIntroducerAsInterface);
|
||||
ApplyIntroducer(context, state, NodeKind::InterfaceIntroducer,
|
||||
State::TypeAfterIntroducerAsInterface);
|
||||
return true;
|
||||
}
|
||||
case Lex::TokenKind::Namespace: {
|
||||
introducer(NodeKind::NamespaceStart, State::Namespace);
|
||||
ApplyIntroducer(context, state, NodeKind::NamespaceStart,
|
||||
State::Namespace);
|
||||
return true;
|
||||
}
|
||||
case Lex::TokenKind::Let: {
|
||||
introducer(NodeKind::LetIntroducer, State::Let);
|
||||
ApplyIntroducer(context, state, NodeKind::LetIntroducer, State::Let);
|
||||
return true;
|
||||
}
|
||||
case Lex::TokenKind::Var: {
|
||||
introducer(NodeKind::VariableIntroducer, State::VarAsDecl);
|
||||
ApplyIntroducer(context, state, NodeKind::VariableIntroducer,
|
||||
State::VarAsDecl);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -243,10 +247,11 @@ auto HandleDeclScopeLoop(Context& context) -> void {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a state with the correct starting position, with a dummy kind until
|
||||
// we see the declaration's introducer.
|
||||
context.PushState(State::DeclScopeLoop);
|
||||
auto state = context.PopState();
|
||||
// Create a state with the correct starting position, with a dummy kind
|
||||
// until we see the declaration's introducer.
|
||||
Context::StateStackEntry state{.state = State::Invalid,
|
||||
.token = *context.position(),
|
||||
.subtree_start = context.tree().size()};
|
||||
|
||||
// Add a placeholder node, to be replaced by the declaration introducer once
|
||||
// it is found.
|
||||
|
||||
Reference in New Issue
Block a user