// 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
//
// Note that this is an X-macro header.
//
// It does not use `#include` guards, and instead is designed to be `#include`ed
// after some set of x-macros are defined in order for its inclusion to expand
// to the desired output.
//
// The viable X-macros to define prior to including the header are:
//
// - `CARBON_TOKEN`
//   - `CARBON_SYMBOL_TOKEN`
//     - `CARBON_OPENING_GROUP_SYMBOL_TOKEN`
//     - `CARBON_CLOSING_GROUP_SYMBOL_TOKEN`
//   - `CARBON_KEYWORD_TOKEN`
//
// This tree represents the subset relationship between these macros.
//
// Regardless of which of these macros is defined prior to inclusion, all of the
// definitions will be removed at the end of including this file to clean up the
// set of defined macros.

#ifndef CARBON_TOKEN
#define CARBON_TOKEN(Name)
#endif

#ifndef CARBON_SYMBOL_TOKEN
#define CARBON_SYMBOL_TOKEN(Name, Spelling) CARBON_TOKEN(Name)
#endif

// Note that symbols need to be ordered from longest to shortest to effectively
// provide max-munch lexing.

// clang-format off

CARBON_SYMBOL_TOKEN(GreaterGreaterEqual, ">>=")
CARBON_SYMBOL_TOKEN(LessEqualGreater,    "<=>")
CARBON_SYMBOL_TOKEN(LessLessEqual,       "<<=")

CARBON_SYMBOL_TOKEN(AmpEqual,            "&=")
CARBON_SYMBOL_TOKEN(CaretEqual,          "^=")
CARBON_SYMBOL_TOKEN(ColonEqual,          ":=")
CARBON_SYMBOL_TOKEN(EqualEqual,          "==")
CARBON_SYMBOL_TOKEN(EqualGreater,        "=>")
CARBON_SYMBOL_TOKEN(ExclaimEqual,        "!=")
CARBON_SYMBOL_TOKEN(GreaterEqual,        ">=")
CARBON_SYMBOL_TOKEN(GreaterGreater,      ">>")
CARBON_SYMBOL_TOKEN(LessEqual,           "<=")
CARBON_SYMBOL_TOKEN(LessGreater,         "<>")
CARBON_SYMBOL_TOKEN(LessLess,            "<<")
CARBON_SYMBOL_TOKEN(LessMinus,           "<-")
CARBON_SYMBOL_TOKEN(MinusEqual,          "-=")
CARBON_SYMBOL_TOKEN(MinusGreater,        "->")
CARBON_SYMBOL_TOKEN(MinusMinus,          "--")
CARBON_SYMBOL_TOKEN(PercentEqual,        "%=")
CARBON_SYMBOL_TOKEN(PipeEqual,           "|=")
CARBON_SYMBOL_TOKEN(PlusEqual,           "+=")
CARBON_SYMBOL_TOKEN(PlusPlus,            "++")
CARBON_SYMBOL_TOKEN(SlashEqual,          "/=")
CARBON_SYMBOL_TOKEN(StarEqual,           "*=")
CARBON_SYMBOL_TOKEN(TildeEqual,          "~=")

CARBON_SYMBOL_TOKEN(Amp,                 "&")
CARBON_SYMBOL_TOKEN(At,                  "@")
CARBON_SYMBOL_TOKEN(Backslash,           "\\")
CARBON_SYMBOL_TOKEN(Caret,               "^")
CARBON_SYMBOL_TOKEN(Colon,               ":")
CARBON_SYMBOL_TOKEN(Comma,               ",")
CARBON_SYMBOL_TOKEN(Equal,               "=")
CARBON_SYMBOL_TOKEN(Exclaim,             "!")
CARBON_SYMBOL_TOKEN(Greater,             ">")
CARBON_SYMBOL_TOKEN(Less,                "<")
CARBON_SYMBOL_TOKEN(Minus,               "-")
CARBON_SYMBOL_TOKEN(Percent,             "%")
CARBON_SYMBOL_TOKEN(Period,              ".")
CARBON_SYMBOL_TOKEN(Pipe,                "|")
CARBON_SYMBOL_TOKEN(Plus,                "+")
CARBON_SYMBOL_TOKEN(Question,            "?")
CARBON_SYMBOL_TOKEN(Semi,                ";")
CARBON_SYMBOL_TOKEN(Slash,               "/")
CARBON_SYMBOL_TOKEN(Star,                "*")
CARBON_SYMBOL_TOKEN(Tilde,               "~")

// clang-format on

#ifndef CARBON_OPENING_GROUP_SYMBOL_TOKEN
#define CARBON_OPENING_GROUP_SYMBOL_TOKEN(Name, Spelling, ClosingName) \
  CARBON_SYMBOL_TOKEN(Name, Spelling)
