TokenKind.h (18417B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 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 #include <stdint.h> 11 12 #include "js/TypeDecls.h" // IF_DECORATORS 13 14 /* 15 * List of token kinds and their ranges. 16 * 17 * The format for each line is: 18 * 19 * MACRO(<TOKEN_KIND_NAME>, <DESCRIPTION>) 20 * 21 * or 22 * 23 * RANGE(<TOKEN_RANGE_NAME>, <TOKEN_KIND_NAME>) 24 * 25 * where ; 26 * <TOKEN_KIND_NAME> is a legal C identifier of the token, that will be used in 27 * the JS engine source. 28 * 29 * <DESCRIPTION> is a string that describe about the token, and will be used in 30 * error message. 31 * 32 * <TOKEN_RANGE_NAME> is a legal C identifier of the range that will be used to 33 * JS engine source. It should end with `First` or `Last`. This is used to check 34 * TokenKind by range-testing: 35 * BinOpFirst <= tt && tt <= BinOpLast 36 * 37 * Second argument of `RANGE` is the actual value of the <TOKEN_RANGE_NAME>, 38 * should be same as one of <TOKEN_KIND_NAME> in other `MACRO`s. 39 * 40 * To use this macro, define two macros for `MACRO` and `RANGE`, and pass them 41 * as arguments. 42 * 43 * #define EMIT_TOKEN(name, desc) ... 44 * #define EMIT_RANGE(name, value) ... 45 * FOR_EACH_TOKEN_KIND_WITH_RANGE(EMIT_TOKEN, EMIT_RANGE) 46 * #undef EMIT_TOKEN 47 * #undef EMIT_RANGE 48 * 49 * If you don't need range data, use FOR_EACH_TOKEN_KIND instead. 50 * 51 * #define EMIT_TOKEN(name, desc) ... 52 * FOR_EACH_TOKEN_KIND(EMIT_TOKEN) 53 * #undef EMIT_TOKEN 54 * 55 * Note that this list does not contain Limit. 56 */ 57 #define FOR_EACH_TOKEN_KIND_WITH_RANGE(MACRO, RANGE) \ 58 MACRO(Eof, "end of script") \ 59 \ 60 /* only returned by peekTokenSameLine() */ \ 61 MACRO(Eol, "line terminator") \ 62 \ 63 MACRO(Semi, "';'") \ 64 MACRO(Comma, "','") \ 65 MACRO(Hook, "'?'") /* conditional */ \ 66 MACRO(Colon, "':'") /* conditional */ \ 67 MACRO(Inc, "'++'") /* increment */ \ 68 MACRO(Dec, "'--'") /* decrement */ \ 69 MACRO(Dot, "'.'") /* member operator */ \ 70 MACRO(TripleDot, "'...'") /* rest arguments and spread operator */ \ 71 MACRO(OptionalChain, "'?.'") \ 72 MACRO(LeftBracket, "'['") \ 73 MACRO(RightBracket, "']'") \ 74 MACRO(LeftCurly, "'{'") \ 75 MACRO(RightCurly, "'}'") \ 76 MACRO(LeftParen, "'('") \ 77 MACRO(RightParen, "')'") \ 78 MACRO(Name, "identifier") \ 79 MACRO(PrivateName, "private identifier") \ 80 MACRO(Number, "numeric literal") \ 81 MACRO(String, "string literal") \ 82 MACRO(BigInt, "bigint literal") \ 83 IF_DECORATORS(MACRO(At, "'@'")) \ 84 \ 85 /* start of template literal with substitutions */ \ 86 MACRO(TemplateHead, "'${'") \ 87 /* template literal without substitutions */ \ 88 MACRO(NoSubsTemplate, "template literal") \ 89 \ 90 MACRO(RegExp, "regular expression literal") \ 91 MACRO(True, "boolean literal 'true'") \ 92 RANGE(ReservedWordLiteralFirst, True) \ 93 MACRO(False, "boolean literal 'false'") \ 94 MACRO(Null, "null literal") \ 95 RANGE(ReservedWordLiteralLast, Null) \ 96 MACRO(This, "keyword 'this'") \ 97 RANGE(KeywordFirst, This) \ 98 MACRO(Function, "keyword 'function'") \ 99 MACRO(If, "keyword 'if'") \ 100 MACRO(Else, "keyword 'else'") \ 101 MACRO(Switch, "keyword 'switch'") \ 102 MACRO(Case, "keyword 'case'") \ 103 MACRO(Default, "keyword 'default'") \ 104 MACRO(While, "keyword 'while'") \ 105 MACRO(Do, "keyword 'do'") \ 106 MACRO(For, "keyword 'for'") \ 107 MACRO(Break, "keyword 'break'") \ 108 MACRO(Continue, "keyword 'continue'") \ 109 MACRO(Var, "keyword 'var'") \ 110 MACRO(Const, "keyword 'const'") \ 111 MACRO(With, "keyword 'with'") \ 112 MACRO(Return, "keyword 'return'") \ 113 MACRO(New, "keyword 'new'") \ 114 MACRO(Delete, "keyword 'delete'") \ 115 MACRO(Try, "keyword 'try'") \ 116 MACRO(Catch, "keyword 'catch'") \ 117 MACRO(Finally, "keyword 'finally'") \ 118 MACRO(Throw, "keyword 'throw'") \ 119 MACRO(Debugger, "keyword 'debugger'") \ 120 MACRO(Export, "keyword 'export'") \ 121 MACRO(Import, "keyword 'import'") \ 122 MACRO(Class, "keyword 'class'") \ 123 MACRO(Extends, "keyword 'extends'") \ 124 MACRO(Super, "keyword 'super'") \ 125 RANGE(KeywordLast, Super) \ 126 \ 127 /* contextual keywords */ \ 128 MACRO(As, "'as'") \ 129 RANGE(ContextualKeywordFirst, As) \ 130 /* TODO: Move to alphabetical order when IF_DECORATORS is removed */ \ 131 IF_DECORATORS(MACRO(Accessor, "'accessor'")) \ 132 MACRO(Async, "'async'") \ 133 MACRO(Await, "'await'") \ 134 MACRO(Each, "'each'") \ 135 MACRO(From, "'from'") \ 136 MACRO(Get, "'get'") \ 137 MACRO(Let, "'let'") \ 138 MACRO(Meta, "'meta'") \ 139 MACRO(Of, "'of'") \ 140 MACRO(Set, "'set'") \ 141 MACRO(Static, "'static'") \ 142 MACRO(Target, "'target'") \ 143 IF_EXPLICIT_RESOURCE_MANAGEMENT(MACRO(Using, "'using'")) \ 144 MACRO(Yield, "'yield'") \ 145 RANGE(ContextualKeywordLast, Yield) \ 146 \ 147 /* future reserved words */ \ 148 MACRO(Enum, "reserved word 'enum'") \ 149 RANGE(FutureReservedKeywordFirst, Enum) \ 150 RANGE(FutureReservedKeywordLast, Enum) \ 151 \ 152 /* reserved words in strict mode */ \ 153 MACRO(Implements, "reserved word 'implements'") \ 154 RANGE(StrictReservedKeywordFirst, Implements) \ 155 MACRO(Interface, "reserved word 'interface'") \ 156 MACRO(Package, "reserved word 'package'") \ 157 MACRO(Private, "reserved word 'private'") \ 158 MACRO(Protected, "reserved word 'protected'") \ 159 MACRO(Public, "reserved word 'public'") \ 160 RANGE(StrictReservedKeywordLast, Public) \ 161 \ 162 /* \ 163 * The following token types occupy contiguous ranges to enable easy \ 164 * range-testing. \ 165 */ \ 166 /* \ 167 * Binary operators. \ 168 * This list must be kept in the same order in several places: \ 169 * - the binary operators in ParseNode.h \ 170 * - the precedence list in Parser.cpp \ 171 * - the JSOp code list in BytecodeEmitter.cpp \ 172 */ \ 173 MACRO(Coalesce, "'\?\?'") /* escapes to avoid trigraphs warning */ \ 174 RANGE(BinOpFirst, Coalesce) \ 175 MACRO(Or, "'||'") /* logical or */ \ 176 MACRO(And, "'&&'") /* logical and */ \ 177 MACRO(BitOr, "'|'") /* bitwise-or */ \ 178 MACRO(BitXor, "'^'") /* bitwise-xor */ \ 179 MACRO(BitAnd, "'&'") /* bitwise-and */ \ 180 \ 181 /* Equality operation tokens, per TokenKindIsEquality. */ \ 182 MACRO(StrictEq, "'==='") \ 183 RANGE(EqualityStart, StrictEq) \ 184 MACRO(Eq, "'=='") \ 185 MACRO(StrictNe, "'!=='") \ 186 MACRO(Ne, "'!='") \ 187 RANGE(EqualityLast, Ne) \ 188 \ 189 /* Relational ops, per TokenKindIsRelational. */ \ 190 MACRO(Lt, "'<'") \ 191 RANGE(RelOpStart, Lt) \ 192 MACRO(Le, "'<='") \ 193 MACRO(Gt, "'>'") \ 194 MACRO(Ge, "'>='") \ 195 RANGE(RelOpLast, Ge) \ 196 \ 197 MACRO(InstanceOf, "keyword 'instanceof'") \ 198 RANGE(KeywordBinOpFirst, InstanceOf) \ 199 MACRO(In, "keyword 'in'") \ 200 MACRO(PrivateIn, "keyword 'in' (private)") \ 201 RANGE(KeywordBinOpLast, PrivateIn) \ 202 \ 203 /* Shift ops, per TokenKindIsShift. */ \ 204 MACRO(Lsh, "'<<'") \ 205 RANGE(ShiftOpStart, Lsh) \ 206 MACRO(Rsh, "'>>'") \ 207 MACRO(Ursh, "'>>>'") \ 208 RANGE(ShiftOpLast, Ursh) \ 209 \ 210 MACRO(Add, "'+'") \ 211 MACRO(Sub, "'-'") \ 212 MACRO(Mul, "'*'") \ 213 MACRO(Div, "'/'") \ 214 MACRO(Mod, "'%'") \ 215 MACRO(Pow, "'**'") \ 216 RANGE(BinOpLast, Pow) \ 217 \ 218 /* Unary operation tokens. */ \ 219 MACRO(TypeOf, "keyword 'typeof'") \ 220 RANGE(KeywordUnOpFirst, TypeOf) \ 221 MACRO(Void, "keyword 'void'") \ 222 RANGE(KeywordUnOpLast, Void) \ 223 MACRO(Not, "'!'") \ 224 MACRO(BitNot, "'~'") \ 225 \ 226 MACRO(Arrow, "'=>'") /* function arrow */ \ 227 \ 228 /* Assignment ops, per TokenKindIsAssignment */ \ 229 MACRO(Assign, "'='") \ 230 RANGE(AssignmentStart, Assign) \ 231 MACRO(AddAssign, "'+='") \ 232 MACRO(SubAssign, "'-='") \ 233 MACRO(CoalesceAssign, "'\?\?='") /* avoid trigraphs warning */ \ 234 MACRO(OrAssign, "'||='") \ 235 MACRO(AndAssign, "'&&='") \ 236 MACRO(BitOrAssign, "'|='") \ 237 MACRO(BitXorAssign, "'^='") \ 238 MACRO(BitAndAssign, "'&='") \ 239 MACRO(LshAssign, "'<<='") \ 240 MACRO(RshAssign, "'>>='") \ 241 MACRO(UrshAssign, "'>>>='") \ 242 MACRO(MulAssign, "'*='") \ 243 MACRO(DivAssign, "'/='") \ 244 MACRO(ModAssign, "'%='") \ 245 MACRO(PowAssign, "'**='") \ 246 RANGE(AssignmentLast, PowAssign) 247 248 #define TOKEN_KIND_RANGE_EMIT_NONE(name, value) 249 #define FOR_EACH_TOKEN_KIND(MACRO) \ 250 FOR_EACH_TOKEN_KIND_WITH_RANGE(MACRO, TOKEN_KIND_RANGE_EMIT_NONE) 251 252 namespace js { 253 namespace frontend { 254 255 // Values of this type are used to index into arrays such as isExprEnding[], 256 // so the first value must be zero. 257 enum class TokenKind : uint8_t { 258 #define EMIT_ENUM(name, desc) name, 259 #define EMIT_ENUM_RANGE(name, value) name = value, 260 FOR_EACH_TOKEN_KIND_WITH_RANGE(EMIT_ENUM, EMIT_ENUM_RANGE) 261 #undef EMIT_ENUM 262 #undef EMIT_ENUM_RANGE 263 Limit // domain size 264 }; 265 266 inline bool TokenKindIsBinaryOp(TokenKind tt) { 267 return TokenKind::BinOpFirst <= tt && tt <= TokenKind::BinOpLast; 268 } 269 270 inline bool TokenKindIsEquality(TokenKind tt) { 271 return TokenKind::EqualityStart <= tt && tt <= TokenKind::EqualityLast; 272 } 273 274 inline bool TokenKindIsRelational(TokenKind tt) { 275 return TokenKind::RelOpStart <= tt && tt <= TokenKind::RelOpLast; 276 } 277 278 inline bool TokenKindIsShift(TokenKind tt) { 279 return TokenKind::ShiftOpStart <= tt && tt <= TokenKind::ShiftOpLast; 280 } 281 282 inline bool TokenKindIsAssignment(TokenKind tt) { 283 return TokenKind::AssignmentStart <= tt && tt <= TokenKind::AssignmentLast; 284 } 285 286 [[nodiscard]] inline bool TokenKindIsKeyword(TokenKind tt) { 287 return (TokenKind::KeywordFirst <= tt && tt <= TokenKind::KeywordLast) || 288 (TokenKind::KeywordBinOpFirst <= tt && 289 tt <= TokenKind::KeywordBinOpLast) || 290 (TokenKind::KeywordUnOpFirst <= tt && 291 tt <= TokenKind::KeywordUnOpLast); 292 } 293 294 [[nodiscard]] inline bool TokenKindIsContextualKeyword(TokenKind tt) { 295 return TokenKind::ContextualKeywordFirst <= tt && 296 tt <= TokenKind::ContextualKeywordLast; 297 } 298 299 [[nodiscard]] inline bool TokenKindIsFutureReservedWord(TokenKind tt) { 300 return TokenKind::FutureReservedKeywordFirst <= tt && 301 tt <= TokenKind::FutureReservedKeywordLast; 302 } 303 304 [[nodiscard]] inline bool TokenKindIsStrictReservedWord(TokenKind tt) { 305 return TokenKind::StrictReservedKeywordFirst <= tt && 306 tt <= TokenKind::StrictReservedKeywordLast; 307 } 308 309 [[nodiscard]] inline bool TokenKindIsReservedWordLiteral(TokenKind tt) { 310 return TokenKind::ReservedWordLiteralFirst <= tt && 311 tt <= TokenKind::ReservedWordLiteralLast; 312 } 313 314 [[nodiscard]] inline bool TokenKindIsReservedWord(TokenKind tt) { 315 return TokenKindIsKeyword(tt) || TokenKindIsFutureReservedWord(tt) || 316 TokenKindIsReservedWordLiteral(tt); 317 } 318 319 [[nodiscard]] inline bool TokenKindIsPossibleIdentifier(TokenKind tt) { 320 return tt == TokenKind::Name || TokenKindIsContextualKeyword(tt) || 321 TokenKindIsStrictReservedWord(tt); 322 } 323 324 [[nodiscard]] inline bool TokenKindIsPossibleIdentifierName(TokenKind tt) { 325 return TokenKindIsPossibleIdentifier(tt) || TokenKindIsReservedWord(tt); 326 } 327 328 } // namespace frontend 329 } // namespace js 330 331 #endif /* frontend_TokenKind_h */