| OLD | NEW |
| (Empty) |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef V8_TOKEN_H_ | |
| 6 #define V8_TOKEN_H_ | |
| 7 | |
| 8 #include "src/base/logging.h" | |
| 9 #include "src/globals.h" | |
| 10 | |
| 11 namespace v8 { | |
| 12 namespace internal { | |
| 13 | |
| 14 // TOKEN_LIST takes a list of 3 macros M, all of which satisfy the | |
| 15 // same signature M(name, string, precedence), where name is the | |
| 16 // symbolic token name, string is the corresponding syntactic symbol | |
| 17 // (or NULL, for literals), and precedence is the precedence (or 0). | |
| 18 // The parameters are invoked for token categories as follows: | |
| 19 // | |
| 20 // T: Non-keyword tokens | |
| 21 // K: Keyword tokens | |
| 22 | |
| 23 // IGNORE_TOKEN is a convenience macro that can be supplied as | |
| 24 // an argument (at any position) for a TOKEN_LIST call. It does | |
| 25 // nothing with tokens belonging to the respective category. | |
| 26 | |
| 27 #define IGNORE_TOKEN(name, string, precedence) | |
| 28 | |
| 29 #define TOKEN_LIST(T, K) \ | |
| 30 /* End of source indicator. */ \ | |
| 31 T(EOS, "EOS", 0) \ | |
| 32 \ | |
| 33 /* Punctuators (ECMA-262, section 7.7, page 15). */ \ | |
| 34 T(LPAREN, "(", 0) \ | |
| 35 T(RPAREN, ")", 0) \ | |
| 36 T(LBRACK, "[", 0) \ | |
| 37 T(RBRACK, "]", 0) \ | |
| 38 T(LBRACE, "{", 0) \ | |
| 39 T(RBRACE, "}", 0) \ | |
| 40 T(COLON, ":", 0) \ | |
| 41 T(SEMICOLON, ";", 0) \ | |
| 42 T(PERIOD, ".", 0) \ | |
| 43 T(ELLIPSIS, "...", 0) \ | |
| 44 T(CONDITIONAL, "?", 3) \ | |
| 45 T(INC, "++", 0) \ | |
| 46 T(DEC, "--", 0) \ | |
| 47 T(ARROW, "=>", 0) \ | |
| 48 \ | |
| 49 /* Assignment operators. */ \ | |
| 50 /* IsAssignmentOp() and Assignment::is_compound() relies on */ \ | |
| 51 /* this block of enum values being contiguous and sorted in the */ \ | |
| 52 /* same order! */ \ | |
| 53 T(INIT, "=init", 2) /* AST-use only. */ \ | |
| 54 T(ASSIGN, "=", 2) \ | |
| 55 T(ASSIGN_BIT_OR, "|=", 2) \ | |
| 56 T(ASSIGN_BIT_XOR, "^=", 2) \ | |
| 57 T(ASSIGN_BIT_AND, "&=", 2) \ | |
| 58 T(ASSIGN_SHL, "<<=", 2) \ | |
| 59 T(ASSIGN_SAR, ">>=", 2) \ | |
| 60 T(ASSIGN_SHR, ">>>=", 2) \ | |
| 61 T(ASSIGN_ADD, "+=", 2) \ | |
| 62 T(ASSIGN_SUB, "-=", 2) \ | |
| 63 T(ASSIGN_MUL, "*=", 2) \ | |
| 64 T(ASSIGN_DIV, "/=", 2) \ | |
| 65 T(ASSIGN_MOD, "%=", 2) \ | |
| 66 \ | |
| 67 /* Binary operators sorted by precedence. */ \ | |
| 68 /* IsBinaryOp() relies on this block of enum values */ \ | |
| 69 /* being contiguous and sorted in the same order! */ \ | |
| 70 T(COMMA, ",", 1) \ | |
| 71 T(OR, "||", 4) \ | |
| 72 T(AND, "&&", 5) \ | |
| 73 T(BIT_OR, "|", 6) \ | |
| 74 T(BIT_XOR, "^", 7) \ | |
| 75 T(BIT_AND, "&", 8) \ | |
| 76 T(SHL, "<<", 11) \ | |
| 77 T(SAR, ">>", 11) \ | |
| 78 T(SHR, ">>>", 11) \ | |
| 79 T(ROR, "rotate right", 11) /* only used by Crankshaft */ \ | |
| 80 T(ADD, "+", 12) \ | |
| 81 T(SUB, "-", 12) \ | |
| 82 T(MUL, "*", 13) \ | |
| 83 T(DIV, "/", 13) \ | |
| 84 T(MOD, "%", 13) \ | |
| 85 \ | |
| 86 /* Compare operators sorted by precedence. */ \ | |
| 87 /* IsCompareOp() relies on this block of enum values */ \ | |
| 88 /* being contiguous and sorted in the same order! */ \ | |
| 89 T(EQ, "==", 9) \ | |
| 90 T(NE, "!=", 9) \ | |
| 91 T(EQ_STRICT, "===", 9) \ | |
| 92 T(NE_STRICT, "!==", 9) \ | |
| 93 T(LT, "<", 10) \ | |
| 94 T(GT, ">", 10) \ | |
| 95 T(LTE, "<=", 10) \ | |
| 96 T(GTE, ">=", 10) \ | |
| 97 K(INSTANCEOF, "instanceof", 10) \ | |
| 98 K(IN, "in", 10) \ | |
| 99 \ | |
| 100 /* Unary operators. */ \ | |
| 101 /* IsUnaryOp() relies on this block of enum values */ \ | |
| 102 /* being contiguous and sorted in the same order! */ \ | |
| 103 T(NOT, "!", 0) \ | |
| 104 T(BIT_NOT, "~", 0) \ | |
| 105 K(DELETE, "delete", 0) \ | |
| 106 K(TYPEOF, "typeof", 0) \ | |
| 107 K(VOID, "void", 0) \ | |
| 108 \ | |
| 109 /* Keywords (ECMA-262, section 7.5.2, page 13). */ \ | |
| 110 K(BREAK, "break", 0) \ | |
| 111 K(CASE, "case", 0) \ | |
| 112 K(CATCH, "catch", 0) \ | |
| 113 K(CONTINUE, "continue", 0) \ | |
| 114 K(DEBUGGER, "debugger", 0) \ | |
| 115 K(DEFAULT, "default", 0) \ | |
| 116 /* DELETE */ \ | |
| 117 K(DO, "do", 0) \ | |
| 118 K(ELSE, "else", 0) \ | |
| 119 K(FINALLY, "finally", 0) \ | |
| 120 K(FOR, "for", 0) \ | |
| 121 K(FUNCTION, "function", 0) \ | |
| 122 K(IF, "if", 0) \ | |
| 123 /* IN */ \ | |
| 124 /* INSTANCEOF */ \ | |
| 125 K(NEW, "new", 0) \ | |
| 126 K(RETURN, "return", 0) \ | |
| 127 K(SWITCH, "switch", 0) \ | |
| 128 K(THIS, "this", 0) \ | |
| 129 K(THROW, "throw", 0) \ | |
| 130 K(TRY, "try", 0) \ | |
| 131 /* TYPEOF */ \ | |
| 132 K(VAR, "var", 0) \ | |
| 133 /* VOID */ \ | |
| 134 K(WHILE, "while", 0) \ | |
| 135 K(WITH, "with", 0) \ | |
| 136 \ | |
| 137 /* Literals (ECMA-262, section 7.8, page 16). */ \ | |
| 138 K(NULL_LITERAL, "null", 0) \ | |
| 139 K(TRUE_LITERAL, "true", 0) \ | |
| 140 K(FALSE_LITERAL, "false", 0) \ | |
| 141 T(NUMBER, NULL, 0) \ | |
| 142 T(SMI, NULL, 0) \ | |
| 143 T(STRING, NULL, 0) \ | |
| 144 \ | |
| 145 /* Identifiers (not keywords or future reserved words). */ \ | |
| 146 T(IDENTIFIER, NULL, 0) \ | |
| 147 \ | |
| 148 /* Future reserved words (ECMA-262, section 7.6.1.2). */ \ | |
| 149 T(FUTURE_RESERVED_WORD, NULL, 0) \ | |
| 150 T(FUTURE_STRICT_RESERVED_WORD, NULL, 0) \ | |
| 151 K(CLASS, "class", 0) \ | |
| 152 K(CONST, "const", 0) \ | |
| 153 K(EXPORT, "export", 0) \ | |
| 154 K(EXTENDS, "extends", 0) \ | |
| 155 K(IMPORT, "import", 0) \ | |
| 156 K(LET, "let", 0) \ | |
| 157 K(STATIC, "static", 0) \ | |
| 158 K(YIELD, "yield", 0) \ | |
| 159 K(SUPER, "super", 0) \ | |
| 160 \ | |
| 161 /* Illegal token - not able to scan. */ \ | |
| 162 T(ILLEGAL, "ILLEGAL", 0) \ | |
| 163 T(ESCAPED_KEYWORD, NULL, 0) \ | |
| 164 T(ESCAPED_STRICT_RESERVED_WORD, NULL, 0) \ | |
| 165 \ | |
| 166 /* Scanner-internal use only. */ \ | |
| 167 T(WHITESPACE, NULL, 0) \ | |
| 168 T(UNINITIALIZED, NULL, 0) \ | |
| 169 \ | |
| 170 /* ES6 Template Literals */ \ | |
| 171 T(TEMPLATE_SPAN, NULL, 0) \ | |
| 172 T(TEMPLATE_TAIL, NULL, 0) | |
| 173 | |
| 174 | |
| 175 class Token { | |
| 176 public: | |
| 177 // All token values. | |
| 178 #define T(name, string, precedence) name, | |
| 179 enum Value { | |
| 180 TOKEN_LIST(T, T) | |
| 181 NUM_TOKENS | |
| 182 }; | |
| 183 #undef T | |
| 184 | |
| 185 // Returns a string corresponding to the C++ token name | |
| 186 // (e.g. "LT" for the token LT). | |
| 187 static const char* Name(Value tok) { | |
| 188 DCHECK(tok < NUM_TOKENS); // tok is unsigned | |
| 189 return name_[tok]; | |
| 190 } | |
| 191 | |
| 192 // Predicates | |
| 193 static bool IsKeyword(Value tok) { | |
| 194 return token_type[tok] == 'K'; | |
| 195 } | |
| 196 | |
| 197 static bool IsIdentifier(Value tok, LanguageMode language_mode, | |
| 198 bool is_generator) { | |
| 199 switch (tok) { | |
| 200 case IDENTIFIER: | |
| 201 return true; | |
| 202 case ESCAPED_STRICT_RESERVED_WORD: | |
| 203 case FUTURE_STRICT_RESERVED_WORD: | |
| 204 case LET: | |
| 205 case STATIC: | |
| 206 return is_sloppy(language_mode); | |
| 207 case YIELD: | |
| 208 return !is_generator && is_sloppy(language_mode); | |
| 209 default: | |
| 210 return false; | |
| 211 } | |
| 212 UNREACHABLE(); | |
| 213 return false; | |
| 214 } | |
| 215 | |
| 216 static bool IsAssignmentOp(Value tok) { | |
| 217 return INIT <= tok && tok <= ASSIGN_MOD; | |
| 218 } | |
| 219 | |
| 220 static bool IsBinaryOp(Value op) { | |
| 221 return COMMA <= op && op <= MOD; | |
| 222 } | |
| 223 | |
| 224 static bool IsTruncatingBinaryOp(Value op) { | |
| 225 return BIT_OR <= op && op <= ROR; | |
| 226 } | |
| 227 | |
| 228 static bool IsCompareOp(Value op) { | |
| 229 return EQ <= op && op <= IN; | |
| 230 } | |
| 231 | |
| 232 static bool IsOrderedRelationalCompareOp(Value op) { | |
| 233 return op == LT || op == LTE || op == GT || op == GTE; | |
| 234 } | |
| 235 | |
| 236 static bool IsEqualityOp(Value op) { | |
| 237 return op == EQ || op == EQ_STRICT; | |
| 238 } | |
| 239 | |
| 240 static bool IsInequalityOp(Value op) { | |
| 241 return op == NE || op == NE_STRICT; | |
| 242 } | |
| 243 | |
| 244 static bool IsArithmeticCompareOp(Value op) { | |
| 245 return IsOrderedRelationalCompareOp(op) || | |
| 246 IsEqualityOp(op) || IsInequalityOp(op); | |
| 247 } | |
| 248 | |
| 249 static Value NegateCompareOp(Value op) { | |
| 250 DCHECK(IsArithmeticCompareOp(op)); | |
| 251 switch (op) { | |
| 252 case EQ: return NE; | |
| 253 case NE: return EQ; | |
| 254 case EQ_STRICT: return NE_STRICT; | |
| 255 case NE_STRICT: return EQ_STRICT; | |
| 256 case LT: return GTE; | |
| 257 case GT: return LTE; | |
| 258 case LTE: return GT; | |
| 259 case GTE: return LT; | |
| 260 default: | |
| 261 UNREACHABLE(); | |
| 262 return op; | |
| 263 } | |
| 264 } | |
| 265 | |
| 266 static Value ReverseCompareOp(Value op) { | |
| 267 DCHECK(IsArithmeticCompareOp(op)); | |
| 268 switch (op) { | |
| 269 case EQ: return EQ; | |
| 270 case NE: return NE; | |
| 271 case EQ_STRICT: return EQ_STRICT; | |
| 272 case NE_STRICT: return NE_STRICT; | |
| 273 case LT: return GT; | |
| 274 case GT: return LT; | |
| 275 case LTE: return GTE; | |
| 276 case GTE: return LTE; | |
| 277 default: | |
| 278 UNREACHABLE(); | |
| 279 return op; | |
| 280 } | |
| 281 } | |
| 282 | |
| 283 static bool IsBitOp(Value op) { | |
| 284 return (BIT_OR <= op && op <= SHR) || op == BIT_NOT; | |
| 285 } | |
| 286 | |
| 287 static bool IsUnaryOp(Value op) { | |
| 288 return (NOT <= op && op <= VOID) || op == ADD || op == SUB; | |
| 289 } | |
| 290 | |
| 291 static bool IsCountOp(Value op) { | |
| 292 return op == INC || op == DEC; | |
| 293 } | |
| 294 | |
| 295 static bool IsShiftOp(Value op) { | |
| 296 return (SHL <= op) && (op <= SHR); | |
| 297 } | |
| 298 | |
| 299 // Returns a string corresponding to the JS token string | |
| 300 // (.e., "<" for the token LT) or NULL if the token doesn't | |
| 301 // have a (unique) string (e.g. an IDENTIFIER). | |
| 302 static const char* String(Value tok) { | |
| 303 DCHECK(tok < NUM_TOKENS); // tok is unsigned. | |
| 304 return string_[tok]; | |
| 305 } | |
| 306 | |
| 307 // Returns the precedence > 0 for binary and compare | |
| 308 // operators; returns 0 otherwise. | |
| 309 static int Precedence(Value tok) { | |
| 310 DCHECK(tok < NUM_TOKENS); // tok is unsigned. | |
| 311 return precedence_[tok]; | |
| 312 } | |
| 313 | |
| 314 private: | |
| 315 static const char* const name_[NUM_TOKENS]; | |
| 316 static const char* const string_[NUM_TOKENS]; | |
| 317 static const int8_t precedence_[NUM_TOKENS]; | |
| 318 static const char token_type[NUM_TOKENS]; | |
| 319 }; | |
| 320 | |
| 321 } // namespace internal | |
| 322 } // namespace v8 | |
| 323 | |
| 324 #endif // V8_TOKEN_H_ | |
| OLD | NEW |