mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-03 21:05:50 +01:00
Note #3486 rewrites the macro behavior, and is already approved: so this PR is only for the changed enforcement during error. Also, #3493 already changed several things to allow any token while this PR was awaiting review, but this still changes enforcement for `For` and `If`. This was brought up on [#toolchain](https://discord.com/channels/655572317891461132/655578254970716160/1182066616456970251), and I think this any-on-error approach gets at least some support. We could try setting it to the introducer, but it's quite possible we want it to be something like the token which led to the parse error, rather than a static token. That leads to a conclusion that, most typically, we'll expect arbitrary tokens when error conditions may lead to tokens which aren't the expected token. A couple related, recent `CARBON_IF_ERROR` crash fixes can be found in #3404 and #3424. Something like #3404 would've been needed regardless because `namespace` didn't have `CARBON_IF_ERROR` before, although I might've missed the underlying issue with declarations because only `namespace` had a relevant test (that is, if #3404 had added `CARBON_ANY_TOKEN_ON_ERROR`, I wouldn't have had a crash in #3462). #3424 would've been avoided with this change because there was a `CARBON_IF_ERROR`, and it was just too restrictive.
757 lines
31 KiB
Modula-2
757 lines
31 KiB
Modula-2
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
// This is an X-macro header. It does not use `#include` guards, and instead is
|
|
// designed to be `#include`ed after the x-macro is defined in order for its
|
|
// inclusion to expand to the desired output. Macro definitions are cleaned up
|
|
// at the end of this file.
|
|
//
|
|
// Supported x-macros are:
|
|
// - CARBON_PARSE_NODE_KIND(Name)
|
|
// Used as a fallback if other macros are missing. No kinds should use this
|
|
// directly.
|
|
// - CARBON_PARSE_NODE_KIND_BRACKET(Name, BracketName, LexTokenKinds)
|
|
// Defines a bracketed node kind. BracketName should refer to the node
|
|
// kind that is the _start_ of the bracketed range.
|
|
// - CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name, ChildCount, LexTokenKinds)
|
|
// 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_TOKEN_LITERAL(Name, LexTokenKinds)
|
|
// Defines a parse node that corresponds to a token that is a single-token
|
|
// literal. The token is wrapped for LexTokenKinds.
|
|
// - CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Name)
|
|
// A token-based modifier. The Name is the TokenKind, and will be appended
|
|
// with "Modifier" for the parse kind.
|
|
//
|
|
// In both cases, LexTokenKinds says which Lex::TokenKind values that this
|
|
// parse node can correspond to, and is a sequence of:
|
|
// - CARBON_TOKEN(kind): This node can correspond to this kind of token.
|
|
// - CARBON_ANY_TOKEN_ON_ERROR: When the `has_error` flag is set, this node
|
|
// can correspond to any token.
|
|
//
|
|
// This tree represents the subset relationship between these macros, where if a
|
|
// specific x-macro isn't defined, it'll fall back to the parent macro.
|
|
//
|
|
// Parse nodes are clustered based on language feature. Comments will show their
|
|
// relationship in postorder, using indentation for child node relationships.
|
|
|
|
#if !(defined(CARBON_PARSE_NODE_KIND) || \
|
|
(defined(CARBON_PARSE_NODE_KIND_BRACKET) && \
|
|
defined(CARBON_PARSE_NODE_KIND_CHILD_COUNT)))
|
|
#error "Must define CARBON_PARSE_NODE_KIND family x-macros to use this file."
|
|
#endif
|
|
|
|
// The BRACKET and CHILD_COUNT macros will use CARBON_PARSE_NODE_KIND by default
|
|
// when undefined.
|
|
#ifndef CARBON_PARSE_NODE_KIND_BRACKET
|
|
#define CARBON_PARSE_NODE_KIND_BRACKET(Name, ...) CARBON_PARSE_NODE_KIND(Name)
|
|
#endif
|
|
#ifndef CARBON_PARSE_NODE_KIND_CHILD_COUNT
|
|
#define CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name, ...) \
|
|
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_INFIX_OPERATOR(Name, ...) <code>
|
|
#ifndef CARBON_PARSE_NODE_KIND_INFIX_OPERATOR
|
|
#define CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Name) \
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(InfixOperator##Name, 2, CARBON_TOKEN(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, ...) <code>
|
|
#ifndef CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR
|
|
#define CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Name) \
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PrefixOperator##Name, 1, \
|
|
CARBON_TOKEN(Name))
|
|
#endif
|
|
|
|
// This is expected to be used with something like:
|
|
//
|
|
// // Use x-macros to handle literal cases.
|
|
// #define CARBON_PARSE_NODE_KIND(...)
|
|
// #define CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(Name, ...) <code>
|
|
#ifndef CARBON_PARSE_NODE_KIND_TOKEN_LITERAL
|
|
#define CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(Name, LexTokenKinds) \
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name, 0, LexTokenKinds)
|
|
#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_TOKEN_MODIFIER(Name, ...) <code>
|
|
#ifndef CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER
|
|
#define CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Name) \
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name##Modifier, 0, CARBON_TOKEN(Name))
|
|
#endif
|
|
|
|
// The start of the file.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(FileStart, 0, CARBON_TOKEN(FileStart))
|
|
|
|
// The end of the file.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(FileEnd, 0, CARBON_TOKEN(FileEnd))
|
|
|
|
// An invalid parse. Used to balance the parse tree. Always has an error.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(InvalidParse, 0, CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// An invalid subtree. Always has an error.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(InvalidParseStart, 0,
|
|
CARBON_ANY_TOKEN_ON_ERROR)
|
|
CARBON_PARSE_NODE_KIND_BRACKET(InvalidParseSubtree, InvalidParseStart,
|
|
CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// A placeholder node to be replaced. Its token kind is not enforced even when
|
|
// valid, as a special-case in node_kind.cpp.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(Placeholder, 0, CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// An empty declaration, such as `;`.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(EmptyDecl, 0,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// An identifier name in a non-expression context, such as a declaration.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IdentifierName, 0,
|
|
CARBON_TOKEN(Identifier)
|
|
CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// An identifier name in an expression context.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IdentifierNameExpr, 0,
|
|
CARBON_TOKEN(Identifier))
|
|
|
|
// The `self` value and `Self` type identifier keywords. Typically of the form
|
|
// `self: Self`.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(SelfValueName, 0,
|
|
CARBON_TOKEN(SelfValueIdentifier))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(SelfValueNameExpr, 0,
|
|
CARBON_TOKEN(SelfValueIdentifier))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(SelfTypeNameExpr, 0,
|
|
CARBON_TOKEN(SelfTypeIdentifier))
|
|
|
|
// The `base` value keyword, introduced by `base: B`. Typically referenced in
|
|
// an expression, as in `x.base` or `{.base = ...}`, but can also be used as a
|
|
// declared name, as in `{.base: partial B}`.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(BaseName, 0, CARBON_TOKEN(Base))
|
|
|
|
// The `package` keyword in an expression.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PackageExpr, 0, CARBON_TOKEN(Package))
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// The comments below follow this pattern:
|
|
//
|
|
// // Descriptive heading:
|
|
// // Child1
|
|
// // Child2
|
|
// // Parent
|
|
//
|
|
// In this, `Child1`, `Child2`, and `Parent` are all kinds of parse nodes, which
|
|
// are then defined using the `CARBON_PARSE_NODE_KIND_*` macros. They are
|
|
// written in postorder, with the indentation showing the tree structure. See
|
|
// tree.h for more information.
|
|
//
|
|
// A parse node kind may be preceded by:
|
|
// - `_optional_` if this node (or nodes) may be present or omitted in valid
|
|
// parses, depending on which tokens are in the source code.
|
|
// - `_repeated_` if this node (or nodes) may be repeated or omitted in valid
|
|
// parses, depending on which tokens are in the source code.
|
|
// - `_external_:` if this node is the child of multiple kinds of nodes and
|
|
// is documented separately.
|
|
//
|
|
// There is generally a close correspondence between handling of tokens and the
|
|
// creation of non-external nodes in a given block.
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// The name of a package or library for `package`, `import`, and `library`.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PackageName, 0, CARBON_TOKEN(Identifier))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(LibraryName, 0, CARBON_TOKEN(StringLiteral))
|
|
|
|
// `package`:
|
|
// PackageIntroducer
|
|
// _optional_ _external_: PackageName
|
|
// _optional_ _external_: LibrarySpecifier
|
|
// PackageApi or PackageImpl
|
|
// PackageDirective
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PackageIntroducer, 0, CARBON_TOKEN(Package))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PackageApi, 0, CARBON_TOKEN(Api))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PackageImpl, 0, CARBON_TOKEN(Impl))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(PackageDirective, PackageIntroducer,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// `import`:
|
|
// ImportIntroducer
|
|
// _optional_ _external_: PackageName
|
|
// _optional_ _external_: LibrarySpecifier
|
|
// ImportDirective
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ImportIntroducer, 0, CARBON_TOKEN(Import))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(ImportDirective, ImportIntroducer,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
// `library` as directive:
|
|
// LibraryIntroducer
|
|
// DefaultLibrary or _external_: LibraryName
|
|
// LibraryDirective
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(DefaultLibrary, 0, CARBON_TOKEN(Default))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(LibraryIntroducer, 0, CARBON_TOKEN(Library))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(LibraryDirective, LibraryIntroducer,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// `library` in `package` or `import`:
|
|
// _external_: LibraryName
|
|
// LibrarySpecifier
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(LibrarySpecifier, 1, CARBON_TOKEN(Library))
|
|
|
|
// `namespace`:
|
|
// NamespaceStart
|
|
// _repeated_ _external_: modifier
|
|
// _external_: Name or QualifiedDecl
|
|
// Namespace
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(NamespaceStart, 0, CARBON_TOKEN(Namespace))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(Namespace, NamespaceStart,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// A code block:
|
|
// CodeBlockStart
|
|
// _repeated_ _external_: statement
|
|
// CodeBlock
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(CodeBlockStart, 0,
|
|
CARBON_TOKEN(OpenCurlyBrace)
|
|
CARBON_ANY_TOKEN_ON_ERROR)
|
|
CARBON_PARSE_NODE_KIND_BRACKET(CodeBlock, CodeBlockStart,
|
|
CARBON_TOKEN(CloseCurlyBrace)
|
|
CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// `fn`:
|
|
// FunctionIntroducer
|
|
// _repeated_ _external_: modifier
|
|
// _external_: Name or QualifiedDecl
|
|
// _external_: TuplePattern
|
|
// _external_: type expression
|
|
// ReturnType
|
|
// FunctionDefinitionStart
|
|
// _repeated_ _external_: statement
|
|
// FunctionDefinition
|
|
//
|
|
// The above is the structure for a definition; for a declaration,
|
|
// FunctionDefinitionStart and later nodes are removed and replaced by
|
|
// FunctionDecl.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(FunctionIntroducer, 0, CARBON_TOKEN(Fn))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ReturnType, 1, CARBON_TOKEN(MinusGreater))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(FunctionDefinitionStart, FunctionIntroducer,
|
|
CARBON_TOKEN(OpenCurlyBrace))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(FunctionDefinition, FunctionDefinitionStart,
|
|
CARBON_TOKEN(CloseCurlyBrace))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(FunctionDecl, FunctionIntroducer,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// A tuple pattern:
|
|
// TuplePatternStart
|
|
// _external_: [Generic]BindingPattern
|
|
// PatternListComma
|
|
// _repeated_
|
|
// TuplePattern
|
|
//
|
|
// Patterns and PatternListComma may repeat with PatternListComma as a
|
|
// separator.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(TuplePatternStart, 0,
|
|
CARBON_TOKEN(OpenParen))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PatternListComma, 0, CARBON_TOKEN(Comma))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(TuplePattern, TuplePatternStart,
|
|
CARBON_TOKEN(CloseParen))
|
|
|
|
// An implicit parameter list:
|
|
// ImplicitParamListStart
|
|
// _external_: [Generic]BindingPattern
|
|
// PatternListComma
|
|
// _repeated_
|
|
// ImplicitParamList
|
|
//
|
|
// Patterns and PatternListComma may repeat with PatternListComma as a
|
|
// separator.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ImplicitParamListStart, 0,
|
|
CARBON_TOKEN(OpenSquareBracket))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(ImplicitParamList, ImplicitParamListStart,
|
|
CARBON_TOKEN(CloseSquareBracket))
|
|
|
|
// An array type, such as `[i32; 3]` or `[i32;]`:
|
|
// ArrayExprStart
|
|
// _external_: type expression
|
|
// ArrayExprSemi
|
|
// _optional_ _external_: expression
|
|
// ArrayExpr
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ArrayExprStart, 0,
|
|
CARBON_TOKEN(OpenSquareBracket))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ArrayExprSemi, 2,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
CARBON_PARSE_NODE_KIND_BRACKET(ArrayExpr, ArrayExprSemi,
|
|
CARBON_TOKEN(CloseSquareBracket))
|
|
|
|
// A binding pattern, such as `name: Type`:
|
|
// Name or SelfValueName
|
|
// _external_: type expression
|
|
// [Generic]BindingPattern
|
|
// _optional_ Address
|
|
// _optional_ Template
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(BindingPattern, 2,
|
|
CARBON_TOKEN(Colon)
|
|
CARBON_ANY_TOKEN_ON_ERROR)
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(GenericBindingPattern, 2,
|
|
CARBON_TOKEN(ColonExclaim))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(Address, 1, CARBON_TOKEN(Addr))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(Template, 1, CARBON_TOKEN(Template))
|
|
|
|
// `let`:
|
|
// LetIntroducer
|
|
// _repeated_ _external_: modifier
|
|
// _external_: BindingPattern or TuplePattern
|
|
// LetInitializer
|
|
// _external_: expression
|
|
// LetDecl
|
|
//
|
|
// Modifier keywords only appear for `let` declarations, not `let` statements.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(LetIntroducer, 0, CARBON_TOKEN(Let))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(LetInitializer, 0, CARBON_TOKEN(Equal))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(LetDecl, LetIntroducer,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// `var` and `returned var`:
|
|
// VariableIntroducer
|
|
// _repeated_ _external_: modifier
|
|
// _optional_ ReturnedModifier
|
|
// _external_: BindingPattern or TuplePattern
|
|
// VariableInitializer
|
|
// _external_: expression
|
|
// _optional_
|
|
// VariableDecl
|
|
//
|
|
// Access and declaration modifier keywords only appear for `var` declarations,
|
|
// whereas the returned modifier only appears on `var` statements.
|
|
// The VariableInitializer and following expression are paired: either both will
|
|
// be present, or neither will.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(VariableIntroducer, 0,
|
|
CARBON_TOKEN(Var) CARBON_ANY_TOKEN_ON_ERROR)
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ReturnedModifier, 0, CARBON_TOKEN(Returned))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(VariableInitializer, 0, CARBON_TOKEN(Equal))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(VariableDecl, VariableIntroducer,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// An expression statement:
|
|
// _external_: expression
|
|
// ExprStatement
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ExprStatement, 1,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// `break`:
|
|
// BreakStatementStart
|
|
// BreakStatement
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(BreakStatementStart, 0, CARBON_TOKEN(Break))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(BreakStatement, 1,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// `continue`:
|
|
// ContinueStatementStart
|
|
// ContinueStatement
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ContinueStatementStart, 0,
|
|
CARBON_TOKEN(Continue))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ContinueStatement, 1,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// `return`:
|
|
// ReturnStatementStart
|
|
// _optional_ ReturnVarModifier or _external_: expression
|
|
// ReturnStatement
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ReturnStatementStart, 0,
|
|
CARBON_TOKEN(Return))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ReturnVarModifier, 0, CARBON_TOKEN(Var))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(ReturnStatement, ReturnStatementStart,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// `for`:
|
|
// ForHeaderStart
|
|
// VariableIntroducer
|
|
// _external_: BindingPattern
|
|
// ForIn
|
|
// _external_: expression
|
|
// ForHeader
|
|
// _external_: CodeBlock
|
|
// ForStatement
|
|
//
|
|
// Versus a normal `var`, ForIn replaces VariableDecl.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ForHeaderStart, 0,
|
|
CARBON_TOKEN(OpenParen)
|
|
CARBON_ANY_TOKEN_ON_ERROR)
|
|
CARBON_PARSE_NODE_KIND_BRACKET(ForIn, VariableIntroducer,
|
|
CARBON_TOKEN(In) CARBON_ANY_TOKEN_ON_ERROR)
|
|
CARBON_PARSE_NODE_KIND_BRACKET(ForHeader, ForHeaderStart,
|
|
CARBON_TOKEN(CloseParen)
|
|
CARBON_ANY_TOKEN_ON_ERROR)
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ForStatement, 2, CARBON_TOKEN(For))
|
|
|
|
// `if` statement + `else`:
|
|
// IfConditionStart
|
|
// _external_: expression
|
|
// IfCondition
|
|
// _external_: CodeBlock
|
|
// IfStatementElse
|
|
// _external_: CodeBlock or IfStatement
|
|
// IfStatement
|
|
//
|
|
// IfStatementElse and the following node are optional based on `else` presence.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfConditionStart, 0,
|
|
CARBON_TOKEN(OpenParen)
|
|
CARBON_ANY_TOKEN_ON_ERROR)
|
|
CARBON_PARSE_NODE_KIND_BRACKET(IfCondition, IfConditionStart,
|
|
CARBON_TOKEN(CloseParen)
|
|
CARBON_ANY_TOKEN_ON_ERROR)
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfStatementElse, 0, CARBON_TOKEN(Else))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(IfStatement, IfCondition, CARBON_TOKEN(If))
|
|
|
|
// `while`:
|
|
// WhileConditionStart
|
|
// _external_: expression
|
|
// WhileCondition
|
|
// _external_: CodeBlock
|
|
// WhileStatement
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(WhileConditionStart, 0,
|
|
CARBON_TOKEN(OpenParen))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(WhileCondition, WhileConditionStart,
|
|
CARBON_TOKEN(CloseParen))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(WhileStatement, 2, CARBON_TOKEN(While))
|
|
|
|
// Index expressions, such as `a[1]`:
|
|
// _external_: expression
|
|
// IndexExprStart
|
|
// _external_: expression
|
|
// IndexExpr
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IndexExprStart, 1,
|
|
CARBON_TOKEN(OpenSquareBracket))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(IndexExpr, IndexExprStart,
|
|
CARBON_TOKEN(CloseSquareBracket))
|
|
|
|
// Parenthesized single expressions, such as `(2)`:
|
|
// ExprOpenParen
|
|
// _external_: expression
|
|
// ParenExpr
|
|
//
|
|
// Tuples, such as `(1, 2)`:
|
|
// ExprOpenParen
|
|
// _external_: expression
|
|
// TupleLiteralComma
|
|
// _repeated_
|
|
// TupleLiteral
|
|
//
|
|
// Expressions and TupleLiteralComma may repeat with TupleLiteralComma as a
|
|
// separator.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ExprOpenParen, 0, CARBON_TOKEN(OpenParen))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(ParenExpr, ExprOpenParen,
|
|
CARBON_TOKEN(CloseParen))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(TupleLiteralComma, 0, CARBON_TOKEN(Comma))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(TupleLiteral, ExprOpenParen,
|
|
CARBON_TOKEN(CloseParen))
|
|
|
|
// Call expressions, such as `a()`:
|
|
// _external_: expression
|
|
// CallExprStart
|
|
// _external_: expression
|
|
// CallExprComma
|
|
// _repeated_
|
|
// CallExpr
|
|
//
|
|
// Exprs and CallExprComma may repeat with CallExprComma as a separator.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(CallExprStart, 1, CARBON_TOKEN(OpenParen))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(CallExprComma, 0, CARBON_TOKEN(Comma))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(CallExpr, CallExprStart,
|
|
CARBON_TOKEN(CloseParen))
|
|
|
|
// A qualified declaration, such as `a.b`:
|
|
// _external_: Name or QualifiedDecl
|
|
// _external_: Name
|
|
// QualifiedDecl
|
|
//
|
|
// TODO: This will eventually more general expressions, for example with
|
|
// `GenericType(type_args).ChildType(child_type_args).Name`.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(QualifiedDecl, 2, CARBON_TOKEN(Period))
|
|
|
|
// A member access expression, such as `a.b` or
|
|
// `GetObject().(Interface.member)`:
|
|
// _external_: lhs expression
|
|
// _external_: rhs expression
|
|
// QualifiedExpr
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(MemberAccessExpr, 2, CARBON_TOKEN(Period))
|
|
|
|
// A pointer member access expression, such as `a->b` or
|
|
// `GetObject()->(Interface.member)`:
|
|
// _external_: lhs expression
|
|
// _external_: rhs expression
|
|
// QualifiedExpr
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PointerMemberAccessExpr, 2,
|
|
CARBON_TOKEN(MinusGreater))
|
|
|
|
// A value literal.
|
|
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(BoolLiteralFalse, CARBON_TOKEN(False))
|
|
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(BoolLiteralTrue, CARBON_TOKEN(True))
|
|
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(IntLiteral, CARBON_TOKEN(IntLiteral))
|
|
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(RealLiteral, CARBON_TOKEN(RealLiteral))
|
|
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(StringLiteral, CARBON_TOKEN(StringLiteral))
|
|
|
|
// A type literal.
|
|
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(BoolTypeLiteral, CARBON_TOKEN(Bool))
|
|
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(IntTypeLiteral,
|
|
CARBON_TOKEN(IntTypeLiteral))
|
|
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(UnsignedIntTypeLiteral,
|
|
CARBON_TOKEN(UnsignedIntTypeLiteral))
|
|
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(FloatTypeLiteral,
|
|
CARBON_TOKEN(FloatTypeLiteral))
|
|
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(StringTypeLiteral,
|
|
CARBON_TOKEN(StringTypeLiteral))
|
|
CARBON_PARSE_NODE_KIND_TOKEN_LITERAL(TypeTypeLiteral, CARBON_TOKEN(Type))
|
|
|
|
// clang-format off
|
|
|
|
// A prefix operator, such as `not`:
|
|
// _external_: expression
|
|
// PrefixOperator<name>
|
|
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Amp)
|
|
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Caret)
|
|
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Const)
|
|
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Not)
|
|
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Minus)
|
|
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(MinusMinus)
|
|
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(PlusPlus)
|
|
CARBON_PARSE_NODE_KIND_PREFIX_OPERATOR(Star)
|
|
|
|
// An infix operator, such as `+`:
|
|
// _external_: lhs expression
|
|
// _external_: rhs expression
|
|
// InfixOperator<name>
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Amp)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(AmpEqual)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(As)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Caret)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(CaretEqual)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Equal)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(EqualEqual)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(ExclaimEqual)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Greater)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(GreaterEqual)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(GreaterGreater)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(GreaterGreaterEqual)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Less)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(LessEqual)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(LessEqualGreater)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(LessLess)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(LessLessEqual)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Minus)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(MinusEqual)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Percent)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(PercentEqual)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Pipe)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(PipeEqual)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Plus)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(PlusEqual)
|
|
CARBON_PARSE_NODE_KIND_INFIX_OPERATOR(Slash)
|
|
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 short-circuiting infix operator, such as `and`:
|
|
// _external_: expression
|
|
// ShortCircuitOperand(And|Or)
|
|
// _external_: expression
|
|
// ShortCircuitOperand(And|Or)
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ShortCircuitOperandAnd, 1, CARBON_TOKEN(And))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ShortCircuitOperandOr, 1, CARBON_TOKEN(Or))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ShortCircuitOperatorAnd, 2,
|
|
CARBON_TOKEN(And))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ShortCircuitOperatorOr, 2, CARBON_TOKEN(Or))
|
|
|
|
// A postfix operator, currently only `*`:
|
|
// _external_: expression
|
|
// PostfixOperatorStar
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(PostfixOperatorStar, 1, CARBON_TOKEN(Star))
|
|
|
|
// `if` expression + `then` + `else`:
|
|
// _external_: expression
|
|
// IfExprIf
|
|
// _external_: expression
|
|
// IfExprThen
|
|
// _external_: expression
|
|
// IfExprElse
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfExprIf, 1, CARBON_TOKEN(If))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfExprThen, 1, CARBON_TOKEN(Then))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfExprElse, 3,
|
|
CARBON_TOKEN(Else) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// Struct literals, such as `{.a = 0}`:
|
|
// StructLiteralOrStructTypeLiteralStart
|
|
// _external_: Name
|
|
// StructFieldDesignator
|
|
// _external_: expression
|
|
// StructFieldValue
|
|
// StructComma
|
|
// _repeated_
|
|
// StructLiteral
|
|
//
|
|
// Struct type literals, such as `{.a: i32}`:
|
|
// StructLiteralOrStructTypeLiteralStart
|
|
// _external_: Name
|
|
// StructFieldDesignator
|
|
// _external_: type expression
|
|
// StructFieldType
|
|
// StructComma
|
|
// _repeated_
|
|
// StructTypeLiteral
|
|
//
|
|
// Elements (StructFieldValue and StructFieldType, respectively) and StructComma
|
|
// may repeat with StructComma as a separator.
|
|
//
|
|
// When a valid StructFieldType or StructFieldValue cannot be formed, elements
|
|
// may be replaced by InvalidParse, which may have a preceding sibling
|
|
// StructFieldDesignator if one was successfully parsed.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructLiteralOrStructTypeLiteralStart, 0,
|
|
CARBON_TOKEN(OpenCurlyBrace))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructFieldDesignator, 1,
|
|
CARBON_TOKEN(Period))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructFieldValue, 2, CARBON_TOKEN(Equal))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructFieldType, 2, CARBON_TOKEN(Colon))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructComma, 0, CARBON_TOKEN(Comma))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(StructLiteral,
|
|
StructLiteralOrStructTypeLiteralStart,
|
|
CARBON_TOKEN(CloseCurlyBrace))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(StructTypeLiteral,
|
|
StructLiteralOrStructTypeLiteralStart,
|
|
CARBON_TOKEN(CloseCurlyBrace))
|
|
|
|
// Various modifiers. These are all a single token.
|
|
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Abstract)
|
|
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Base)
|
|
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Default)
|
|
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Extend)
|
|
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Final)
|
|
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Impl)
|
|
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Private)
|
|
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Protected)
|
|
CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Virtual)
|
|
|
|
// `class`:
|
|
// ClassIntroducer
|
|
// _repeated_ _external_: modifier
|
|
// _external_: Name or QualifiedDecl
|
|
// ClassDefinitionStart
|
|
// _external_: declarations
|
|
// ClassDefinition
|
|
//
|
|
// The above is the structure for a definition; for a declaration,
|
|
// ClassDefinitionStart and later nodes are removed and replaced by
|
|
// ClassDecl.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ClassIntroducer, 0, CARBON_TOKEN(Class))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(ClassDefinitionStart, ClassIntroducer,
|
|
CARBON_TOKEN(OpenCurlyBrace))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(ClassDefinition, ClassDefinitionStart,
|
|
CARBON_TOKEN(CloseCurlyBrace))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(ClassDecl, ClassIntroducer,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// `base`:
|
|
// BaseIntroducer
|
|
// _repeated_ _external_: modifier
|
|
// BaseColon
|
|
// _external_: expression
|
|
// BaseDecl
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(BaseIntroducer, 0, CARBON_TOKEN(Base))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(BaseColon, 0, CARBON_TOKEN(Colon))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(BaseDecl, BaseIntroducer,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// `interface`:
|
|
// InterfaceIntroducer
|
|
// _repeated_ _external_: modifier
|
|
// _external_: Name or QualifiedDecl
|
|
// InterfaceDefinitionStart
|
|
// _external_: declarations
|
|
// InterfaceDefinition
|
|
//
|
|
// The above is the structure for a definition; for a declaration,
|
|
// InterfaceDefinitionStart and later nodes are removed and replaced by
|
|
// InterfaceDecl.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(InterfaceIntroducer, 0,
|
|
CARBON_TOKEN(Interface))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(InterfaceDefinitionStart, InterfaceIntroducer,
|
|
CARBON_TOKEN(OpenCurlyBrace))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(InterfaceDefinition, InterfaceDefinitionStart,
|
|
CARBON_TOKEN(CloseCurlyBrace))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(InterfaceDecl, InterfaceIntroducer,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// `impl ... as`:
|
|
// ImplIntroducer
|
|
// _repeated_ _external_: modifier
|
|
// _optional_ ImplForall (see below)
|
|
// _optional_ _external_: expression
|
|
// ImplAs
|
|
// _external_: expression
|
|
// ImplDefinitionStart
|
|
// _external_: declarations
|
|
// ImplDefinition
|
|
//
|
|
// The above is the structure for a definition; for a declaration,
|
|
// ImplDefinitionStart and later nodes are removed and replaced by
|
|
// ImplDecl.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ImplIntroducer, 0, CARBON_TOKEN(Impl))
|
|
|
|
// `forall ...`:
|
|
// _external_: ImplicitParamList
|
|
// ImplForall
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ImplForall, 1, CARBON_TOKEN(Forall))
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(ImplAs, 0, CARBON_TOKEN(As))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(ImplDefinitionStart, ImplIntroducer,
|
|
CARBON_TOKEN(OpenCurlyBrace))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(ImplDefinition, ImplDefinitionStart,
|
|
CARBON_TOKEN(CloseCurlyBrace))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(ImplDecl, ImplIntroducer,
|
|
CARBON_TOKEN(Semi) CARBON_ANY_TOKEN_ON_ERROR)
|
|
|
|
// `constraint`:
|
|
// NamedConstraintIntroducer
|
|
// _repeated_ _external_: modifier
|
|
// _external_: Name or QualifiedDecl
|
|
// NamedConstraintDefinitionStart
|
|
// _external_: declarations
|
|
// NamedConstraintDefinition
|
|
//
|
|
// The above is the structure for a definition; for a declaration,
|
|
// NamedConstraintDefinitionStart and later nodes are removed and replaced by
|
|
// NamedConstraintDecl.
|
|
CARBON_PARSE_NODE_KIND_CHILD_COUNT(NamedConstraintIntroducer, 0,
|
|
CARBON_TOKEN(Constraint))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(NamedConstraintDefinitionStart,
|
|
NamedConstraintIntroducer,
|
|
CARBON_TOKEN(OpenCurlyBrace))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(NamedConstraintDefinition,
|
|
NamedConstraintDefinitionStart,
|
|
CARBON_TOKEN(CloseCurlyBrace))
|
|
CARBON_PARSE_NODE_KIND_BRACKET(NamedConstraintDecl, NamedConstraintIntroducer,
|
|
CARBON_TOKEN(Semi))
|
|
|
|
#undef CARBON_PARSE_NODE_KIND
|
|
#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_PREFIX_OPERATOR
|
|
#undef CARBON_PARSE_NODE_KIND_TOKEN_LITERAL
|
|
#undef CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER
|
|
#undef CARBON_TOKEN
|
|
#undef CARBON_ANY_TOKEN_ON_ERROR
|