Line data Source code
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, with `TOK_` prefix.
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, with `TOK_` prefix. It should end with `_FIRST` or `_LAST`.
30 : * This is used to check TokenKind by range-testing:
31 : * TOK_BINOP_FIRST <= tt && tt <= TOK_BINOP_LAST
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(TEMPLATE_HEAD, "'${'") \
79 : /* template literal without substitutions */ \
80 : macro(NO_SUBS_TEMPLATE, "template literal") \
81 : \
82 : macro(REGEXP, "regular expression literal") \
83 : macro(TRUE, "boolean literal 'true'") \
84 : range(RESERVED_WORD_LITERAL_FIRST, TRUE) \
85 : macro(FALSE, "boolean literal 'false'") \
86 : macro(NULL, "null literal") \
87 : range(RESERVED_WORD_LITERAL_LAST, NULL) \
88 : macro(THIS, "keyword 'this'") \
89 : range(KEYWORD_FIRST, 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(KEYWORD_LAST, SUPER) \
118 : \
119 : /* contextual keywords */ \
120 : macro(AS, "'as'") \
121 : range(CONTEXTUAL_KEYWORD_FIRST, 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(CONTEXTUAL_KEYWORD_LAST, YIELD) \
134 : \
135 : /* future reserved words */ \
136 : macro(ENUM, "reserved word 'enum'") \
137 : range(FUTURE_RESERVED_KEYWORD_FIRST, ENUM) \
138 : range(FUTURE_RESERVED_KEYWORD_LAST, ENUM) \
139 : \
140 : /* reserved words in strict mode */ \
141 : macro(IMPLEMENTS, "reserved word 'implements'") \
142 : range(STRICT_RESERVED_KEYWORD_FIRST, 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(STRICT_RESERVED_KEYWORD_LAST, PUBLIC) \
149 : \
150 : /* \
151 : * The following token types occupy contiguous ranges to enable easy \
152 : * range-testing. \
153 : */ \
154 : /* \
155 : * Binary operators tokens, TOK_OR thru TOK_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(OR, "'||'") /* logical or */ \
159 : range(BINOP_FIRST, OR) \
160 : macro(AND, "'&&'") /* logical and */ \
161 : macro(BITOR, "'|'") /* bitwise-or */ \
162 : macro(BITXOR, "'^'") /* bitwise-xor */ \
163 : macro(BITAND, "'&'") /* bitwise-and */ \
164 : \
165 : /* Equality operation tokens, per TokenKindIsEquality. */ \
166 : macro(STRICTEQ, "'==='") \
167 : range(EQUALITY_START, STRICTEQ) \
168 : macro(EQ, "'=='") \
169 : macro(STRICTNE, "'!=='") \
170 : macro(NE, "'!='") \
171 : range(EQUALITY_LAST, NE) \
172 : \
173 : /* Relational ops, per TokenKindIsRelational. */ \
174 : macro(LT, "'<'") \
175 : range(RELOP_START, LT) \
176 : macro(LE, "'<='") \
177 : macro(GT, "'>'") \
178 : macro(GE, "'>='") \
179 : range(RELOP_LAST, GE) \
180 : \
181 : macro(INSTANCEOF, "keyword 'instanceof'") \
182 : range(KEYWORD_BINOP_FIRST, INSTANCEOF) \
183 : macro(IN, "keyword 'in'") \
184 : range(KEYWORD_BINOP_LAST, IN) \
185 : \
186 : /* Shift ops, per TokenKindIsShift. */ \
187 : macro(LSH, "'<<'") \
188 : range(SHIFTOP_START, LSH) \
189 : macro(RSH, "'>>'") \
190 : macro(URSH, "'>>>'") \
191 : range(SHIFTOP_LAST, URSH) \
192 : \
193 : macro(ADD, "'+'") \
194 : macro(SUB, "'-'") \
195 : macro(MUL, "'*'") \
196 : macro(DIV, "'/'") \
197 : macro(MOD, "'%'") \
198 : macro(POW, "'**'") \
199 : range(BINOP_LAST, POW) \
200 : \
201 : /* Unary operation tokens. */ \
202 : macro(TYPEOF, "keyword 'typeof'") \
203 : range(KEYWORD_UNOP_FIRST, TYPEOF) \
204 : macro(VOID, "keyword 'void'") \
205 : range(KEYWORD_UNOP_LAST, VOID) \
206 : macro(NOT, "'!'") \
207 : macro(BITNOT, "'~'") \
208 : \
209 : macro(ARROW, "'=>'") /* function arrow */ \
210 : \
211 : /* Assignment ops, per TokenKindIsAssignment */ \
212 : macro(ASSIGN, "'='") \
213 : range(ASSIGNMENT_START, ASSIGN) \
214 : macro(ADDASSIGN, "'+='") \
215 : macro(SUBASSIGN, "'-='") \
216 : macro(BITORASSIGN, "'|='") \
217 : macro(BITXORASSIGN, "'^='") \
218 : macro(BITANDASSIGN, "'&='") \
219 : macro(LSHASSIGN, "'<<='") \
220 : macro(RSHASSIGN, "'>>='") \
221 : macro(URSHASSIGN, "'>>>='") \
222 : macro(MULASSIGN, "'*='") \
223 : macro(DIVASSIGN, "'/='") \
224 : macro(MODASSIGN, "'%='") \
225 : macro(POWASSIGN, "'**='") \
226 : range(ASSIGNMENT_LAST, POWASSIGN)
227 :
228 : #define TOKEN_KIND_RANGE_EMIT_NONE(name, value)
229 : #define FOR_EACH_TOKEN_KIND(macro) \
230 : FOR_EACH_TOKEN_KIND_WITH_RANGE(macro, TOKEN_KIND_RANGE_EMIT_NONE)
231 :
232 : namespace js {
233 : namespace frontend {
234 :
235 : // Values of this type are used to index into arrays such as isExprEnding[],
236 : // so the first value must be zero.
237 : enum TokenKind {
238 : #define EMIT_ENUM(name, desc) TOK_##name,
239 : #define EMIT_ENUM_RANGE(name, value) TOK_##name = TOK_##value,
240 : FOR_EACH_TOKEN_KIND_WITH_RANGE(EMIT_ENUM, EMIT_ENUM_RANGE)
241 : #undef EMIT_ENUM
242 : #undef EMIT_ENUM_RANGE
243 : TOK_LIMIT // domain size
244 : };
245 :
246 : inline bool
247 104598 : TokenKindIsBinaryOp(TokenKind tt)
248 : {
249 104598 : return TOK_BINOP_FIRST <= tt && tt <= TOK_BINOP_LAST;
250 : }
251 :
252 : inline bool
253 : TokenKindIsEquality(TokenKind tt)
254 : {
255 : return TOK_EQUALITY_START <= tt && tt <= TOK_EQUALITY_LAST;
256 : }
257 :
258 : inline bool
259 : TokenKindIsRelational(TokenKind tt)
260 : {
261 : return TOK_RELOP_START <= tt && tt <= TOK_RELOP_LAST;
262 : }
263 :
264 : inline bool
265 : TokenKindIsShift(TokenKind tt)
266 : {
267 : return TOK_SHIFTOP_START <= tt && tt <= TOK_SHIFTOP_LAST;
268 : }
269 :
270 : inline bool
271 63920 : TokenKindIsAssignment(TokenKind tt)
272 : {
273 63920 : return TOK_ASSIGNMENT_START <= tt && tt <= TOK_ASSIGNMENT_LAST;
274 : }
275 :
276 : inline MOZ_MUST_USE bool
277 1424 : TokenKindIsKeyword(TokenKind tt)
278 : {
279 2848 : return (TOK_KEYWORD_FIRST <= tt && tt <= TOK_KEYWORD_LAST) ||
280 2951 : (TOK_KEYWORD_BINOP_FIRST <= tt && tt <= TOK_KEYWORD_BINOP_LAST) ||
281 1527 : (TOK_KEYWORD_UNOP_FIRST <= tt && tt <= TOK_KEYWORD_UNOP_LAST);
282 : }
283 :
284 : inline MOZ_MUST_USE bool
285 17908 : TokenKindIsContextualKeyword(TokenKind tt)
286 : {
287 17908 : return TOK_CONTEXTUAL_KEYWORD_FIRST <= tt && tt <= TOK_CONTEXTUAL_KEYWORD_LAST;
288 : }
289 :
290 : inline MOZ_MUST_USE bool
291 103 : TokenKindIsFutureReservedWord(TokenKind tt)
292 : {
293 103 : return TOK_FUTURE_RESERVED_KEYWORD_FIRST <= tt && tt <= TOK_FUTURE_RESERVED_KEYWORD_LAST;
294 : }
295 :
296 : inline MOZ_MUST_USE bool
297 7953 : TokenKindIsStrictReservedWord(TokenKind tt)
298 : {
299 7953 : return TOK_STRICT_RESERVED_KEYWORD_FIRST <= tt && tt <= TOK_STRICT_RESERVED_KEYWORD_LAST;
300 : }
301 :
302 : inline MOZ_MUST_USE bool
303 103 : TokenKindIsReservedWordLiteral(TokenKind tt)
304 : {
305 103 : return TOK_RESERVED_WORD_LITERAL_FIRST <= tt && tt <= TOK_RESERVED_WORD_LITERAL_LAST;
306 : }
307 :
308 : inline MOZ_MUST_USE bool
309 1424 : TokenKindIsReservedWord(TokenKind tt)
310 : {
311 1527 : return TokenKindIsKeyword(tt) ||
312 1527 : TokenKindIsFutureReservedWord(tt) ||
313 1527 : TokenKindIsReservedWordLiteral(tt);
314 : }
315 :
316 : inline MOZ_MUST_USE bool
317 164751 : TokenKindIsPossibleIdentifier(TokenKind tt)
318 : {
319 17252 : return tt == TOK_NAME ||
320 172704 : TokenKindIsContextualKeyword(tt) ||
321 172704 : TokenKindIsStrictReservedWord(tt);
322 : }
323 :
324 : inline MOZ_MUST_USE bool
325 57184 : TokenKindIsPossibleIdentifierName(TokenKind tt)
326 : {
327 58608 : return TokenKindIsPossibleIdentifier(tt) ||
328 58608 : TokenKindIsReservedWord(tt);
329 : }
330 :
331 : } // namespace frontend
332 : } // namespace js
333 :
334 : #endif /* frontend_TokenKind_h */
|