summaryrefslogtreecommitdiffstats
path: root/js/src/frontend/TokenKind.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/frontend/TokenKind.h')
-rw-r--r--js/src/frontend/TokenKind.h333
1 files changed, 333 insertions, 0 deletions
diff --git a/js/src/frontend/TokenKind.h b/js/src/frontend/TokenKind.h
new file mode 100644
index 0000000000..102b91c6c4
--- /dev/null
+++ b/js/src/frontend/TokenKind.h
@@ -0,0 +1,333 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef frontend_TokenKind_h
+#define frontend_TokenKind_h
+
+#include <stdint.h>
+
+#include "js/TypeDecls.h" // IF_RECORD_TUPLE
+
+/*
+ * List of token kinds and their ranges.
+ *
+ * The format for each line is:
+ *
+ * MACRO(<TOKEN_KIND_NAME>, <DESCRIPTION>)
+ *
+ * or
+ *
+ * RANGE(<TOKEN_RANGE_NAME>, <TOKEN_KIND_NAME>)
+ *
+ * where ;
+ * <TOKEN_KIND_NAME> is a legal C identifier of the token, that will be used in
+ * the JS engine source.
+ *
+ * <DESCRIPTION> is a string that describe about the token, and will be used in
+ * error message.
+ *
+ * <TOKEN_RANGE_NAME> is a legal C identifier of the range that will be used to
+ * JS engine source. It should end with `First` or `Last`. This is used to check
+ * TokenKind by range-testing:
+ * BinOpFirst <= tt && tt <= BinOpLast
+ *
+ * Second argument of `RANGE` is the actual value of the <TOKEN_RANGE_NAME>,
+ * should be same as one of <TOKEN_KIND_NAME> in other `MACRO`s.
+ *
+ * To use this macro, define two macros for `MACRO` and `RANGE`, and pass them
+ * as arguments.
+ *
+ * #define EMIT_TOKEN(name, desc) ...
+ * #define EMIT_RANGE(name, value) ...
+ * FOR_EACH_TOKEN_KIND_WITH_RANGE(EMIT_TOKEN, EMIT_RANGE)
+ * #undef EMIT_TOKEN
+ * #undef EMIT_RANGE
+ *
+ * If you don't need range data, use FOR_EACH_TOKEN_KIND instead.
+ *
+ * #define EMIT_TOKEN(name, desc) ...
+ * FOR_EACH_TOKEN_KIND(EMIT_TOKEN)
+ * #undef EMIT_TOKEN
+ *
+ * Note that this list does not contain ERROR and LIMIT.
+ */
+#define FOR_EACH_TOKEN_KIND_WITH_RANGE(MACRO, RANGE) \
+ MACRO(Eof, "end of script") \
+ \
+ /* only returned by peekTokenSameLine() */ \
+ MACRO(Eol, "line terminator") \
+ \
+ MACRO(Semi, "';'") \
+ MACRO(Comma, "','") \
+ MACRO(Hook, "'?'") /* conditional */ \
+ MACRO(Colon, "':'") /* conditional */ \
+ MACRO(Inc, "'++'") /* increment */ \
+ MACRO(Dec, "'--'") /* decrement */ \
+ MACRO(Dot, "'.'") /* member operator */ \
+ MACRO(TripleDot, "'...'") /* rest arguments and spread operator */ \
+ MACRO(OptionalChain, "'?.'") \
+ MACRO(LeftBracket, "'['") \
+ IF_RECORD_TUPLE(MACRO(HashBracket, "'#['")) \
+ MACRO(RightBracket, "']'") \
+ MACRO(LeftCurly, "'{'") \
+ IF_RECORD_TUPLE(MACRO(HashCurly, "'#{'")) \
+ MACRO(RightCurly, "'}'") \
+ MACRO(LeftParen, "'('") \
+ MACRO(RightParen, "')'") \
+ MACRO(Name, "identifier") \
+ MACRO(PrivateName, "private identifier") \
+ MACRO(Number, "numeric literal") \
+ MACRO(String, "string literal") \
+ MACRO(BigInt, "bigint literal") \
+ IF_DECORATORS(MACRO(At, "'@'")) \
+ \
+ /* start of template literal with substitutions */ \
+ MACRO(TemplateHead, "'${'") \
+ /* template literal without substitutions */ \
+ MACRO(NoSubsTemplate, "template literal") \
+ \
+ MACRO(RegExp, "regular expression literal") \
+ MACRO(True, "boolean literal 'true'") \
+ RANGE(ReservedWordLiteralFirst, True) \
+ MACRO(False, "boolean literal 'false'") \
+ MACRO(Null, "null literal") \
+ RANGE(ReservedWordLiteralLast, Null) \
+ MACRO(This, "keyword 'this'") \
+ RANGE(KeywordFirst, This) \
+ MACRO(Function, "keyword 'function'") \
+ MACRO(If, "keyword 'if'") \
+ MACRO(Else, "keyword 'else'") \
+ MACRO(Switch, "keyword 'switch'") \
+ MACRO(Case, "keyword 'case'") \
+ MACRO(Default, "keyword 'default'") \
+ MACRO(While, "keyword 'while'") \
+ MACRO(Do, "keyword 'do'") \
+ MACRO(For, "keyword 'for'") \
+ MACRO(Break, "keyword 'break'") \
+ MACRO(Continue, "keyword 'continue'") \
+ MACRO(Var, "keyword 'var'") \
+ MACRO(Const, "keyword 'const'") \
+ MACRO(With, "keyword 'with'") \
+ MACRO(Return, "keyword 'return'") \
+ MACRO(New, "keyword 'new'") \
+ MACRO(Delete, "keyword 'delete'") \
+ MACRO(Try, "keyword 'try'") \
+ MACRO(Catch, "keyword 'catch'") \
+ MACRO(Finally, "keyword 'finally'") \
+ MACRO(Throw, "keyword 'throw'") \
+ MACRO(Debugger, "keyword 'debugger'") \
+ MACRO(Export, "keyword 'export'") \
+ MACRO(Import, "keyword 'import'") \
+ MACRO(Class, "keyword 'class'") \
+ MACRO(Extends, "keyword 'extends'") \
+ MACRO(Super, "keyword 'super'") \
+ RANGE(KeywordLast, Super) \
+ \
+ /* contextual keywords */ \
+ MACRO(As, "'as'") \
+ RANGE(ContextualKeywordFirst, As) \
+ /* TODO: Move to alphabetical order when IF_DECORATORS is removed */ \
+ IF_DECORATORS(MACRO(Accessor, "'accessor'")) \
+ MACRO(Assert, "'assert'") \
+ MACRO(Async, "'async'") \
+ MACRO(Await, "'await'") \
+ MACRO(Each, "'each'") \
+ MACRO(From, "'from'") \
+ MACRO(Get, "'get'") \
+ MACRO(Let, "'let'") \
+ MACRO(Meta, "'meta'") \
+ MACRO(Of, "'of'") \
+ MACRO(Set, "'set'") \
+ MACRO(Static, "'static'") \
+ MACRO(Target, "'target'") \
+ MACRO(Yield, "'yield'") \
+ RANGE(ContextualKeywordLast, Yield) \
+ \
+ /* future reserved words */ \
+ MACRO(Enum, "reserved word 'enum'") \
+ RANGE(FutureReservedKeywordFirst, Enum) \
+ RANGE(FutureReservedKeywordLast, Enum) \
+ \
+ /* reserved words in strict mode */ \
+ MACRO(Implements, "reserved word 'implements'") \
+ RANGE(StrictReservedKeywordFirst, Implements) \
+ MACRO(Interface, "reserved word 'interface'") \
+ MACRO(Package, "reserved word 'package'") \
+ MACRO(Private, "reserved word 'private'") \
+ MACRO(Protected, "reserved word 'protected'") \
+ MACRO(Public, "reserved word 'public'") \
+ RANGE(StrictReservedKeywordLast, Public) \
+ \
+ /* \
+ * The following token types occupy contiguous ranges to enable easy \
+ * range-testing. \
+ */ \
+ /* \
+ * Binary operators. \
+ * This list must be kept in the same order in several places: \
+ * - the binary operators in ParseNode.h \
+ * - the precedence list in Parser.cpp \
+ * - the JSOp code list in BytecodeEmitter.cpp \
+ */ \
+ MACRO(Coalesce, "'\?\?'") /* escapes to avoid trigraphs warning */ \
+ RANGE(BinOpFirst, Coalesce) \
+ MACRO(Or, "'||'") /* logical or */ \
+ MACRO(And, "'&&'") /* logical and */ \
+ MACRO(BitOr, "'|'") /* bitwise-or */ \
+ MACRO(BitXor, "'^'") /* bitwise-xor */ \
+ MACRO(BitAnd, "'&'") /* bitwise-and */ \
+ \
+ /* Equality operation tokens, per TokenKindIsEquality. */ \
+ MACRO(StrictEq, "'==='") \
+ RANGE(EqualityStart, StrictEq) \
+ MACRO(Eq, "'=='") \
+ MACRO(StrictNe, "'!=='") \
+ MACRO(Ne, "'!='") \
+ RANGE(EqualityLast, Ne) \
+ \
+ /* Relational ops, per TokenKindIsRelational. */ \
+ MACRO(Lt, "'<'") \
+ RANGE(RelOpStart, Lt) \
+ MACRO(Le, "'<='") \
+ MACRO(Gt, "'>'") \
+ MACRO(Ge, "'>='") \
+ RANGE(RelOpLast, Ge) \
+ \
+ MACRO(InstanceOf, "keyword 'instanceof'") \
+ RANGE(KeywordBinOpFirst, InstanceOf) \
+ MACRO(In, "keyword 'in'") \
+ MACRO(PrivateIn, "keyword 'in' (private)") \
+ RANGE(KeywordBinOpLast, PrivateIn) \
+ \
+ /* Shift ops, per TokenKindIsShift. */ \
+ MACRO(Lsh, "'<<'") \
+ RANGE(ShiftOpStart, Lsh) \
+ MACRO(Rsh, "'>>'") \
+ MACRO(Ursh, "'>>>'") \
+ RANGE(ShiftOpLast, Ursh) \
+ \
+ MACRO(Add, "'+'") \
+ MACRO(Sub, "'-'") \
+ MACRO(Mul, "'*'") \
+ MACRO(Div, "'/'") \
+ MACRO(Mod, "'%'") \
+ MACRO(Pow, "'**'") \
+ RANGE(BinOpLast, Pow) \
+ \
+ /* Unary operation tokens. */ \
+ MACRO(TypeOf, "keyword 'typeof'") \
+ RANGE(KeywordUnOpFirst, TypeOf) \
+ MACRO(Void, "keyword 'void'") \
+ RANGE(KeywordUnOpLast, Void) \
+ MACRO(Not, "'!'") \
+ MACRO(BitNot, "'~'") \
+ \
+ MACRO(Arrow, "'=>'") /* function arrow */ \
+ \
+ /* Assignment ops, per TokenKindIsAssignment */ \
+ MACRO(Assign, "'='") \
+ RANGE(AssignmentStart, Assign) \
+ MACRO(AddAssign, "'+='") \
+ MACRO(SubAssign, "'-='") \
+ MACRO(CoalesceAssign, "'\?\?='") /* avoid trigraphs warning */ \
+ MACRO(OrAssign, "'||='") \
+ MACRO(AndAssign, "'&&='") \
+ MACRO(BitOrAssign, "'|='") \
+ MACRO(BitXorAssign, "'^='") \
+ MACRO(BitAndAssign, "'&='") \
+ MACRO(LshAssign, "'<<='") \
+ MACRO(RshAssign, "'>>='") \
+ MACRO(UrshAssign, "'>>>='") \
+ MACRO(MulAssign, "'*='") \
+ MACRO(DivAssign, "'/='") \
+ MACRO(ModAssign, "'%='") \
+ MACRO(PowAssign, "'**='") \
+ RANGE(AssignmentLast, PowAssign)
+
+#define TOKEN_KIND_RANGE_EMIT_NONE(name, value)
+#define FOR_EACH_TOKEN_KIND(MACRO) \
+ FOR_EACH_TOKEN_KIND_WITH_RANGE(MACRO, TOKEN_KIND_RANGE_EMIT_NONE)
+
+namespace js {
+namespace frontend {
+
+// Values of this type are used to index into arrays such as isExprEnding[],
+// so the first value must be zero.
+enum class TokenKind : uint8_t {
+#define EMIT_ENUM(name, desc) name,
+#define EMIT_ENUM_RANGE(name, value) name = value,
+ FOR_EACH_TOKEN_KIND_WITH_RANGE(EMIT_ENUM, EMIT_ENUM_RANGE)
+#undef EMIT_ENUM
+#undef EMIT_ENUM_RANGE
+ Limit // domain size
+};
+
+inline bool TokenKindIsBinaryOp(TokenKind tt) {
+ return TokenKind::BinOpFirst <= tt && tt <= TokenKind::BinOpLast;
+}
+
+inline bool TokenKindIsEquality(TokenKind tt) {
+ return TokenKind::EqualityStart <= tt && tt <= TokenKind::EqualityLast;
+}
+
+inline bool TokenKindIsRelational(TokenKind tt) {
+ return TokenKind::RelOpStart <= tt && tt <= TokenKind::RelOpLast;
+}
+
+inline bool TokenKindIsShift(TokenKind tt) {
+ return TokenKind::ShiftOpStart <= tt && tt <= TokenKind::ShiftOpLast;
+}
+
+inline bool TokenKindIsAssignment(TokenKind tt) {
+ return TokenKind::AssignmentStart <= tt && tt <= TokenKind::AssignmentLast;
+}
+
+[[nodiscard]] inline bool TokenKindIsKeyword(TokenKind tt) {
+ return (TokenKind::KeywordFirst <= tt && tt <= TokenKind::KeywordLast) ||
+ (TokenKind::KeywordBinOpFirst <= tt &&
+ tt <= TokenKind::KeywordBinOpLast) ||
+ (TokenKind::KeywordUnOpFirst <= tt &&
+ tt <= TokenKind::KeywordUnOpLast);
+}
+
+[[nodiscard]] inline bool TokenKindIsContextualKeyword(TokenKind tt) {
+ return TokenKind::ContextualKeywordFirst <= tt &&
+ tt <= TokenKind::ContextualKeywordLast;
+}
+
+[[nodiscard]] inline bool TokenKindIsFutureReservedWord(TokenKind tt) {
+ return TokenKind::FutureReservedKeywordFirst <= tt &&
+ tt <= TokenKind::FutureReservedKeywordLast;
+}
+
+[[nodiscard]] inline bool TokenKindIsStrictReservedWord(TokenKind tt) {
+ return TokenKind::StrictReservedKeywordFirst <= tt &&
+ tt <= TokenKind::StrictReservedKeywordLast;
+}
+
+[[nodiscard]] inline bool TokenKindIsReservedWordLiteral(TokenKind tt) {
+ return TokenKind::ReservedWordLiteralFirst <= tt &&
+ tt <= TokenKind::ReservedWordLiteralLast;
+}
+
+[[nodiscard]] inline bool TokenKindIsReservedWord(TokenKind tt) {
+ return TokenKindIsKeyword(tt) || TokenKindIsFutureReservedWord(tt) ||
+ TokenKindIsReservedWordLiteral(tt);
+}
+
+[[nodiscard]] inline bool TokenKindIsPossibleIdentifier(TokenKind tt) {
+ return tt == TokenKind::Name || TokenKindIsContextualKeyword(tt) ||
+ TokenKindIsStrictReservedWord(tt);
+}
+
+[[nodiscard]] inline bool TokenKindIsPossibleIdentifierName(TokenKind tt) {
+ return TokenKindIsPossibleIdentifier(tt) || TokenKindIsReservedWord(tt);
+}
+
+} // namespace frontend
+} // namespace js
+
+#endif /* frontend_TokenKind_h */