| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
| * vim: set ts=8 sts=4 et sw=4 tw=99: |
| * This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| |
| #ifndef frontend_TokenKind_h |
| #define frontend_TokenKind_h |
| |
| /* |
| * List of token kinds and their ranges. |
| * |
| * The format for each line is: |
| * |
| * macro(<TOKEN_KIND_NAME>, <DESCRIPTION>) |
| * |
| * or |
| * |
| * range(<TOKEN_RANGE_NAME>, <TOKEN_KIND_NAME>) |
| * |
| * where ; |
| * <TOKEN_KIND_NAME> is a legal C identifier of the token, that will be used in |
| * the JS engine source, with `TOK_` prefix. |
| * |
| * <DESCRIPTION> is a string that describe about the token, and will be used in |
| * error message. |
| * |
| * <TOKEN_RANGE_NAME> is a legal C identifier of the range that will be used to |
| * JS engine source, with `TOK_` prefix. It should end with `_FIRST` or `_LAST`. |
| * This is used to check TokenKind by range-testing: |
| * TOK_BINOP_FIRST <= tt && tt <= TOK_BINOP_LAST |
| * |
| * Second argument of `range` is the actual value of the <TOKEN_RANGE_NAME>, |
| * should be same as one of <TOKEN_KIND_NAME> in other `macro`s. |
| * |
| * To use this macro, define two macros for `macro` and `range`, and pass them |
| * as arguments. |
| * |
| * #define EMIT_TOKEN(name, desc) ... |
| * #define EMIT_RANGE(name, value) ... |
| * FOR_EACH_TOKEN_KIND_WITH_RANGE(EMIT_TOKEN, EMIT_RANGE) |
| * #undef EMIT_TOKEN |
| * #undef EMIT_RANGE |
| * |
| * If you don't need range data, use FOR_EACH_TOKEN_KIND instead. |
| * |
| * #define EMIT_TOKEN(name, desc) ... |
| * FOR_EACH_TOKEN_KIND(EMIT_TOKEN) |
| * #undef EMIT_TOKEN |
| * |
| * Note that this list does not contain ERROR and LIMIT. |
| */ |
| #define FOR_EACH_TOKEN_KIND_WITH_RANGE(macro, range) \ |
| macro(EOF, "end of script") \ |
| \ |
| /* only returned by peekTokenSameLine() */ \ |
| macro(EOL, "line terminator") \ |
| \ |
| macro(SEMI, "';'") \ |
| macro(COMMA, "','") \ |
| macro(HOOK, "'?'") /* conditional */ \ |
| macro(COLON, "':'") /* conditional */ \ |
| macro(INC, "'++'") /* increment */ \ |
| macro(DEC, "'--'") /* decrement */ \ |
| macro(DOT, "'.'") /* member operator */ \ |
| macro(TRIPLEDOT, "'...'") /* rest arguments and spread operator */ \ |
| macro(LB, "'['") \ |
| macro(RB, "']'") \ |
| macro(LC, "'{'") \ |
| macro(RC, "'}'") \ |
| macro(LP, "'('") \ |
| macro(RP, "')'") \ |
| macro(NAME, "identifier") \ |
| macro(NUMBER, "numeric literal") \ |
| macro(STRING, "string literal") \ |
| \ |
| /* start of template literal with substitutions */ \ |
| macro(TEMPLATE_HEAD, "'${'") \ |
| /* template literal without substitutions */ \ |
| macro(NO_SUBS_TEMPLATE, "template literal") \ |
| \ |
| macro(REGEXP, "regular expression literal") \ |
| macro(TRUE, "boolean literal 'true'") \ |
| macro(FALSE, "boolean literal 'false'") \ |
| macro(NULL, "null literal") \ |
| macro(THIS, "keyword 'this'") \ |
| macro(FUNCTION, "keyword 'function'") \ |
| macro(IF, "keyword 'if'") \ |
| macro(ELSE, "keyword 'else'") \ |
| macro(SWITCH, "keyword 'switch'") \ |
| macro(CASE, "keyword 'case'") \ |
| macro(DEFAULT, "keyword 'default'") \ |
| macro(WHILE, "keyword 'while'") \ |
| macro(DO, "keyword 'do'") \ |
| macro(FOR, "keyword 'for'") \ |
| macro(BREAK, "keyword 'break'") \ |
| macro(CONTINUE, "keyword 'continue'") \ |
| macro(VAR, "keyword 'var'") \ |
| macro(CONST, "keyword 'const'") \ |
| macro(WITH, "keyword 'with'") \ |
| macro(RETURN, "keyword 'return'") \ |
| macro(NEW, "keyword 'new'") \ |
| macro(DELETE, "keyword 'delete'") \ |
| macro(TRY, "keyword 'try'") \ |
| macro(CATCH, "keyword 'catch'") \ |
| macro(FINALLY, "keyword 'finally'") \ |
| macro(THROW, "keyword 'throw'") \ |
| macro(DEBUGGER, "keyword 'debugger'") \ |
| macro(YIELD, "keyword 'yield'") \ |
| macro(LET, "keyword 'let'") \ |
| macro(EXPORT, "keyword 'export'") \ |
| macro(IMPORT, "keyword 'import'") \ |
| macro(CLASS, "keyword 'class'") \ |
| macro(EXTENDS, "keyword 'extends'") \ |
| macro(SUPER, "keyword 'super'") \ |
| macro(RESERVED, "reserved keyword") \ |
| /* reserved keywords in strict mode */ \ |
| macro(STRICT_RESERVED, "reserved keyword") \ |
| \ |
| /* \ |
| * The following token types occupy contiguous ranges to enable easy \ |
| * range-testing. \ |
| */ \ |
| /* \ |
| * Binary operators tokens, TOK_OR thru TOK_POW. These must be in the same \ |
| * order as F(OR) and friends in FOR_EACH_PARSE_NODE_KIND in ParseNode.h. \ |
| */ \ |
| macro(OR, "'||'") /* logical or */ \ |
| range(BINOP_FIRST, OR) \ |
| macro(AND, "'&&'") /* logical and */ \ |
| macro(BITOR, "'|'") /* bitwise-or */ \ |
| macro(BITXOR, "'^'") /* bitwise-xor */ \ |
| macro(BITAND, "'&'") /* bitwise-and */ \ |
| \ |
| /* Equality operation tokens, per TokenKindIsEquality. */ \ |
| macro(STRICTEQ, "'==='") \ |
| range(EQUALITY_START, STRICTEQ) \ |
| macro(EQ, "'=='") \ |
| macro(STRICTNE, "'!=='") \ |
| macro(NE, "'!='") \ |
| range(EQUALITY_LAST, NE) \ |
| \ |
| /* Relational ops, per TokenKindIsRelational. */ \ |
| macro(LT, "'<'") \ |
| range(RELOP_START, LT) \ |
| macro(LE, "'<='") \ |
| macro(GT, "'>'") \ |
| macro(GE, "'>='") \ |
| range(RELOP_LAST, GE) \ |
| \ |
| macro(INSTANCEOF, "keyword 'instanceof'") \ |
| macro(IN, "keyword 'in'") \ |
| \ |
| /* Shift ops, per TokenKindIsShift. */ \ |
| macro(LSH, "'<<'") \ |
| range(SHIFTOP_START, LSH) \ |
| macro(RSH, "'>>'") \ |
| macro(URSH, "'>>>'") \ |
| range(SHIFTOP_LAST, URSH) \ |
| \ |
| macro(ADD, "'+'") \ |
| macro(SUB, "'-'") \ |
| macro(MUL, "'*'") \ |
| macro(DIV, "'/'") \ |
| macro(MOD, "'%'") \ |
| macro(POW, "'**'") \ |
| range(BINOP_LAST, POW) \ |
| \ |
| /* Unary operation tokens. */ \ |
| macro(TYPEOF, "keyword 'typeof'") \ |
| macro(VOID, "keyword 'void'") \ |
| macro(NOT, "'!'") \ |
| macro(BITNOT, "'~'") \ |
| \ |
| macro(ARROW, "'=>'") /* function arrow */ \ |
| \ |
| /* Assignment ops, per TokenKindIsAssignment */ \ |
| macro(ASSIGN, "'='") \ |
| range(ASSIGNMENT_START, ASSIGN) \ |
| macro(ADDASSIGN, "'+='") \ |
| macro(SUBASSIGN, "'-='") \ |
| macro(BITORASSIGN, "'|='") \ |
| macro(BITXORASSIGN, "'^='") \ |
| macro(BITANDASSIGN, "'&='") \ |
| macro(LSHASSIGN, "'<<='") \ |
| macro(RSHASSIGN, "'>>='") \ |
| macro(URSHASSIGN, "'>>>='") \ |
| macro(MULASSIGN, "'*='") \ |
| macro(DIVASSIGN, "'/='") \ |
| macro(MODASSIGN, "'%='") \ |
| macro(POWASSIGN, "'**='") \ |
| range(ASSIGNMENT_LAST, POWASSIGN) |
| |
| #define TOKEN_KIND_RANGE_EMIT_NONE(name, value) |
| #define FOR_EACH_TOKEN_KIND(macro) \ |
| FOR_EACH_TOKEN_KIND_WITH_RANGE(macro, TOKEN_KIND_RANGE_EMIT_NONE) |
| |
| namespace js { |
| namespace frontend { |
| |
| // Values of this type are used to index into arrays such as isExprEnding[], |
| // so the first value must be zero. |
| enum TokenKind { |
| #define EMIT_ENUM(name, desc) TOK_##name, |
| #define EMIT_ENUM_RANGE(name, value) TOK_##name = TOK_##value, |
| FOR_EACH_TOKEN_KIND_WITH_RANGE(EMIT_ENUM, EMIT_ENUM_RANGE) |
| #undef EMIT_ENUM |
| #undef EMIT_ENUM_RANGE |
| TOK_LIMIT // domain size |
| }; |
| |
| inline bool |
| TokenKindIsBinaryOp(TokenKind tt) |
| { |
| return TOK_BINOP_FIRST <= tt && tt <= TOK_BINOP_LAST; |
| } |
| |
| inline bool |
| TokenKindIsEquality(TokenKind tt) |
| { |
| return TOK_EQUALITY_START <= tt && tt <= TOK_EQUALITY_LAST; |
| } |
| |
| inline bool |
| TokenKindIsRelational(TokenKind tt) |
| { |
| return TOK_RELOP_START <= tt && tt <= TOK_RELOP_LAST; |
| } |
| |
| inline bool |
| TokenKindIsShift(TokenKind tt) |
| { |
| return TOK_SHIFTOP_START <= tt && tt <= TOK_SHIFTOP_LAST; |
| } |
| |
| inline bool |
| TokenKindIsAssignment(TokenKind tt) |
| { |
| return TOK_ASSIGNMENT_START <= tt && tt <= TOK_ASSIGNMENT_LAST; |
| } |
| |
| inline bool |
| TokenKindIsDecl(TokenKind tt) |
| { |
| return tt == TOK_VAR || tt == TOK_LET; |
| } |
| |
| } // namespace frontend |
| } // namespace js |
| |
| #endif /* frontend_TokenKind_h */ |