2011-05-24 Oliver Hunt <oliver@apple.com>
[WebKit-https.git] / Source / JavaScriptCore / parser / SyntaxChecker.h
1 /*
2  * Copyright (C) 2010 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 SyntaxChecker_h
27 #define SyntaxChecker_h
28
29 #include "Lexer.h"
30 #include <yarr/YarrSyntaxChecker.h>
31
32 namespace JSC {
33 class SyntaxChecker {
34 public:
35     struct BinaryExprContext {
36         BinaryExprContext(SyntaxChecker& context)
37             : m_context(&context)
38         {
39             m_context->m_topBinaryExprs.append(m_context->m_topBinaryExpr);
40             m_context->m_topBinaryExpr = 0;
41         }
42         ~BinaryExprContext()
43         {
44             m_context->m_topBinaryExpr = m_context->m_topBinaryExprs.last();
45             m_context->m_topBinaryExprs.removeLast();
46         }
47     private:
48         SyntaxChecker* m_context;
49     };
50     struct UnaryExprContext {
51         UnaryExprContext(SyntaxChecker& context)
52             : m_context(&context)
53         {
54             m_context->m_topUnaryTokens.append(m_context->m_topUnaryToken);
55             m_context->m_topUnaryToken = 0;
56         }
57         ~UnaryExprContext()
58         {
59             m_context->m_topUnaryToken = m_context->m_topUnaryTokens.last();
60             m_context->m_topUnaryTokens.removeLast();
61         }
62     private:
63         SyntaxChecker* m_context;
64     };
65     
66     SyntaxChecker(JSGlobalData* , Lexer*)
67     {
68     }
69
70     typedef SyntaxChecker FunctionBodyBuilder;
71     enum { NoneExpr = 0,
72         ResolveEvalExpr, ResolveExpr, NumberExpr, StringExpr,
73         ThisExpr, NullExpr, BoolExpr, RegExpExpr, ObjectLiteralExpr,
74         FunctionExpr, BracketExpr, DotExpr, CallExpr,
75         NewExpr, PreExpr, PostExpr, UnaryExpr, BinaryExpr,
76         ConditionalExpr, AssignmentExpr, TypeofExpr,
77         DeleteExpr, ArrayLiteralExpr };
78     typedef int ExpressionType;
79
80     typedef ExpressionType Expression;
81     typedef int SourceElements;
82     typedef int Arguments;
83     typedef ExpressionType Comma;
84     struct Property {
85         ALWAYS_INLINE Property(void* = 0)
86             : type((PropertyNode::Type)0)
87         {
88         }
89         ALWAYS_INLINE Property(const Identifier* ident, PropertyNode::Type ty)
90         : name(ident)
91         , type(ty)
92         {
93         }
94         ALWAYS_INLINE Property(PropertyNode::Type ty)
95             : name(0)
96             , type(ty)
97         {
98         }
99         ALWAYS_INLINE bool operator!() { return !type; }
100         const Identifier* name;
101         PropertyNode::Type type;
102     };
103     typedef int PropertyList;
104     typedef int ElementList;
105     typedef int ArgumentsList;
106     typedef int FormalParameterList;
107     typedef int FunctionBody;
108     typedef int Statement;
109     typedef int ClauseList;
110     typedef int Clause;
111     typedef int ConstDeclList;
112     typedef int BinaryOperand;
113     
114     static const bool CreatesAST = false;
115     static const bool NeedsFreeVariableInfo = false;
116     static const bool CanUseFunctionCache = true;
117     static const unsigned DontBuildKeywords = Lexer::DontBuildKeywords;
118     static const unsigned DontBuildStrings = Lexer::DontBuildStrings;
119
120     int createSourceElements() { return 1; }
121     ExpressionType makeFunctionCallNode(int, int, int, int, int) { return CallExpr; }
122     void appendToComma(ExpressionType& base, ExpressionType right) { base = right; }
123     ExpressionType createCommaExpr(ExpressionType, ExpressionType right) { return right; }
124     ExpressionType makeAssignNode(ExpressionType, Operator, ExpressionType, bool, bool, int, int, int) { return AssignmentExpr; }
125     ExpressionType makePrefixNode(ExpressionType, Operator, int, int, int) { return PreExpr; }
126     ExpressionType makePostfixNode(ExpressionType, Operator, int, int, int) { return PostExpr; }
127     ExpressionType makeTypeOfNode(ExpressionType) { return TypeofExpr; }
128     ExpressionType makeDeleteNode(ExpressionType, int, int, int) { return DeleteExpr; }
129     ExpressionType makeNegateNode(ExpressionType) { return UnaryExpr; }
130     ExpressionType makeBitwiseNotNode(ExpressionType) { return UnaryExpr; }
131     ExpressionType createLogicalNot(ExpressionType) { return UnaryExpr; }
132     ExpressionType createUnaryPlus(ExpressionType) { return UnaryExpr; }
133     ExpressionType createVoid(ExpressionType) { return UnaryExpr; }
134     ExpressionType thisExpr() { return ThisExpr; }
135     ExpressionType createResolve(const Identifier*, int) { return ResolveExpr; }
136     ExpressionType createObjectLiteral() { return ObjectLiteralExpr; }
137     ExpressionType createObjectLiteral(int) { return ObjectLiteralExpr; }
138     ExpressionType createArray(int) { return ArrayLiteralExpr; }
139     ExpressionType createArray(int, int) { return ArrayLiteralExpr; }
140     ExpressionType createNumberExpr(double) { return NumberExpr; }
141     ExpressionType createString(const Identifier*) { return StringExpr; }
142     ExpressionType createBoolean(bool) { return BoolExpr; }
143     ExpressionType createNull() { return NullExpr; }
144     ExpressionType createBracketAccess(ExpressionType, ExpressionType, bool, int, int, int) { return BracketExpr; }
145     ExpressionType createDotAccess(ExpressionType, const Identifier*, int, int, int) { return DotExpr; }
146     ExpressionType createRegExp(const Identifier& pattern, const Identifier&, int) { return Yarr::checkSyntax(pattern.ustring()) ? 0 : RegExpExpr; }
147     ExpressionType createNewExpr(ExpressionType, int, int, int, int) { return NewExpr; }
148     ExpressionType createNewExpr(ExpressionType, int, int) { return NewExpr; }
149     ExpressionType createConditionalExpr(ExpressionType, ExpressionType, ExpressionType) { return ConditionalExpr; }
150     ExpressionType createAssignResolve(const Identifier&, ExpressionType, bool, int, int, int) { return AssignmentExpr; }
151     ExpressionType createFunctionExpr(const Identifier*, int, int, int, int, int, int) { return FunctionExpr; }
152     int createFunctionBody(bool) { return 1; }
153     int createArguments() { return 1; }
154     int createArguments(int) { return 1; }
155     int createArgumentsList(int) { return 1; }
156     int createArgumentsList(int, int) { return 1; }
157     template <bool complete> Property createProperty(const Identifier* name, int, PropertyNode::Type type)
158     {
159         if (!complete)
160             return Property(type);
161         ASSERT(name);
162         return Property(name, type);
163     }
164     template <bool complete> Property createProperty(JSGlobalData* globalData, double name, int, PropertyNode::Type type)
165     {
166         if (!complete)
167             return Property(type);
168         return Property(&globalData->parser->arena().identifierArena().makeNumericIdentifier(globalData, name), type);
169     }
170     int createPropertyList(Property) { return 1; }
171     int createPropertyList(Property, int) { return 1; }
172     int createElementList(int, int) { return 1; }
173     int createElementList(int, int, int) { return 1; }
174     int createFormalParameterList(const Identifier&) { return 1; }
175     int createFormalParameterList(int, const Identifier&) { return 1; }
176     int createClause(int, int) { return 1; }
177     int createClauseList(int) { return 1; }
178     int createClauseList(int, int) { return 1; }
179     void setUsesArguments(int) { }
180     int createFuncDeclStatement(const Identifier*, int, int, int, int, int, int) { return 1; }
181     int createBlockStatement(int, int, int) { return 1; }
182     int createExprStatement(int, int, int) { return 1; }
183     int createIfStatement(int, int, int, int) { return 1; }
184     int createIfStatement(int, int, int, int, int) { return 1; }
185     int createForLoop(int, int, int, int, bool, int, int) { return 1; }
186     int createForInLoop(const Identifier*, int, int, int, int, int, int, int, int, int, int) { return 1; }
187     int createForInLoop(int, int, int, int, int, int, int, int) { return 1; }
188     int createEmptyStatement() { return 1; }
189     int createVarStatement(int, int, int) { return 1; }
190     int createReturnStatement(int, int, int, int, int) { return 1; }
191     int createBreakStatement(int, int, int, int) { return 1; }
192     int createBreakStatement(const Identifier*, int, int, int, int) { return 1; }
193     int createContinueStatement(int, int, int, int) { return 1; }
194     int createContinueStatement(const Identifier*, int, int, int, int) { return 1; }
195     int createTryStatement(int, const Identifier*, bool, int, int, int, int) { return 1; }
196     int createSwitchStatement(int, int, int, int, int, int) { return 1; }
197     int createWhileStatement(int, int, int, int) { return 1; }
198     int createWithStatement(int, int, int, int, int, int) { return 1; }
199     int createDoWhileStatement(int, int, int, int) { return 1; }
200     int createLabelStatement(const Identifier*, int, int, int) { return 1; }
201     int createThrowStatement(int, int, int, int, int) { return 1; }
202     int createDebugger(int, int) { return 1; }
203     int createConstStatement(int, int, int) { return 1; }
204     int appendConstDecl(int, const Identifier*, int) { return 1; }
205     template <bool strict> Property createGetterOrSetterProperty(PropertyNode::Type type, const Identifier* name, int, int, int, int, int, int)
206     {
207         ASSERT(name);
208         if (!strict)
209             return Property(type);
210         return Property(name, type);
211     }
212
213     void appendStatement(int, int) { }
214     void addVar(const Identifier*, bool) { }
215     int combineCommaNodes(int, int) { return 1; }
216     int evalCount() const { return 0; }
217     void appendBinaryExpressionInfo(int& operandStackDepth, int expr, int, int, int, bool)
218     {
219         if (!m_topBinaryExpr)
220             m_topBinaryExpr = expr;
221         else
222             m_topBinaryExpr = BinaryExpr;
223         operandStackDepth++;
224     }
225     
226     // Logic to handle datastructures used during parsing of binary expressions
227     void operatorStackPop(int& operatorStackDepth) { operatorStackDepth--; }
228     bool operatorStackHasHigherPrecedence(int&, int) { return true; }
229     BinaryOperand getFromOperandStack(int) { return m_topBinaryExpr; }
230     void shrinkOperandStackBy(int& operandStackDepth, int amount) { operandStackDepth -= amount; }
231     void appendBinaryOperation(int& operandStackDepth, int&, BinaryOperand, BinaryOperand) { operandStackDepth++; }
232     void operatorStackAppend(int& operatorStackDepth, int, int) { operatorStackDepth++; }
233     int popOperandStack(int&) { int res = m_topBinaryExpr; m_topBinaryExpr = 0; return res; }
234     
235     void appendUnaryToken(int& stackDepth, int tok, int) { stackDepth = 1; m_topUnaryToken = tok; }
236     int unaryTokenStackLastType(int&) { return m_topUnaryToken; }
237     int unaryTokenStackLastStart(int&) { return 0; }
238     void unaryTokenStackRemoveLast(int& stackDepth) { stackDepth = 0; }
239     
240     void assignmentStackAppend(int, int, int, int, int, Operator) { }
241     int createAssignment(int, int, int, int, int) { ASSERT_NOT_REACHED(); return 1; }
242     const Identifier& getName(const Property& property) const { ASSERT(property.name); return *property.name; }
243     PropertyNode::Type getType(const Property& property) const { return property.type; }
244     bool isResolve(ExpressionType expr) const { return expr == ResolveExpr || expr == ResolveEvalExpr; }
245     
246 private:
247     int m_topBinaryExpr;
248     int m_topUnaryToken;
249     Vector<int, 8> m_topBinaryExprs;
250     Vector<int, 8> m_topUnaryTokens;
251 };
252
253 }
254
255 #endif