1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef frontend_TokenKind_h
8 #define frontend_TokenKind_h
12 #include "js/TypeDecls.h" // IF_RECORD_TUPLE
15 * List of token kinds and their ranges.
17 * The format for each line is:
19 * MACRO(<TOKEN_KIND_NAME>, <DESCRIPTION>)
23 * RANGE(<TOKEN_RANGE_NAME>, <TOKEN_KIND_NAME>)
26 * <TOKEN_KIND_NAME> is a legal C identifier of the token, that will be used in
27 * the JS engine source.
29 * <DESCRIPTION> is a string that describe about the token, and will be used in
32 * <TOKEN_RANGE_NAME> is a legal C identifier of the range that will be used to
33 * JS engine source. It should end with `First` or `Last`. This is used to check
34 * TokenKind by range-testing:
35 * BinOpFirst <= tt && tt <= BinOpLast
37 * Second argument of `RANGE` is the actual value of the <TOKEN_RANGE_NAME>,
38 * should be same as one of <TOKEN_KIND_NAME> in other `MACRO`s.
40 * To use this macro, define two macros for `MACRO` and `RANGE`, and pass them
43 * #define EMIT_TOKEN(name, desc) ...
44 * #define EMIT_RANGE(name, value) ...
45 * FOR_EACH_TOKEN_KIND_WITH_RANGE(EMIT_TOKEN, EMIT_RANGE)
49 * If you don't need range data, use FOR_EACH_TOKEN_KIND instead.
51 * #define EMIT_TOKEN(name, desc) ...
52 * FOR_EACH_TOKEN_KIND(EMIT_TOKEN)
55 * Note that this list does not contain Limit.
57 #define FOR_EACH_TOKEN_KIND_WITH_RANGE(MACRO, RANGE) \
58 MACRO(Eof, "end of script") \
60 /* only returned by peekTokenSameLine() */ \
61 MACRO(Eol, "line terminator") \
65 MACRO(Hook, "'?'") /* conditional */ \
66 MACRO(Colon, "':'") /* conditional */ \
67 MACRO(Inc, "'++'") /* increment */ \
68 MACRO(Dec, "'--'") /* decrement */ \
69 MACRO(Dot, "'.'") /* member operator */ \
70 MACRO(TripleDot, "'...'") /* rest arguments and spread operator */ \
71 MACRO(OptionalChain, "'?.'") \
72 MACRO(LeftBracket, "'['") \
73 IF_RECORD_TUPLE(MACRO(HashBracket, "'#['")) \
74 MACRO(RightBracket, "']'") \
75 MACRO(LeftCurly, "'{'") \
76 IF_RECORD_TUPLE(MACRO(HashCurly, "'#{'")) \
77 MACRO(RightCurly, "'}'") \
78 MACRO(LeftParen, "'('") \
79 MACRO(RightParen, "')'") \
80 MACRO(Name, "identifier") \
81 MACRO(PrivateName, "private identifier") \
82 MACRO(Number, "numeric literal") \
83 MACRO(String, "string literal") \
84 MACRO(BigInt, "bigint literal") \
85 IF_DECORATORS(MACRO(At, "'@'")) \
87 /* start of template literal with substitutions */ \
88 MACRO(TemplateHead, "'${'") \
89 /* template literal without substitutions */ \
90 MACRO(NoSubsTemplate, "template literal") \
92 MACRO(RegExp, "regular expression literal") \
93 MACRO(True, "boolean literal 'true'") \
94 RANGE(ReservedWordLiteralFirst, True) \
95 MACRO(False, "boolean literal 'false'") \
96 MACRO(Null, "null literal") \
97 RANGE(ReservedWordLiteralLast, Null) \
98 MACRO(This, "keyword 'this'") \
99 RANGE(KeywordFirst, This) \
100 MACRO(Function, "keyword 'function'") \
101 MACRO(If, "keyword 'if'") \
102 MACRO(Else, "keyword 'else'") \
103 MACRO(Switch, "keyword 'switch'") \
104 MACRO(Case, "keyword 'case'") \
105 MACRO(Default, "keyword 'default'") \
106 MACRO(While, "keyword 'while'") \
107 MACRO(Do, "keyword 'do'") \
108 MACRO(For, "keyword 'for'") \
109 MACRO(Break, "keyword 'break'") \
110 MACRO(Continue, "keyword 'continue'") \
111 MACRO(Var, "keyword 'var'") \
112 MACRO(Const, "keyword 'const'") \
113 MACRO(With, "keyword 'with'") \
114 MACRO(Return, "keyword 'return'") \
115 MACRO(New, "keyword 'new'") \
116 MACRO(Delete, "keyword 'delete'") \
117 MACRO(Try, "keyword 'try'") \
118 MACRO(Catch, "keyword 'catch'") \
119 MACRO(Finally, "keyword 'finally'") \
120 MACRO(Throw, "keyword 'throw'") \
121 MACRO(Debugger, "keyword 'debugger'") \
122 MACRO(Export, "keyword 'export'") \
123 MACRO(Import, "keyword 'import'") \
124 MACRO(Class, "keyword 'class'") \
125 MACRO(Extends, "keyword 'extends'") \
126 MACRO(Super, "keyword 'super'") \
127 RANGE(KeywordLast, Super) \
129 /* contextual keywords */ \
131 RANGE(ContextualKeywordFirst, As) \
132 /* TODO: Move to alphabetical order when IF_DECORATORS is removed */ \
133 IF_DECORATORS(MACRO(Accessor, "'accessor'")) \
134 MACRO(Assert, "'assert'") \
135 MACRO(Async, "'async'") \
136 MACRO(Await, "'await'") \
137 MACRO(Each, "'each'") \
138 MACRO(From, "'from'") \
139 MACRO(Get, "'get'") \
140 MACRO(Let, "'let'") \
141 MACRO(Meta, "'meta'") \
143 MACRO(Set, "'set'") \
144 MACRO(Static, "'static'") \
145 MACRO(Target, "'target'") \
146 MACRO(Yield, "'yield'") \
147 RANGE(ContextualKeywordLast, Yield) \
149 /* future reserved words */ \
150 MACRO(Enum, "reserved word 'enum'") \
151 RANGE(FutureReservedKeywordFirst, Enum) \
152 RANGE(FutureReservedKeywordLast, Enum) \
154 /* reserved words in strict mode */ \
155 MACRO(Implements, "reserved word 'implements'") \
156 RANGE(StrictReservedKeywordFirst, Implements) \
157 MACRO(Interface, "reserved word 'interface'") \
158 MACRO(Package, "reserved word 'package'") \
159 MACRO(Private, "reserved word 'private'") \
160 MACRO(Protected, "reserved word 'protected'") \
161 MACRO(Public, "reserved word 'public'") \
162 RANGE(StrictReservedKeywordLast, Public) \
165 * The following token types occupy contiguous ranges to enable easy \
169 * Binary operators. \
170 * This list must be kept in the same order in several places: \
171 * - the binary operators in ParseNode.h \
172 * - the precedence list in Parser.cpp \
173 * - the JSOp code list in BytecodeEmitter.cpp \
175 MACRO(Coalesce, "'\?\?'") /* escapes to avoid trigraphs warning */ \
176 RANGE(BinOpFirst, Coalesce) \
177 MACRO(Or, "'||'") /* logical or */ \
178 MACRO(And, "'&&'") /* logical and */ \
179 MACRO(BitOr, "'|'") /* bitwise-or */ \
180 MACRO(BitXor, "'^'") /* bitwise-xor */ \
181 MACRO(BitAnd, "'&'") /* bitwise-and */ \
183 /* Equality operation tokens, per TokenKindIsEquality. */ \
184 MACRO(StrictEq, "'==='") \
185 RANGE(EqualityStart, StrictEq) \
187 MACRO(StrictNe, "'!=='") \
189 RANGE(EqualityLast, Ne) \
191 /* Relational ops, per TokenKindIsRelational. */ \
193 RANGE(RelOpStart, Lt) \
197 RANGE(RelOpLast, Ge) \
199 MACRO(InstanceOf, "keyword 'instanceof'") \
200 RANGE(KeywordBinOpFirst, InstanceOf) \
201 MACRO(In, "keyword 'in'") \
202 MACRO(PrivateIn, "keyword 'in' (private)") \
203 RANGE(KeywordBinOpLast, PrivateIn) \
205 /* Shift ops, per TokenKindIsShift. */ \
207 RANGE(ShiftOpStart, Lsh) \
209 MACRO(Ursh, "'>>>'") \
210 RANGE(ShiftOpLast, Ursh) \
218 RANGE(BinOpLast, Pow) \
220 /* Unary operation tokens. */ \
221 MACRO(TypeOf, "keyword 'typeof'") \
222 RANGE(KeywordUnOpFirst, TypeOf) \
223 MACRO(Void, "keyword 'void'") \
224 RANGE(KeywordUnOpLast, Void) \
226 MACRO(BitNot, "'~'") \
228 MACRO(Arrow, "'=>'") /* function arrow */ \
230 /* Assignment ops, per TokenKindIsAssignment */ \
231 MACRO(Assign, "'='") \
232 RANGE(AssignmentStart, Assign) \
233 MACRO(AddAssign, "'+='") \
234 MACRO(SubAssign, "'-='") \
235 MACRO(CoalesceAssign, "'\?\?='") /* avoid trigraphs warning */ \
236 MACRO(OrAssign, "'||='") \
237 MACRO(AndAssign, "'&&='") \
238 MACRO(BitOrAssign, "'|='") \
239 MACRO(BitXorAssign, "'^='") \
240 MACRO(BitAndAssign, "'&='") \
241 MACRO(LshAssign, "'<<='") \
242 MACRO(RshAssign, "'>>='") \
243 MACRO(UrshAssign, "'>>>='") \
244 MACRO(MulAssign, "'*='") \
245 MACRO(DivAssign, "'/='") \
246 MACRO(ModAssign, "'%='") \
247 MACRO(PowAssign, "'**='") \
248 RANGE(AssignmentLast, PowAssign)
250 #define TOKEN_KIND_RANGE_EMIT_NONE(name, value)
251 #define FOR_EACH_TOKEN_KIND(MACRO) \
252 FOR_EACH_TOKEN_KIND_WITH_RANGE(MACRO, TOKEN_KIND_RANGE_EMIT_NONE)
257 // Values of this type are used to index into arrays such as isExprEnding[],
258 // so the first value must be zero.
259 enum class TokenKind
: uint8_t {
260 #define EMIT_ENUM(name, desc) name,
261 #define EMIT_ENUM_RANGE(name, value) name = value,
262 FOR_EACH_TOKEN_KIND_WITH_RANGE(EMIT_ENUM
, EMIT_ENUM_RANGE
)
264 #undef EMIT_ENUM_RANGE
268 inline bool TokenKindIsBinaryOp(TokenKind tt
) {
269 return TokenKind::BinOpFirst
<= tt
&& tt
<= TokenKind::BinOpLast
;
272 inline bool TokenKindIsEquality(TokenKind tt
) {
273 return TokenKind::EqualityStart
<= tt
&& tt
<= TokenKind::EqualityLast
;
276 inline bool TokenKindIsRelational(TokenKind tt
) {
277 return TokenKind::RelOpStart
<= tt
&& tt
<= TokenKind::RelOpLast
;
280 inline bool TokenKindIsShift(TokenKind tt
) {
281 return TokenKind::ShiftOpStart
<= tt
&& tt
<= TokenKind::ShiftOpLast
;
284 inline bool TokenKindIsAssignment(TokenKind tt
) {
285 return TokenKind::AssignmentStart
<= tt
&& tt
<= TokenKind::AssignmentLast
;
288 [[nodiscard
]] inline bool TokenKindIsKeyword(TokenKind tt
) {
289 return (TokenKind::KeywordFirst
<= tt
&& tt
<= TokenKind::KeywordLast
) ||
290 (TokenKind::KeywordBinOpFirst
<= tt
&&
291 tt
<= TokenKind::KeywordBinOpLast
) ||
292 (TokenKind::KeywordUnOpFirst
<= tt
&&
293 tt
<= TokenKind::KeywordUnOpLast
);
296 [[nodiscard
]] inline bool TokenKindIsContextualKeyword(TokenKind tt
) {
297 return TokenKind::ContextualKeywordFirst
<= tt
&&
298 tt
<= TokenKind::ContextualKeywordLast
;
301 [[nodiscard
]] inline bool TokenKindIsFutureReservedWord(TokenKind tt
) {
302 return TokenKind::FutureReservedKeywordFirst
<= tt
&&
303 tt
<= TokenKind::FutureReservedKeywordLast
;
306 [[nodiscard
]] inline bool TokenKindIsStrictReservedWord(TokenKind tt
) {
307 return TokenKind::StrictReservedKeywordFirst
<= tt
&&
308 tt
<= TokenKind::StrictReservedKeywordLast
;
311 [[nodiscard
]] inline bool TokenKindIsReservedWordLiteral(TokenKind tt
) {
312 return TokenKind::ReservedWordLiteralFirst
<= tt
&&
313 tt
<= TokenKind::ReservedWordLiteralLast
;
316 [[nodiscard
]] inline bool TokenKindIsReservedWord(TokenKind tt
) {
317 return TokenKindIsKeyword(tt
) || TokenKindIsFutureReservedWord(tt
) ||
318 TokenKindIsReservedWordLiteral(tt
);
321 [[nodiscard
]] inline bool TokenKindIsPossibleIdentifier(TokenKind tt
) {
322 return tt
== TokenKind::Name
|| TokenKindIsContextualKeyword(tt
) ||
323 TokenKindIsStrictReservedWord(tt
);
326 [[nodiscard
]] inline bool TokenKindIsPossibleIdentifierName(TokenKind tt
) {
327 return TokenKindIsPossibleIdentifier(tt
) || TokenKindIsReservedWord(tt
);
330 } // namespace frontend
333 #endif /* frontend_TokenKind_h */