LCOV - code coverage report
Current view: top level - src/parsing - token.h (source / functions) Hit Total Coverage
Test: app.info Lines: 20 20 100.0 %
Date: 2019-01-20 Functions: 7 7 100.0 %

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

Generated by: LCOV version 1.10