Split out and/or operator handling from infix. (#3480)

This is also doing the parse node split, allowing lower reliance in
formatter on the tokenized buffer (something that I may be touching more
due to import handling).
This commit is contained in:
Jon Ross-Perkins
2023-12-09 01:03:32 +00:00
committed by GitHub
parent b7d129b88c
commit c4864aa2ff
12 changed files with 151 additions and 105 deletions
+34 -15
View File
@@ -264,15 +264,26 @@ auto HandleExprLoop(Context& context) -> void {
state.lhs_precedence = operator_precedence;
if (is_binary) {
if (operator_kind == Lex::TokenKind::And ||
operator_kind == Lex::TokenKind::Or) {
switch (operator_kind) {
// For `and` and `or`, wrap the first operand in a virtual parse tree
// node so that semantics can insert control flow here.
context.AddNode(NodeKind::ShortCircuitOperand, state.token,
state.subtree_start, state.has_error);
// node so that checking can insert control flow here.
case Lex::TokenKind::And:
context.AddNode(NodeKind::ShortCircuitOperandAnd, state.token,
state.subtree_start, state.has_error);
state.state = State::ExprLoopForShortCircuitOperatorAsAnd;
break;
case Lex::TokenKind::Or:
context.AddNode(NodeKind::ShortCircuitOperandOr, state.token,
state.subtree_start, state.has_error);
state.state = State::ExprLoopForShortCircuitOperatorAsOr;
break;
default:
state.state = State::ExprLoopForBinary;
break;
}
context.PushState(state, State::ExprLoopForBinary);
context.PushState(state);
context.PushStateForExpr(operator_precedence);
} else {
context.AddNode(NodeKind::PostfixOperator, state.token, state.subtree_start,
@@ -282,22 +293,30 @@ auto HandleExprLoop(Context& context) -> void {
}
}
auto HandleExprLoopForBinary(Context& context) -> void {
// Adds the operator node and returns the the main expression loop.
static auto HandleExprLoopForOperator(Context& context, NodeKind node_kind)
-> void {
auto state = context.PopState();
context.AddNode(NodeKind::InfixOperator, state.token, state.subtree_start,
state.has_error);
context.AddNode(node_kind, state.token, state.subtree_start, state.has_error);
state.has_error = false;
context.PushState(state, State::ExprLoop);
}
auto HandleExprLoopForPrefix(Context& context) -> void {
auto state = context.PopState();
auto HandleExprLoopForBinary(Context& context) -> void {
HandleExprLoopForOperator(context, NodeKind::InfixOperator);
}
context.AddNode(NodeKind::PrefixOperator, state.token, state.subtree_start,
state.has_error);
state.has_error = false;
context.PushState(state, State::ExprLoop);
auto HandleExprLoopForPrefix(Context& context) -> void {
HandleExprLoopForOperator(context, NodeKind::PrefixOperator);
}
auto HandleExprLoopForShortCircuitOperatorAsAnd(Context& context) -> void {
HandleExprLoopForOperator(context, NodeKind::ShortCircuitOperatorAnd);
}
auto HandleExprLoopForShortCircuitOperatorAsOr(Context& context) -> void {
HandleExprLoopForOperator(context, NodeKind::ShortCircuitOperatorOr);
}
auto HandleIfExprFinishCondition(Context& context) -> void {