173d88f434a936ebb96f9bd0bee1eebd4b3d9370
[WebKit-https.git] / Source / JavaScriptCore / parser / ParserTokens.h
1 /*
2  * Copyright (C) 2010, 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #pragma once
27
28 #include "ParserModes.h"
29 #include <limits.h>
30 #include <stdint.h>
31
32 namespace JSC {
33
34 class Identifier;
35
36 enum {
37     // Token Bitfield: 0b000000000RTE000IIIIPPPPKUXXXXXXX
38     // R = right-associative bit
39     // T = unterminated error flag
40     // E = error flag
41     // I = binary operator allows 'in'
42     // P = binary operator precedence
43     // K = keyword flag
44     // U = unary operator flag
45     UnaryOpTokenFlag = 128,
46     KeywordTokenFlag = 256,
47     BinaryOpTokenPrecedenceShift = 9,
48     BinaryOpTokenAllowsInPrecedenceAdditionalShift = 4,
49     BinaryOpTokenPrecedenceMask = 15 << BinaryOpTokenPrecedenceShift,
50     ErrorTokenFlag = 1 << (BinaryOpTokenAllowsInPrecedenceAdditionalShift + BinaryOpTokenPrecedenceShift + 7),
51     UnterminatedErrorTokenFlag = ErrorTokenFlag << 1,
52     RightAssociativeBinaryOpTokenFlag = UnterminatedErrorTokenFlag << 1
53 };
54
55 #define BINARY_OP_PRECEDENCE(prec) (((prec) << BinaryOpTokenPrecedenceShift) | ((prec) << (BinaryOpTokenPrecedenceShift + BinaryOpTokenAllowsInPrecedenceAdditionalShift)))
56 #define IN_OP_PRECEDENCE(prec) ((prec) << (BinaryOpTokenPrecedenceShift + BinaryOpTokenAllowsInPrecedenceAdditionalShift))
57
58 enum JSTokenType {
59     NULLTOKEN = KeywordTokenFlag,
60     TRUETOKEN,
61     FALSETOKEN,
62     BREAK,
63     CASE,
64     DEFAULT,
65     FOR,
66     NEW,
67     VAR,
68     CONSTTOKEN,
69     CONTINUE,
70     FUNCTION,
71     RETURN,
72     IF,
73     THISTOKEN,
74     DO,
75     WHILE,
76     SWITCH,
77     WITH,
78     RESERVED,
79     RESERVED_IF_STRICT,
80     THROW,
81     TRY,
82     CATCH,
83     FINALLY,
84     DEBUGGER,
85     ELSE,
86     IMPORT,
87     EXPORT,
88     CLASSTOKEN,
89     EXTENDS,
90     SUPER,
91
92     // Contextual keywords
93     
94     LET,
95     YIELD,
96     AWAIT,
97     ASYNC,
98
99     FirstContextualKeywordToken = LET,
100     LastContextualKeywordToken = ASYNC,
101     FirstSafeContextualKeywordToken = AWAIT,
102     LastSafeContextualKeywordToken = LastContextualKeywordToken,
103
104     OPENBRACE = 0,
105     CLOSEBRACE,
106     OPENPAREN,
107     CLOSEPAREN,
108     OPENBRACKET,
109     CLOSEBRACKET,
110     COMMA,
111     QUESTION,
112     BACKQUOTE,
113     INTEGER,
114     DOUBLE,
115     IDENT,
116     STRING,
117     TEMPLATE,
118     REGEXP,
119     SEMICOLON,
120     COLON,
121     DOT,
122     EOFTOK,
123     EQUAL,
124     PLUSEQUAL,
125     MINUSEQUAL,
126     MULTEQUAL,
127     DIVEQUAL,
128     LSHIFTEQUAL,
129     RSHIFTEQUAL,
130     URSHIFTEQUAL,
131     ANDEQUAL,
132     MODEQUAL,
133     POWEQUAL,
134     XOREQUAL,
135     OREQUAL,
136     DOTDOTDOT,
137     ARROWFUNCTION,
138     LastUntaggedToken,
139
140     // Begin tagged tokens
141     PLUSPLUS = 0 | UnaryOpTokenFlag,
142     MINUSMINUS = 1 | UnaryOpTokenFlag,
143     AUTOPLUSPLUS = 2 | UnaryOpTokenFlag,
144     AUTOMINUSMINUS = 3 | UnaryOpTokenFlag,
145     EXCLAMATION = 4 | UnaryOpTokenFlag,
146     TILDE = 5 | UnaryOpTokenFlag,
147     TYPEOF = 6 | UnaryOpTokenFlag | KeywordTokenFlag,
148     VOIDTOKEN = 7 | UnaryOpTokenFlag | KeywordTokenFlag,
149     DELETETOKEN = 8 | UnaryOpTokenFlag | KeywordTokenFlag,
150     OR = 0 | BINARY_OP_PRECEDENCE(1),
151     AND = 1 | BINARY_OP_PRECEDENCE(2),
152     BITOR = 2 | BINARY_OP_PRECEDENCE(3),
153     BITXOR = 3 | BINARY_OP_PRECEDENCE(4),
154     BITAND = 4 | BINARY_OP_PRECEDENCE(5),
155     EQEQ = 5 | BINARY_OP_PRECEDENCE(6),
156     NE = 6 | BINARY_OP_PRECEDENCE(6),
157     STREQ = 7 | BINARY_OP_PRECEDENCE(6),
158     STRNEQ = 8 | BINARY_OP_PRECEDENCE(6),
159     LT = 9 | BINARY_OP_PRECEDENCE(7),
160     GT = 10 | BINARY_OP_PRECEDENCE(7),
161     LE = 11 | BINARY_OP_PRECEDENCE(7),
162     GE = 12 | BINARY_OP_PRECEDENCE(7),
163     INSTANCEOF = 13 | BINARY_OP_PRECEDENCE(7) | KeywordTokenFlag,
164     INTOKEN = 14 | IN_OP_PRECEDENCE(7) | KeywordTokenFlag,
165     LSHIFT = 15 | BINARY_OP_PRECEDENCE(8),
166     RSHIFT = 16 | BINARY_OP_PRECEDENCE(8),
167     URSHIFT = 17 | BINARY_OP_PRECEDENCE(8),
168     PLUS = 18 | BINARY_OP_PRECEDENCE(9) | UnaryOpTokenFlag,
169     MINUS = 19 | BINARY_OP_PRECEDENCE(9) | UnaryOpTokenFlag,
170     TIMES = 20 | BINARY_OP_PRECEDENCE(10),
171     DIVIDE = 21 | BINARY_OP_PRECEDENCE(10),
172     MOD = 22 | BINARY_OP_PRECEDENCE(10),
173     POW = 23 | BINARY_OP_PRECEDENCE(11) | RightAssociativeBinaryOpTokenFlag, // Make sure that POW has the highest operator precedence.
174     ERRORTOK = 0 | ErrorTokenFlag,
175     UNTERMINATED_IDENTIFIER_ESCAPE_ERRORTOK = 0 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
176     INVALID_IDENTIFIER_ESCAPE_ERRORTOK = 1 | ErrorTokenFlag,
177     UNTERMINATED_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK = 2 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
178     INVALID_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK = 3 | ErrorTokenFlag,
179     UNTERMINATED_MULTILINE_COMMENT_ERRORTOK = 4 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
180     UNTERMINATED_NUMERIC_LITERAL_ERRORTOK = 5 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
181     UNTERMINATED_OCTAL_NUMBER_ERRORTOK = 6 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
182     INVALID_NUMERIC_LITERAL_ERRORTOK = 7 | ErrorTokenFlag,
183     UNTERMINATED_STRING_LITERAL_ERRORTOK = 8 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
184     INVALID_STRING_LITERAL_ERRORTOK = 9 | ErrorTokenFlag,
185     INVALID_PRIVATE_NAME_ERRORTOK = 10 | ErrorTokenFlag,
186     UNTERMINATED_HEX_NUMBER_ERRORTOK = 11 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
187     UNTERMINATED_BINARY_NUMBER_ERRORTOK = 12 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
188     UNTERMINATED_TEMPLATE_LITERAL_ERRORTOK = 13 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
189     UNTERMINATED_REGEXP_LITERAL_ERRORTOK = 14 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
190     INVALID_TEMPLATE_LITERAL_ERRORTOK = 15 | ErrorTokenFlag,
191     UNEXPECTED_ESCAPE_ERRORTOK = 16 | ErrorTokenFlag,
192 };
193
194 struct JSTextPosition {
195     JSTextPosition() : line(0), offset(0), lineStartOffset(0) { }
196     JSTextPosition(int _line, int _offset, int _lineStartOffset) : line(_line), offset(_offset), lineStartOffset(_lineStartOffset) { }
197     JSTextPosition(const JSTextPosition& other) : line(other.line), offset(other.offset), lineStartOffset(other.lineStartOffset) { }
198
199     JSTextPosition operator+(int adjustment) const { return JSTextPosition(line, offset + adjustment, lineStartOffset); }
200     JSTextPosition operator+(unsigned adjustment) const { return *this + static_cast<int>(adjustment); }
201     JSTextPosition operator-(int adjustment) const { return *this + (- adjustment); }
202     JSTextPosition operator-(unsigned adjustment) const { return *this + (- static_cast<int>(adjustment)); }
203
204     operator int() const { return offset; }
205
206     int line;
207     int offset;
208     int lineStartOffset;
209 };
210
211 union JSTokenData {
212     struct {
213         uint32_t line;
214         uint32_t offset;
215         uint32_t lineStartOffset;
216     };
217     double doubleValue;
218     const Identifier* ident;
219     struct {
220         const Identifier* cooked;
221         const Identifier* raw;
222         bool isTail;
223     };
224     struct {
225         const Identifier* pattern;
226         const Identifier* flags;
227     };
228 };
229
230 struct JSTokenLocation {
231     JSTokenLocation() : line(0), lineStartOffset(0), startOffset(0) { }
232     JSTokenLocation(const JSTokenLocation& location)
233     {
234         line = location.line;
235         lineStartOffset = location.lineStartOffset;
236         startOffset = location.startOffset;
237         endOffset = location.endOffset;
238     }
239
240     int line;
241     unsigned lineStartOffset;
242     unsigned startOffset;
243     unsigned endOffset;
244 };
245
246 struct JSToken {
247     JSTokenType m_type;
248     JSTokenData m_data;
249     JSTokenLocation m_location;
250     JSTextPosition m_startPosition;
251     JSTextPosition m_endPosition;
252 };
253
254 ALWAYS_INLINE bool isUpdateOp(JSTokenType token)
255 {
256     return token >= PLUSPLUS && token <= AUTOMINUSMINUS;
257 }
258
259 ALWAYS_INLINE bool isUnaryOp(JSTokenType token)
260 {
261     return token & UnaryOpTokenFlag;
262 }
263
264 } // namespace JSC