#endif
// clang-format on
CARBON_OPENING_GROUP_SYMBOL_TOKEN(OpenParen, "(", CloseParen)
CARBON_OPENING_GROUP_SYMBOL_TOKEN(OpenCurlyBrace, "{", CloseCurlyBrace)
// clang-format off
#undef CARBON_OPENING_GROUP_SYMBOL_TOKEN

#ifndef CARBON_CLOSING_GROUP_SYMBOL_TOKEN
#define CARBON_CLOSING_GROUP_SYMBOL_TOKEN(Name, Spelling, OpeningName)         \
  CARBON_SYMBOL_TOKEN(Name, Spelling)
#endif
// clang-format on
CARBON_CLOSING_GROUP_SYMBOL_TOKEN(CloseParen, ")", OpenParen)
CARBON_CLOSING_GROUP_SYMBOL_TOKEN(CloseCurlyBrace, "}", OpenCurlyBrace)
// clang-format off
#undef CARBON_CLOSING_GROUP_SYMBOL_TOKEN

#undef CARBON_SYMBOL_TOKEN

#ifndef CARBON_KEYWORD_TOKEN
#define CARBON_KEYWORD_TOKEN(Name, Spelling) CARBON_TOKEN(Name)
#endif
// clang-format off
CARBON_KEYWORD_TOKEN(AndKeyword,        "and")
CARBON_KEYWORD_TOKEN(AsmKeyword,        "asm")
CARBON_KEYWORD_TOKEN(BreakKeyword,      "break")
CARBON_KEYWORD_TOKEN(CatchKeyword,      "catch")
CARBON_KEYWORD_TOKEN(ClassKeyword,      "class")
CARBON_KEYWORD_TOKEN(ContinueKeyword,   "continue")
CARBON_KEYWORD_TOKEN(ElseKeyword,       "else")
CARBON_KEYWORD_TOKEN(EnumKeyword,       "enum")
CARBON_KEYWORD_TOKEN(ExternKeyword,     "extern")
CARBON_KEYWORD_TOKEN(FinalKeyword,      "final")
CARBON_KEYWORD_TOKEN(FixKeyword,        "fix")
CARBON_KEYWORD_TOKEN(FnKeyword,         "fn")
CARBON_KEYWORD_TOKEN(ForKeyword,        "for")
CARBON_KEYWORD_TOKEN(GuardKeyword,      "guard")
CARBON_KEYWORD_TOKEN(IfKeyword,         "if")
CARBON_KEYWORD_TOKEN(InlineKeyword,     "inline")
CARBON_KEYWORD_TOKEN(InoutKeyword,      "inout")
CARBON_KEYWORD_TOKEN(InterfaceKeyword,  "interface")
CARBON_KEYWORD_TOKEN(InternalKeyword,   "internal")
CARBON_KEYWORD_TOKEN(LetKeyword,        "let")
CARBON_KEYWORD_TOKEN(LoopKeyword,       "loop")
CARBON_KEYWORD_TOKEN(MatchKeyword,      "match")
CARBON_KEYWORD_TOKEN(NotKeyword,        "not")
CARBON_KEYWORD_TOKEN(OrKeyword,         "or")
CARBON_KEYWORD_TOKEN(OutKeyword,        "out")
CARBON_KEYWORD_TOKEN(PrivateKeyword,    "private")
CARBON_KEYWORD_TOKEN(ProtectedKeyword,  "protected")
CARBON_KEYWORD_TOKEN(PublicKeyword,     "public")
CARBON_KEYWORD_TOKEN(RefKeyword,        "ref")
CARBON_KEYWORD_TOKEN(ReturnKeyword,     "return")
CARBON_KEYWORD_TOKEN(StaticKeyword,     "static")
CARBON_KEYWORD_TOKEN(StructKeyword,     "struct")
CARBON_KEYWORD_TOKEN(ThroKeyword,       "throw")
CARBON_KEYWORD_TOKEN(TryKeyword,        "try")
CARBON_KEYWORD_TOKEN(UnderscoreKeyword, "_")
CARBON_KEYWORD_TOKEN(VarKeyword,        "var")
CARBON_KEYWORD_TOKEN(VirtualKeyword,    "virtual")
CARBON_KEYWORD_TOKEN(WhileKeyword,      "while")
CARBON_KEYWORD_TOKEN(XorKeyword,        "xor")
// clang-format on
#undef CARBON_KEYWORD_TOKEN

CARBON_TOKEN(Identifier)
CARBON_TOKEN(IntegerLiteral)
CARBON_TOKEN(RealLiteral)
CARBON_TOKEN(StringLiteral)
CARBON_TOKEN(Error)

#undef CARBON_TOKEN
