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#ifndef ParserTokens_h
27#define ParserTokens_h
28
29#include "ParserModes.h"
30#include <limits.h>
31#include <stdint.h>
32
33namespace JSC {
34
35class Identifier;
36
37enum {
38    UnaryOpTokenFlag = 64,
39    KeywordTokenFlag = 128,
40    BinaryOpTokenPrecedenceShift = 8,
41    BinaryOpTokenAllowsInPrecedenceAdditionalShift = 4,
42    BinaryOpTokenPrecedenceMask = 15 << BinaryOpTokenPrecedenceShift,
43    ErrorTokenFlag = 1 << (BinaryOpTokenAllowsInPrecedenceAdditionalShift + BinaryOpTokenPrecedenceShift + 7),
44    UnterminatedErrorTokenFlag = ErrorTokenFlag << 1
45};
46
47#define BINARY_OP_PRECEDENCE(prec) (((prec) << BinaryOpTokenPrecedenceShift) | ((prec) << (BinaryOpTokenPrecedenceShift + BinaryOpTokenAllowsInPrecedenceAdditionalShift)))
48#define IN_OP_PRECEDENCE(prec) ((prec) << (BinaryOpTokenPrecedenceShift + BinaryOpTokenAllowsInPrecedenceAdditionalShift))
49
50enum JSTokenType {
51    NULLTOKEN = KeywordTokenFlag,
52    TRUETOKEN,
53    FALSETOKEN,
54    BREAK,
55    CASE,
56    DEFAULT,
57    FOR,
58    NEW,
59    VAR,
60    CONSTTOKEN,
61    CONTINUE,
62    FUNCTION,
63    RETURN,
64    IF,
65    THISTOKEN,
66    DO,
67    WHILE,
68    SWITCH,
69    WITH,
70    RESERVED,
71    RESERVED_IF_STRICT,
72    THROW,
73    TRY,
74    CATCH,
75    FINALLY,
76    DEBUGGER,
77    ELSE,
78    OPENBRACE = 0,
79    CLOSEBRACE,
80    OPENPAREN,
81    CLOSEPAREN,
82    OPENBRACKET,
83    CLOSEBRACKET,
84    COMMA,
85    QUESTION,
86    NUMBER,
87    IDENT,
88    STRING,
89    SEMICOLON,
90    COLON,
91    DOT,
92    EOFTOK,
93    EQUAL,
94    PLUSEQUAL,
95    MINUSEQUAL,
96    MULTEQUAL,
97    DIVEQUAL,
98    LSHIFTEQUAL,
99    RSHIFTEQUAL,
100    URSHIFTEQUAL,
101    ANDEQUAL,
102    MODEQUAL,
103    XOREQUAL,
104    OREQUAL,
105    DOTDOTDOT,
106    LastUntaggedToken,
107
108    // Begin tagged tokens
109    PLUSPLUS = 0 | UnaryOpTokenFlag,
110    MINUSMINUS = 1 | UnaryOpTokenFlag,
111    EXCLAMATION = 2 | UnaryOpTokenFlag,
112    TILDE = 3 | UnaryOpTokenFlag,
113    AUTOPLUSPLUS = 4 | UnaryOpTokenFlag,
114    AUTOMINUSMINUS = 5 | UnaryOpTokenFlag,
115    TYPEOF = 6 | UnaryOpTokenFlag | KeywordTokenFlag,
116    VOIDTOKEN = 7 | UnaryOpTokenFlag | KeywordTokenFlag,
117    DELETETOKEN = 8 | UnaryOpTokenFlag | KeywordTokenFlag,
118    OR = 0 | BINARY_OP_PRECEDENCE(1),
119    AND = 1 | BINARY_OP_PRECEDENCE(2),
120    BITOR = 2 | BINARY_OP_PRECEDENCE(3),
121    BITXOR = 3 | BINARY_OP_PRECEDENCE(4),
122    BITAND = 4 | BINARY_OP_PRECEDENCE(5),
123    EQEQ = 5 | BINARY_OP_PRECEDENCE(6),
124    NE = 6 | BINARY_OP_PRECEDENCE(6),
125    STREQ = 7 | BINARY_OP_PRECEDENCE(6),
126    STRNEQ = 8 | BINARY_OP_PRECEDENCE(6),
127    LT = 9 | BINARY_OP_PRECEDENCE(7),
128    GT = 10 | BINARY_OP_PRECEDENCE(7),
129    LE = 11 | BINARY_OP_PRECEDENCE(7),
130    GE = 12 | BINARY_OP_PRECEDENCE(7),
131    INSTANCEOF = 13 | BINARY_OP_PRECEDENCE(7) | KeywordTokenFlag,
132    INTOKEN = 14 | IN_OP_PRECEDENCE(7) | KeywordTokenFlag,
133    LSHIFT = 15 | BINARY_OP_PRECEDENCE(8),
134    RSHIFT = 16 | BINARY_OP_PRECEDENCE(8),
135    URSHIFT = 17 | BINARY_OP_PRECEDENCE(8),
136    PLUS = 18 | BINARY_OP_PRECEDENCE(9) | UnaryOpTokenFlag,
137    MINUS = 19 | BINARY_OP_PRECEDENCE(9) | UnaryOpTokenFlag,
138    TIMES = 20 | BINARY_OP_PRECEDENCE(10),
139    DIVIDE = 21 | BINARY_OP_PRECEDENCE(10),
140    MOD = 22 | BINARY_OP_PRECEDENCE(10),
141    ERRORTOK = 0 | ErrorTokenFlag,
142    UNTERMINATED_IDENTIFIER_ESCAPE_ERRORTOK = 0 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
143    INVALID_IDENTIFIER_ESCAPE_ERRORTOK = 1 | ErrorTokenFlag,
144    UNTERMINATED_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK = 2 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
145    INVALID_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK = 3 | ErrorTokenFlag,
146    UNTERMINATED_MULTILINE_COMMENT_ERRORTOK = 4 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
147    UNTERMINATED_NUMERIC_LITERAL_ERRORTOK = 5 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
148    INVALID_OCTAL_NUMBER_ERRORTOK = 6 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
149    INVALID_NUMERIC_LITERAL_ERRORTOK = 7 | ErrorTokenFlag,
150    UNTERMINATED_STRING_LITERAL_ERRORTOK = 8 | ErrorTokenFlag | UnterminatedErrorTokenFlag,
151    INVALID_STRING_LITERAL_ERRORTOK = 9 | ErrorTokenFlag,
152    INVALID_PRIVATE_NAME_ERRORTOK = 10 | ErrorTokenFlag,
153    INVALID_HEX_NUMBER_ERRORTOK = 11 | ErrorTokenFlag
154};
155
156struct JSTextPosition {
157    JSTextPosition() : line(0), offset(0), lineStartOffset(0) { }
158    JSTextPosition(int _line, int _offset, int _lineStartOffset) : line(_line), offset(_offset), lineStartOffset(_lineStartOffset) { }
159    JSTextPosition(const JSTextPosition& other) : line(other.line), offset(other.offset), lineStartOffset(other.lineStartOffset) { }
160
161    JSTextPosition operator+(int adjustment) const { return JSTextPosition(line, offset + adjustment, lineStartOffset); }
162    JSTextPosition operator+(unsigned adjustment) const { return *this + static_cast<int>(adjustment); }
163    JSTextPosition operator-(int adjustment) const { return *this + (- adjustment); }
164    JSTextPosition operator-(unsigned adjustment) const { return *this + (- static_cast<int>(adjustment)); }
165
166    operator int() const { return offset; }
167
168    int line;
169    int offset;
170    int lineStartOffset;
171};
172
173union JSTokenData {
174    struct {
175        uint32_t line;
176        uint32_t offset;
177        uint32_t lineStartOffset;
178    };
179    double doubleValue;
180    const Identifier* ident;
181};
182
183struct JSTokenLocation {
184    JSTokenLocation() : line(0), lineStartOffset(0), startOffset(0) { }
185    JSTokenLocation(const JSTokenLocation& location)
186    {
187        line = location.line;
188        lineStartOffset = location.lineStartOffset;
189        startOffset = location.startOffset;
190        endOffset = location.endOffset;
191    }
192
193    int line;
194    unsigned lineStartOffset;
195    unsigned startOffset;
196    unsigned endOffset;
197};
198
199struct JSToken {
200    JSTokenType m_type;
201    JSTokenData m_data;
202    JSTokenLocation m_location;
203    JSTextPosition m_startPosition;
204    JSTextPosition m_endPosition;
205};
206
207} // namespace JSC
208
209#endif // ParserTokens_h
210