mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 12:11:04 +01:00
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:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user