From e343ea593cfcfb9df9d4e7bcfcdbcb85bd8da25b Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Wed, 13 Dec 2023 15:54:27 -0800 Subject: [PATCH] Add macro for postfix operators. (#3504) Per request on #3481, for consistency with prefix/infix. --- toolchain/check/node_stack.h | 4 +++- toolchain/parse/handle_expr.cpp | 18 ++++++++++++++-- toolchain/parse/node_kind.def | 37 ++++++++++++++++++++------------- 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/toolchain/check/node_stack.h b/toolchain/check/node_stack.h index 907af2da172b..dadb493ed2cb 100644 --- a/toolchain/check/node_stack.h +++ b/toolchain/check/node_stack.h @@ -333,7 +333,6 @@ class NodeStack { case Parse::NodeKind::MemberAccessExpr: case Parse::NodeKind::PackageExpr: case Parse::NodeKind::ParenExpr: - case Parse::NodeKind::PostfixOperatorStar: case Parse::NodeKind::ReturnType: case Parse::NodeKind::SelfTypeNameExpr: case Parse::NodeKind::SelfValueNameExpr: @@ -387,6 +386,9 @@ class NodeStack { #define CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Name, ...) \ case Parse::NodeKind::InfixOperator##Name: \ return IdKind::InstId; +#define CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR(Name, ...) \ + case Parse::NodeKind::PostfixOperator##Name: \ + return IdKind::InstId; #define CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Name, ...) \ case Parse::NodeKind::PrefixOperator##Name: \ return IdKind::InstId; diff --git a/toolchain/parse/handle_expr.cpp b/toolchain/parse/handle_expr.cpp index 58ffb50449e6..81d72a697de5 100644 --- a/toolchain/parse/handle_expr.cpp +++ b/toolchain/parse/handle_expr.cpp @@ -287,8 +287,22 @@ auto HandleExprLoop(Context& context) -> void { context.PushState(state); context.PushStateForExpr(operator_precedence); } else { - context.AddNode(NodeKind::PostfixOperatorStar, state.token, - state.subtree_start, state.has_error); + NodeKind node_kind; + switch (operator_kind) { +#define CARBON_PARSE_NODE_KIND(...) +#define CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR(Name, ...) \ + case Lex::TokenKind::Name: \ + node_kind = NodeKind::PostfixOperator##Name; \ + break; +#include "toolchain/parse/node_kind.def" + + default: + CARBON_FATAL() << "Unexpected token kind for postfix operator: " + << operator_kind; + } + + context.AddNode(node_kind, state.token, state.subtree_start, + state.has_error); state.has_error = false; context.PushState(state); } diff --git a/toolchain/parse/node_kind.def b/toolchain/parse/node_kind.def index ebda9ec3c59a..649fd4e75876 100644 --- a/toolchain/parse/node_kind.def +++ b/toolchain/parse/node_kind.def @@ -16,10 +16,12 @@ // - CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name, ChildCount, LexTokenKind) // Defines a parse node with a set number of children, often 0. This count // must be correct even when the node contains errors. -// - CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Name) -// Defines a parse node for an infix operator, with the Name as token. // - CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Name) // Defines a parse node for a prefix operator, with the Name as token. +// - CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Name) +// Defines a parse node for an infix operator, with the Name as token. +// - CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR(Name) +// Defines a parse node for a postfix operator, with the Name as token. // - CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(Name, LexTokenKind) // Defines a parse node that corresponds to a token that is a single-token // literal. The token is wrapped for LexTokenKinds. @@ -56,6 +58,16 @@ CARBON_PARSE_NODE_KIND(Name) #endif +// This is expected to be used with something like: +// +// // Use x-macros to handle modifier cases. +// #define CARBON_PARSE_NODE_KIND(...) +// #define CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Name, ...) +#ifndef CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR +#define CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Name) \ + CARBON_PARSE_NODE_KIND_CHILD_COUNT(PrefixOperator##Name, 1, Name) +#endif + // This is expected to be used with something like: // // // Use x-macros to handle modifier cases. @@ -70,10 +82,10 @@ // // // Use x-macros to handle modifier cases. // #define CARBON_PARSE_NODE_KIND(...) -// #define CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Name, ...) -#ifndef CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR -#define CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Name) \ - CARBON_PARSE_NODE_KIND_CHILD_COUNT(PrefixOperator##Name, 1, Name) +// #define CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR(Name, ...) +#ifndef CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR +#define CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR(Name) \ + CARBON_PARSE_NODE_KIND_CHILD_COUNT(PostfixOperator##Name, 1, Name) #endif // This is expected to be used with something like: @@ -472,8 +484,6 @@ CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(FloatTypeLiteral, FloatTypeLiteral) CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(StringTypeLiteral, StringTypeLiteral) CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(TypeTypeLiteral, Type) -// clang-format off - // A prefix operator, such as `not`: // _external_: expression // PrefixOperator @@ -520,7 +530,10 @@ CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(SlashEqual) CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Star) CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(StarEqual) -// clang-format on +// A postfix operator, currently only `*`: +// _external_: expression +// PostfixOperator +CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR(Star) // A short-circuiting infix operator, such as `and`: // _external_: expression @@ -532,11 +545,6 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(ShortCircuitOperandOr, 1, Or) CARBON_PARSE_NODE_KIND_CHILD_COUNT(ShortCircuitOperatorAnd, 2, And) CARBON_PARSE_NODE_KIND_CHILD_COUNT(ShortCircuitOperatorOr, 2, Or) -// A postfix operator, currently only `*`: -// _external_: expression -// PostfixOperatorStar -CARBON_PARSE_NODE_KIND_CHILD_COUNT(PostfixOperatorStar, 1, Star) - // `if` expression + `then` + `else`: // _external_: expression // IfExprIf @@ -696,6 +704,7 @@ CARBON_PARSE_NODE_KIND_BRACKET(NamedConstraintDecl, NamedConstraintIntroducer, #undef CARBON_PARSE_NODE_KIND_BRACKET #undef CARBON_PARSE_NODE_KIND_CHILD_COUNT #undef CARBON_PARSE_NODE_KIND_INFIX_OPERATOR +#undef CARBON_PARSE_NODE_KIND_POSTFIX_OPERATOR #undef CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR #undef CARBON_PARSE_NODE_KIND_TOKEN_LITERAL #undef CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER