Flutter Engine
The Flutter Engine
token.h
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_TOKEN_H_
6#define RUNTIME_VM_TOKEN_H_
7
8#include "platform/assert.h"
9#include "vm/allocation.h"
10
11namespace dart {
12
13// Operator precedence table
14//
15// 14 multiplicative * / ~/ %
16// 13 additive + -
17// 12 shift << >> >>>
18// 11 bitwise and &
19// 10 bitwise xor ^
20// 9 bitwise or |
21// 8 relational >= > <= < is as
22// 7 equality == != === !==
23// 6 logical and &&
24// 5 logical or ||
25// 4 null check ??
26// 3 conditional ?
27// 2 assignment = *= /= ~/= %= += -= <<= >>= >>>= &= ^= |= ??=
28// 1 comma ,
29
30// Token definitions.
31// Some operator tokens appear in blocks, e.g. assignment operators.
32// There is code that depends on the values within a block to be
33// contiguous, and on the order of values.
34#define DART_TOKEN_LIST(TOK) \
35 TOK(kEOS, "", 0, kNoAttribute) \
36 \
37 TOK(kLPAREN, "(", 0, kNoAttribute) \
38 TOK(kRPAREN, ")", 0, kNoAttribute) \
39 TOK(kLBRACK, "[", 0, kNoAttribute) \
40 TOK(kRBRACK, "]", 0, kNoAttribute) \
41 TOK(kLBRACE, "{", 0, kNoAttribute) \
42 TOK(kRBRACE, "}", 0, kNoAttribute) \
43 TOK(kARROW, "=>", 0, kNoAttribute) \
44 TOK(kCOLON, ":", 0, kNoAttribute) \
45 TOK(kSEMICOLON, ";", 0, kNoAttribute) \
46 TOK(kPERIOD, ".", 0, kNoAttribute) \
47 TOK(kQM_PERIOD, "?.", 0, kNoAttribute) \
48 TOK(kINCR, "++", 0, kNoAttribute) \
49 TOK(kDECR, "--", 0, kNoAttribute) \
50 \
51 /* Assignment operators. */ \
52 /* Please update IsAssignmentOperator() if you make */ \
53 /* any changes to this block. */ \
54 TOK(kASSIGN, "=", 2, kNoAttribute) \
55 TOK(kASSIGN_OR, "|=", 2, kNoAttribute) \
56 TOK(kASSIGN_XOR, "^=", 2, kNoAttribute) \
57 TOK(kASSIGN_AND, "&=", 2, kNoAttribute) \
58 TOK(kASSIGN_SHL, "<<=", 2, kNoAttribute) \
59 TOK(kASSIGN_SHR, ">>=", 2, kNoAttribute) \
60 TOK(kASSIGN_USHR, ">>>=", 2, kNoAttribute) \
61 TOK(kASSIGN_ADD, "+=", 2, kNoAttribute) \
62 TOK(kASSIGN_SUB, "-=", 2, kNoAttribute) \
63 TOK(kASSIGN_MUL, "*=", 2, kNoAttribute) \
64 TOK(kASSIGN_TRUNCDIV, "~/=", 2, kNoAttribute) \
65 TOK(kASSIGN_DIV, "/=", 2, kNoAttribute) \
66 TOK(kASSIGN_MOD, "%=", 2, kNoAttribute) \
67 /* Avoid trigraph ??= below. */ \
68 TOK(kASSIGN_COND, "?\?=", 2, kNoAttribute) \
69 \
70 TOK(kCASCADE, "..", 2, kNoAttribute) \
71 \
72 TOK(kCOMMA, ",", 1, kNoAttribute) \
73 TOK(kOR, "||", 5, kNoAttribute) \
74 TOK(kAND, "&&", 6, kNoAttribute) \
75 TOK(kBIT_OR, "|", 9, kNoAttribute) \
76 TOK(kBIT_XOR, "^", 10, kNoAttribute) \
77 TOK(kBIT_AND, "&", 11, kNoAttribute) \
78 TOK(kBIT_NOT, "~", 0, kNoAttribute) \
79 \
80 /* Shift operators. */ \
81 TOK(kSHL, "<<", 12, kNoAttribute) \
82 TOK(kSHR, ">>", 12, kNoAttribute) \
83 TOK(kUSHR, ">>>", 12, kNoAttribute) \
84 \
85 /* Additive operators. */ \
86 TOK(kADD, "+", 13, kNoAttribute) \
87 TOK(kSUB, "-", 13, kNoAttribute) \
88 \
89 /* Multiplicative operators */ \
90 TOK(kMUL, "*", 14, kNoAttribute) \
91 TOK(kDIV, "/", 14, kNoAttribute) \
92 TOK(kTRUNCDIV, "~/", 14, kNoAttribute) \
93 TOK(kMOD, "%", 14, kNoAttribute) \
94 \
95 TOK(kNOT, "!", 0, kNoAttribute) \
96 TOK(kCONDITIONAL, "?", 3, kNoAttribute) \
97 TOK(kIFnullptr, "??", 4, kNoAttribute) \
98 \
99 /* Equality operators. */ \
100 /* Please update IsEqualityOperator() if you make */ \
101 /* any changes to this block. */ \
102 TOK(kEQ, "==", 7, kNoAttribute) \
103 TOK(kNE, "!=", 7, kNoAttribute) \
104 TOK(kEQ_STRICT, "===", 7, kNoAttribute) \
105 TOK(kNE_STRICT, "!==", 7, kNoAttribute) \
106 \
107 /* Relational operators. */ \
108 /* Please update IsRelationalOperator() if you make */ \
109 /* any changes to this block. */ \
110 TOK(kLT, "<", 8, kNoAttribute) \
111 TOK(kGT, ">", 8, kNoAttribute) \
112 TOK(kLTE, "<=", 8, kNoAttribute) \
113 TOK(kGTE, ">=", 8, kNoAttribute) \
114 \
115 /* Internal token for !(expr is Type) negative type test operator */ \
116 TOK(kISNOT, "", 11, kNoAttribute) \
117 \
118 TOK(kINDEX, "[]", 0, kNoAttribute) \
119 TOK(kASSIGN_INDEX, "[]=", 0, kNoAttribute) \
120 TOK(kNEGATE, "unary-", 0, kNoAttribute) \
121 \
122 TOK(kIDENT, "", 0, kNoAttribute) \
123 TOK(kSTRING, "", 0, kNoAttribute) \
124 TOK(kINTEGER, "", 0, kNoAttribute) \
125 TOK(kDOUBLE, "", 0, kNoAttribute) \
126 \
127 TOK(kINTERPOL_VAR, "$", 0, kNoAttribute) \
128 TOK(kINTERPOL_START, "${", 0, kNoAttribute) \
129 TOK(kINTERPOL_END, "}", 0, kNoAttribute) \
130 \
131 TOK(kAT, "@", 0, kNoAttribute) \
132 TOK(kHASH, "#", 0, kNoAttribute) \
133 \
134 TOK(kNEWLINE, "\n", 0, kNoAttribute) \
135 TOK(kWHITESP, "", 0, kNoAttribute) \
136 TOK(kERROR, "", 0, kNoAttribute) \
137 TOK(kILLEGAL, "", 0, kNoAttribute) \
138 \
139 /* Support for Dart scripts. */ \
140 TOK(kSCRIPTTAG, "#!", 0, kNoAttribute) \
141 \
142 /* Support for optimized code */ \
143 TOK(kREM, "rem", 0, kNoAttribute) \
144 TOK(kABS, "abs", 0, kNoAttribute) \
145 TOK(kSQRT, "sqrt", 0, kNoAttribute) \
146 TOK(kMIN, "min", 0, kNoAttribute) \
147 TOK(kMAX, "max", 0, kNoAttribute) \
148 TOK(kRECIPROCAL, "reciprocal", 0, kNoAttribute) \
149 TOK(kRECIPROCAL_SQRT, "reciprocal-sqrt", 0, kNoAttribute) \
150 TOK(kSQUARE, "square", 0, kNoAttribute) \
151 TOK(kTRUNCATE, "truncate", 0, kNoAttribute) \
152 TOK(kFLOOR, "floor", 0, kNoAttribute) \
153 TOK(kCEILING, "ceiling", 0, kNoAttribute)
154
155// List of keywords. The list must be alphabetically ordered. The
156// keyword recognition code depends on the ordering.
157// If you add a keyword at the beginning or end of this list, make sure
158// to update kFirstKeyword and kLastKeyword below.
159#define DART_KEYWORD_LIST(KW) \
160 KW(kABSTRACT, "abstract", 0, kPseudoKeyword) /* == kFirstKeyword */ \
161 KW(kAS, "as", 11, kPseudoKeyword) \
162 KW(kASSERT, "assert", 0, kKeyword) \
163 KW(kBREAK, "break", 0, kKeyword) \
164 KW(kCASE, "case", 0, kKeyword) \
165 KW(kCATCH, "catch", 0, kKeyword) \
166 KW(kCLASS, "class", 0, kKeyword) \
167 KW(kCONST, "const", 0, kKeyword) \
168 KW(kCONTINUE, "continue", 0, kKeyword) \
169 KW(kCOVARIANT, "covariant", 0, kPseudoKeyword) \
170 KW(kDEFAULT, "default", 0, kKeyword) \
171 KW(kDEFERRED, "deferred", 0, kPseudoKeyword) \
172 KW(kDO, "do", 0, kKeyword) \
173 KW(kELSE, "else", 0, kKeyword) \
174 KW(kENUM, "enum", 0, kKeyword) \
175 KW(kEXPORT, "export", 0, kPseudoKeyword) \
176 KW(kEXTENDS, "extends", 0, kKeyword) \
177 KW(kEXTERNAL, "external", 0, kPseudoKeyword) \
178 KW(kFACTORY, "factory", 0, kPseudoKeyword) \
179 KW(kFALSE, "false", 0, kKeyword) \
180 KW(kFINAL, "final", 0, kKeyword) \
181 KW(kFINALLY, "finally", 0, kKeyword) \
182 KW(kFOR, "for", 0, kKeyword) \
183 KW(kGET, "get", 0, kPseudoKeyword) \
184 KW(kIF, "if", 0, kKeyword) \
185 KW(kIMPLEMENTS, "implements", 0, kPseudoKeyword) \
186 KW(kIMPORT, "import", 0, kPseudoKeyword) \
187 KW(kIN, "in", 0, kKeyword) \
188 KW(kIS, "is", 11, kKeyword) \
189 KW(kLIBRARY, "library", 0, kPseudoKeyword) \
190 KW(kNEW, "new", 0, kKeyword) \
191 KW(knullptr, "null", 0, kKeyword) \
192 KW(kOPERATOR, "operator", 0, kPseudoKeyword) \
193 KW(kPART, "part", 0, kPseudoKeyword) \
194 KW(kRETHROW, "rethrow", 0, kKeyword) \
195 KW(kRETURN, "return", 0, kKeyword) \
196 KW(kSET, "set", 0, kPseudoKeyword) \
197 KW(kSTATIC, "static", 0, kPseudoKeyword) \
198 KW(kSUPER, "super", 0, kKeyword) \
199 KW(kSWITCH, "switch", 0, kKeyword) \
200 KW(kTHIS, "this", 0, kKeyword) \
201 KW(kTHROW, "throw", 0, kKeyword) \
202 KW(kTRUE, "true", 0, kKeyword) \
203 KW(kTRY, "try", 0, kKeyword) \
204 KW(kTYPEDEF, "typedef", 0, kPseudoKeyword) \
205 KW(kVAR, "var", 0, kKeyword) \
206 KW(kVOID, "void", 0, kKeyword) \
207 KW(kWHILE, "while", 0, kKeyword) \
208 KW(kWITH, "with", 0, kKeyword) /* == kLastKeyword */
209
210class String;
211
212class Token {
213 public:
214#define T(t, s, p, a) t,
215 enum Kind { DART_TOKEN_LIST(T) DART_KEYWORD_LIST(T) kNumTokens };
216#undef T
217
220 kKeyword = 1 << 0,
222 };
223
224 static const Kind kFirstKeyword = kABSTRACT;
225 static const Kind kLastKeyword = kWITH;
226 static constexpr int kNumKeywords = kLastKeyword - kFirstKeyword + 1;
227
228 static bool IsAssignmentOperator(Kind tok) {
229 return kASSIGN <= tok && tok <= kASSIGN_COND;
230 }
231
232 static bool IsRelationalOperator(Kind tok) {
233 return kLT <= tok && tok <= kGTE;
234 }
235
236 static bool IsEqualityOperator(Kind tok) {
237 return kEQ <= tok && tok <= kNE_STRICT;
238 }
239
241 return (tok == kEQ_STRICT) || (tok == kNE_STRICT);
242 }
243
244 static bool IsTypeTestOperator(Kind tok) {
245 return (tok == kIS) || (tok == kISNOT);
246 }
247
248 static bool IsTypeCastOperator(Kind tok) { return tok == kAS; }
249
250 static bool IsIndexOperator(Kind tok) {
251 return tok == kINDEX || tok == kASSIGN_INDEX;
252 }
253
254 static bool IsPseudoKeyword(Kind tok) {
255 return (Attributes(tok) & kPseudoKeyword) != 0;
256 }
257
258 static bool IsKeyword(Kind tok) { return (Attributes(tok) & kKeyword) != 0; }
259
260 static bool IsIdentifier(Kind tok) {
261 return (tok == kIDENT) || IsPseudoKeyword(tok);
262 }
263
264 static const char* Name(Kind tok) {
265 ASSERT(tok < kNumTokens);
266 return name_[tok];
267 }
268
269 static const char* Str(Kind tok) {
270 ASSERT(tok < kNumTokens);
271 return tok_str_[tok];
272 }
273
274 static bool FromStr(const char* str, Kind* out) {
275 ASSERT(str != nullptr && out != nullptr);
276#define TOK_CASE(t, s, p, a) \
277 if (strcmp(str, tok_str_[(t)]) == 0) { \
278 *out = (t); \
279 return true; \
280 }
283#undef TOK_CASE
284 return false;
285 }
286
287 static int Precedence(Kind tok) {
288 ASSERT(tok < kNumTokens);
289 return precedence_[tok];
290 }
291
293 ASSERT(tok < kNumTokens);
294 return attributes_[tok];
295 }
296
297 static bool CanBeOverloaded(Kind tok) {
298 ASSERT(tok < kNumTokens);
299 return IsRelationalOperator(tok) || (tok == kEQ) ||
300 (tok >= kADD && tok <= kMOD) || // Arithmetic operations.
301 (tok >= kBIT_OR && tok <= kUSHR) || // Bit operations.
302 (tok == kINDEX) || (tok == kASSIGN_INDEX);
303 }
304
305 static bool NeedsLiteralToken(Kind tok) {
306 ASSERT(tok < kNumTokens);
307 return ((tok == Token::kINTEGER) || (tok == Token::kSTRING) ||
308 (tok == Token::kINTERPOL_VAR) || (tok == Token::kERROR) ||
309 (tok == Token::kDOUBLE));
310 }
311
312 static bool IsBinaryOperator(Token::Kind token);
313 static bool IsUnaryOperator(Token::Kind token);
314
315 static bool IsBinaryArithmeticOperator(Token::Kind token);
316 static bool IsUnaryArithmeticOperator(Token::Kind token);
317
318 static bool IsBinaryBitwiseOperator(Token::Kind token);
319
320 // For a comparison operation return an operation for the negated comparison:
321 // !(a (op) b) === a (op') b
323 switch (op) {
324 case Token::kEQ:
325 return Token::kNE;
326 case Token::kNE:
327 return Token::kEQ;
328 case Token::kLT:
329 return Token::kGTE;
330 case Token::kGT:
331 return Token::kLTE;
332 case Token::kLTE:
333 return Token::kGT;
334 case Token::kGTE:
335 return Token::kLT;
336 case Token::kEQ_STRICT:
337 return Token::kNE_STRICT;
338 case Token::kNE_STRICT:
339 return Token::kEQ_STRICT;
340 case Token::kIS:
341 return Token::kISNOT;
342 case Token::kISNOT:
343 return Token::kIS;
344 default:
345 UNREACHABLE();
346 return Token::kILLEGAL;
347 }
348 }
349
350 // For a comparison operation return an operation for the equivalent flipped
351 // comparison: a (op) b === b (op') a.
353 switch (op) {
354 case Token::kEQ:
355 return Token::kEQ;
356 case Token::kNE:
357 return Token::kNE;
358 case Token::kLT:
359 return Token::kGT;
360 case Token::kGT:
361 return Token::kLT;
362 case Token::kLTE:
363 return Token::kGTE;
364 case Token::kGTE:
365 return Token::kLTE;
366 case Token::kEQ_STRICT:
367 return Token::kEQ_STRICT;
368 case Token::kNE_STRICT:
369 return Token::kNE_STRICT;
370 default:
371 UNREACHABLE();
372 return Token::kILLEGAL;
373 }
374 }
375
376 private:
377 static const char* const name_[];
378 static const char* const tok_str_[];
379 static const uint8_t precedence_[];
380 static const Attribute attributes_[];
381};
382
383} // namespace dart
384
385#endif // RUNTIME_VM_TOKEN_H_
#define UNREACHABLE()
Definition: assert.h:248
static bool IsTypeTestOperator(Kind tok)
Definition: token.h:244
static const Kind kLastKeyword
Definition: token.h:225
static bool NeedsLiteralToken(Kind tok)
Definition: token.h:305
static bool IsKeyword(Kind tok)
Definition: token.h:258
static Token::Kind FlipComparison(Token::Kind op)
Definition: token.h:352
static bool IsAssignmentOperator(Kind tok)
Definition: token.h:228
static bool IsBinaryArithmeticOperator(Token::Kind token)
Definition: token.cc:45
static bool IsTypeCastOperator(Kind tok)
Definition: token.h:248
static bool IsIndexOperator(Kind tok)
Definition: token.h:250
static int Precedence(Kind tok)
Definition: token.h:287
static bool IsRelationalOperator(Kind tok)
Definition: token.h:232
static const char * Name(Kind tok)
Definition: token.h:264
static Token::Kind NegateComparison(Token::Kind op)
Definition: token.h:322
static bool IsPseudoKeyword(Kind tok)
Definition: token.h:254
@ kPseudoKeyword
Definition: token.h:221
@ kNoAttribute
Definition: token.h:219
@ kKeyword
Definition: token.h:220
static const char * Str(Kind tok)
Definition: token.h:269
static bool IsBinaryOperator(Token::Kind token)
Definition: token.cc:31
static bool IsIdentifier(Kind tok)
Definition: token.h:260
static const Kind kFirstKeyword
Definition: token.h:224
static Attribute Attributes(Kind tok)
Definition: token.h:292
static constexpr int kNumKeywords
Definition: token.h:226
static bool IsEqualityOperator(Kind tok)
Definition: token.h:236
static bool IsUnaryOperator(Token::Kind token)
Definition: token.cc:41
@ DART_TOKEN_LIST
Definition: token.h:215
static bool IsStrictEqualityOperator(Kind tok)
Definition: token.h:240
static bool CanBeOverloaded(Kind tok)
Definition: token.h:297
static bool IsBinaryBitwiseOperator(Token::Kind token)
Definition: token.cc:85
static bool FromStr(const char *str, Kind *out)
Definition: token.h:274
static bool IsUnaryArithmeticOperator(Token::Kind token)
Definition: token.cc:67
#define ASSERT(E)
Definition: dart_vm.cc:33
#define DART_KEYWORD_LIST(KW)
Definition: token.h:159
#define TOK_CASE(t, s, p, a)
#define T(t, s, p, a)
Definition: token.h:214