1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * vim: set ts=8 sts=4 et sw=4 tw=99:
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/. */
6 
7 #ifndef frontend_TokenKind_h
8 #define frontend_TokenKind_h
9 
10 /*
11  * List of token kinds and their ranges.
12  *
13  * The format for each line is:
14  *
15  *   MACRO(<TOKEN_KIND_NAME>, <DESCRIPTION>)
16  *
17  * or
18  *
19  *   RANGE(<TOKEN_RANGE_NAME>, <TOKEN_KIND_NAME>)
20  *
21  * where ;
22  * <TOKEN_KIND_NAME> is a legal C identifier of the token, that will be used in
23  * the JS engine source.
24  *
25  * <DESCRIPTION> is a string that describe about the token, and will be used in
26  * error message.
27  *
28  * <TOKEN_RANGE_NAME> is a legal C identifier of the range that will be used to
29  * JS engine source. It should end with `First` or `Last`. This is used to check
30  * TokenKind by range-testing:
31  *   BinOpFirst <= tt && tt <= BinOpLast
32  *
33  * Second argument of `RANGE` is the actual value of the <TOKEN_RANGE_NAME>,
34  * should be same as one of <TOKEN_KIND_NAME> in other `MACRO`s.
35  *
36  * To use this macro, define two macros for `MACRO` and `RANGE`, and pass them
37  * as arguments.
38  *
39  *   #define EMIT_TOKEN(name, desc) ...
40  *   #define EMIT_RANGE(name, value) ...
41  *   FOR_EACH_TOKEN_KIND_WITH_RANGE(EMIT_TOKEN, EMIT_RANGE)
42  *   #undef EMIT_TOKEN
43  *   #undef EMIT_RANGE
44  *
45  * If you don't need range data, use FOR_EACH_TOKEN_KIND instead.
46  *
47  *   #define EMIT_TOKEN(name, desc) ...
48  *   FOR_EACH_TOKEN_KIND(EMIT_TOKEN)
49  *   #undef EMIT_TOKEN
50  *
51  * Note that this list does not contain ERROR and LIMIT.
52  */
53 #define FOR_EACH_TOKEN_KIND_WITH_RANGE(MACRO, RANGE)                        \
54   MACRO(Eof, "end of script")                                               \
55                                                                             \
56   /* only returned by peekTokenSameLine() */                                \
57   MACRO(Eol, "line terminator")                                             \
58                                                                             \
59   MACRO(Semi, "';'")                                                        \
60   MACRO(Comma, "','")                                                       \
61   MACRO(Hook, "'?'")        /* conditional */                               \
62   MACRO(Colon, "':'")       /* conditional */                               \
63   MACRO(Inc, "'++'")        /* increment */                                 \
64   MACRO(Dec, "'--'")        /* decrement */                                 \
65   MACRO(Dot, "'.'")         /* member operator */                           \
66   MACRO(TripleDot, "'...'") /* rest arguments and spread operator */        \
67   MACRO(Lb, "'['")                                                          \
68   MACRO(Rb, "']'")                                                          \
69   MACRO(Lc, "'{'")                                                          \
70   MACRO(Rc, "'}'")                                                          \
71   MACRO(Lp, "'('")                                                          \
72   MACRO(Rp, "')'")                                                          \
73   MACRO(Name, "identifier")                                                 \
74   MACRO(Number, "numeric literal")                                          \
75   MACRO(String, "string literal")                                           \
76                                                                             \
77   /* start of template literal with substitutions */                        \
78   MACRO(TemplateHead, "'${'")                                               \
79   /* template literal without substitutions */                              \
80   MACRO(NoSubsTemplate, "template literal")                                 \
81                                                                             \
82   MACRO(RegExp, "regular expression literal")                               \
83   MACRO(True, "boolean literal 'true'")                                     \
84   RANGE(ReservedWordLiteralFirst, True)                                     \
85   MACRO(False, "boolean literal 'false'")                                   \
86   MACRO(Null, "null literal")                                               \
87   RANGE(ReservedWordLiteralLast, Null)                                      \
88   MACRO(This, "keyword 'this'")                                             \
89   RANGE(KeywordFirst, This)                                                 \
90   MACRO(Function, "keyword 'function'")                                     \
91   MACRO(If, "keyword 'if'")                                                 \
92   MACRO(Else, "keyword 'else'")                                             \
93   MACRO(Switch, "keyword 'switch'")                                         \
94   MACRO(Case, "keyword 'case'")                                             \
95   MACRO(Default, "keyword 'default'")                                       \
96   MACRO(While, "keyword 'while'")                                           \
97   MACRO(Do, "keyword 'do'")                                                 \
98   MACRO(For, "keyword 'for'")                                               \
99   MACRO(Break, "keyword 'break'")                                           \
100   MACRO(Continue, "keyword 'continue'")                                     \
101   MACRO(Var, "keyword 'var'")                                               \
102   MACRO(Const, "keyword 'const'")                                           \
103   MACRO(With, "keyword 'with'")                                             \
104   MACRO(Return, "keyword 'return'")                                         \
105   MACRO(New, "keyword 'new'")                                               \
106   MACRO(Delete, "keyword 'delete'")                                         \
107   MACRO(Try, "keyword 'try'")                                               \
108   MACRO(Catch, "keyword 'catch'")                                           \
109   MACRO(Finally, "keyword 'finally'")                                       \
110   MACRO(Throw, "keyword 'throw'")                                           \
111   MACRO(Debugger, "keyword 'debugger'")                                     \
112   MACRO(Export, "keyword 'export'")                                         \
113   MACRO(Import, "keyword 'import'")                                         \
114   MACRO(Class, "keyword 'class'")                                           \
115   MACRO(Extends, "keyword 'extends'")                                       \
116   MACRO(Super, "keyword 'super'")                                           \
117   RANGE(KeywordLast, Super)                                                 \
118                                                                             \
119   /* contextual keywords */                                                 \
120   MACRO(As, "'as'")                                                         \
121   RANGE(ContextualKeywordFirst, As)                                         \
122   MACRO(Async, "'async'")                                                   \
123   MACRO(Await, "'await'")                                                   \
124   MACRO(Each, "'each'")                                                     \
125   MACRO(From, "'from'")                                                     \
126   MACRO(Get, "'get'")                                                       \
127   MACRO(Let, "'let'")                                                       \
128   MACRO(Of, "'of'")                                                         \
129   MACRO(Set, "'set'")                                                       \
130   MACRO(Static, "'static'")                                                 \
131   MACRO(Target, "'target'")                                                 \
132   MACRO(Yield, "'yield'")                                                   \
133   RANGE(ContextualKeywordLast, Yield)                                       \
134                                                                             \
135   /* future reserved words */                                               \
136   MACRO(Enum, "reserved word 'enum'")                                       \
137   RANGE(FutureReservedKeywordFirst, Enum)                                   \
138   RANGE(FutureReservedKeywordLast, Enum)                                    \
139                                                                             \
140   /* reserved words in strict mode */                                       \
141   MACRO(Implements, "reserved word 'implements'")                           \
142   RANGE(StrictReservedKeywordFirst, Implements)                             \
143   MACRO(Interface, "reserved word 'interface'")                             \
144   MACRO(Package, "reserved word 'package'")                                 \
145   MACRO(Private, "reserved word 'private'")                                 \
146   MACRO(Protected, "reserved word 'protected'")                             \
147   MACRO(Public, "reserved word 'public'")                                   \
148   RANGE(StrictReservedKeywordLast, Public)                                  \
149                                                                             \
150   /*                                                                        \
151    * The following token types occupy contiguous ranges to enable easy      \
152    * range-testing.                                                         \
153    */                                                                       \
154   /*                                                                        \
155    * Binary operators tokens, Or thru Pow. These must be in the same        \
156    * order as F(OR) and friends in FOR_EACH_PARSE_NODE_KIND in ParseNode.h. \
157    */                                                                       \
158   MACRO(Pipeline, "'|>'")                                                   \
159   RANGE(BinOpFirst, Pipeline)                                               \
160   MACRO(Or, "'||'")    /* logical or */                                     \
161   MACRO(And, "'&&'")   /* logical and */                                    \
162   MACRO(BitOr, "'|'")  /* bitwise-or */                                     \
163   MACRO(BitXor, "'^'") /* bitwise-xor */                                    \
164   MACRO(BitAnd, "'&'") /* bitwise-and */                                    \
165                                                                             \
166   /* Equality operation tokens, per TokenKindIsEquality. */                 \
167   MACRO(StrictEq, "'==='")                                                  \
168   RANGE(EqualityStart, StrictEq)                                            \
169   MACRO(Eq, "'=='")                                                         \
170   MACRO(StrictNe, "'!=='")                                                  \
171   MACRO(Ne, "'!='")                                                         \
172   RANGE(EqualityLast, Ne)                                                   \
173                                                                             \
174   /* Relational ops, per TokenKindIsRelational. */                          \
175   MACRO(Lt, "'<'")                                                          \
176   RANGE(RelOpStart, Lt)                                                     \
177   MACRO(Le, "'<='")                                                         \
178   MACRO(Gt, "'>'")                                                          \
179   MACRO(Ge, "'>='")                                                         \
180   RANGE(RelOpLast, Ge)                                                      \
181                                                                             \
182   MACRO(InstanceOf, "keyword 'instanceof'")                                 \
183   RANGE(KeywordBinOpFirst, InstanceOf)                                      \
184   MACRO(In, "keyword 'in'")                                                 \
185   RANGE(KeywordBinOpLast, In)                                               \
186                                                                             \
187   /* Shift ops, per TokenKindIsShift. */                                    \
188   MACRO(Lsh, "'<<'")                                                        \
189   RANGE(ShiftOpStart, Lsh)                                                  \
190   MACRO(Rsh, "'>>'")                                                        \
191   MACRO(Ursh, "'>>>'")                                                      \
192   RANGE(ShiftOpLast, Ursh)                                                  \
193                                                                             \
194   MACRO(Add, "'+'")                                                         \
195   MACRO(Sub, "'-'")                                                         \
196   MACRO(Mul, "'*'")                                                         \
197   MACRO(Div, "'/'")                                                         \
198   MACRO(Mod, "'%'")                                                         \
199   MACRO(Pow, "'**'")                                                        \
200   RANGE(BinOpLast, Pow)                                                     \
201                                                                             \
202   /* Unary operation tokens. */                                             \
203   MACRO(TypeOf, "keyword 'typeof'")                                         \
204   RANGE(KeywordUnOpFirst, TypeOf)                                           \
205   MACRO(Void, "keyword 'void'")                                             \
206   RANGE(KeywordUnOpLast, Void)                                              \
207   MACRO(Not, "'!'")                                                         \
208   MACRO(BitNot, "'~'")                                                      \
209                                                                             \
210   MACRO(Arrow, "'=>'") /* function arrow */                                 \
211                                                                             \
212   /* Assignment ops, per TokenKindIsAssignment */                           \
213   MACRO(Assign, "'='")                                                      \
214   RANGE(AssignmentStart, Assign)                                            \
215   MACRO(AddAssign, "'+='")                                                  \
216   MACRO(SubAssign, "'-='")                                                  \
217   MACRO(BitOrAssign, "'|='")                                                \
218   MACRO(BitXorAssign, "'^='")                                               \
219   MACRO(BitAndAssign, "'&='")                                               \
220   MACRO(LshAssign, "'<<='")                                                 \
221   MACRO(RshAssign, "'>>='")                                                 \
222   MACRO(UrshAssign, "'>>>='")                                               \
223   MACRO(MulAssign, "'*='")                                                  \
224   MACRO(DivAssign, "'/='")                                                  \
225   MACRO(ModAssign, "'%='")                                                  \
226   MACRO(PowAssign, "'**='")                                                 \
227   RANGE(AssignmentLast, PowAssign)
228 
229 #define TOKEN_KIND_RANGE_EMIT_NONE(name, value)
230 #define FOR_EACH_TOKEN_KIND(MACRO) \
231   FOR_EACH_TOKEN_KIND_WITH_RANGE(MACRO, TOKEN_KIND_RANGE_EMIT_NONE)
232 
233 namespace js {
234 namespace frontend {
235 
236 // Values of this type are used to index into arrays such as isExprEnding[],
237 // so the first value must be zero.
238 enum class TokenKind {
239 #define EMIT_ENUM(name, desc) name,
240 #define EMIT_ENUM_RANGE(name, value) name = value,
241   FOR_EACH_TOKEN_KIND_WITH_RANGE(EMIT_ENUM, EMIT_ENUM_RANGE)
242 #undef EMIT_ENUM
243 #undef EMIT_ENUM_RANGE
244       Limit  // domain size
245 };
246 
TokenKindIsBinaryOp(TokenKind tt)247 inline bool TokenKindIsBinaryOp(TokenKind tt) {
248   return TokenKind::BinOpFirst <= tt && tt <= TokenKind::BinOpLast;
249 }
250 
TokenKindIsEquality(TokenKind tt)251 inline bool TokenKindIsEquality(TokenKind tt) {
252   return TokenKind::EqualityStart <= tt && tt <= TokenKind::EqualityLast;
253 }
254 
TokenKindIsRelational(TokenKind tt)255 inline bool TokenKindIsRelational(TokenKind tt) {
256   return TokenKind::RelOpStart <= tt && tt <= TokenKind::RelOpLast;
257 }
258 
TokenKindIsShift(TokenKind tt)259 inline bool TokenKindIsShift(TokenKind tt) {
260   return TokenKind::ShiftOpStart <= tt && tt <= TokenKind::ShiftOpLast;
261 }
262 
TokenKindIsAssignment(TokenKind tt)263 inline bool TokenKindIsAssignment(TokenKind tt) {
264   return TokenKind::AssignmentStart <= tt && tt <= TokenKind::AssignmentLast;
265 }
266 
TokenKindIsKeyword(TokenKind tt)267 inline MOZ_MUST_USE bool TokenKindIsKeyword(TokenKind tt) {
268   return (TokenKind::KeywordFirst <= tt && tt <= TokenKind::KeywordLast) ||
269          (TokenKind::KeywordBinOpFirst <= tt &&
270           tt <= TokenKind::KeywordBinOpLast) ||
271          (TokenKind::KeywordUnOpFirst <= tt &&
272           tt <= TokenKind::KeywordUnOpLast);
273 }
274 
TokenKindIsContextualKeyword(TokenKind tt)275 inline MOZ_MUST_USE bool TokenKindIsContextualKeyword(TokenKind tt) {
276   return TokenKind::ContextualKeywordFirst <= tt &&
277          tt <= TokenKind::ContextualKeywordLast;
278 }
279 
TokenKindIsFutureReservedWord(TokenKind tt)280 inline MOZ_MUST_USE bool TokenKindIsFutureReservedWord(TokenKind tt) {
281   return TokenKind::FutureReservedKeywordFirst <= tt &&
282          tt <= TokenKind::FutureReservedKeywordLast;
283 }
284 
TokenKindIsStrictReservedWord(TokenKind tt)285 inline MOZ_MUST_USE bool TokenKindIsStrictReservedWord(TokenKind tt) {
286   return TokenKind::StrictReservedKeywordFirst <= tt &&
287          tt <= TokenKind::StrictReservedKeywordLast;
288 }
289 
TokenKindIsReservedWordLiteral(TokenKind tt)290 inline MOZ_MUST_USE bool TokenKindIsReservedWordLiteral(TokenKind tt) {
291   return TokenKind::ReservedWordLiteralFirst <= tt &&
292          tt <= TokenKind::ReservedWordLiteralLast;
293 }
294 
TokenKindIsReservedWord(TokenKind tt)295 inline MOZ_MUST_USE bool TokenKindIsReservedWord(TokenKind tt) {
296   return TokenKindIsKeyword(tt) || TokenKindIsFutureReservedWord(tt) ||
297          TokenKindIsReservedWordLiteral(tt);
298 }
299 
TokenKindIsPossibleIdentifier(TokenKind tt)300 inline MOZ_MUST_USE bool TokenKindIsPossibleIdentifier(TokenKind tt) {
301   return tt == TokenKind::Name || TokenKindIsContextualKeyword(tt) ||
302          TokenKindIsStrictReservedWord(tt);
303 }
304 
TokenKindIsPossibleIdentifierName(TokenKind tt)305 inline MOZ_MUST_USE bool TokenKindIsPossibleIdentifierName(TokenKind tt) {
306   return TokenKindIsPossibleIdentifier(tt) || TokenKindIsReservedWord(tt);
307 }
308 
309 }  // namespace frontend
310 }  // namespace js
311 
312 #endif /* frontend_TokenKind_h */
313