initial import
[vuplus_webkit] / Source / JavaScriptCore / parser / ASTBuilder.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 ASTBuilder_h
27 #define ASTBuilder_h
28
29 #include "NodeConstructors.h"
30 #include "SyntaxChecker.h"
31 #include <utility>
32
33 namespace JSC {
34
35 class ASTBuilder {
36     struct BinaryOpInfo {
37         BinaryOpInfo() {}
38         BinaryOpInfo(int s, int d, int e, bool r)
39             : start(s)
40             , divot(d)
41             , end(e)
42             , hasAssignment(r)
43         {
44         }
45         BinaryOpInfo(const BinaryOpInfo& lhs, const BinaryOpInfo& rhs)
46             : start(lhs.start)
47             , divot(rhs.start)
48             , end(rhs.end)
49             , hasAssignment(lhs.hasAssignment || rhs.hasAssignment)
50         {
51         }
52         int start;
53         int divot;
54         int end;
55         bool hasAssignment;
56     };
57     
58     
59     struct AssignmentInfo {
60         AssignmentInfo() {}
61         AssignmentInfo(ExpressionNode* node, int start, int divot, int initAssignments, Operator op)
62             : m_node(node)
63             , m_start(start)
64             , m_divot(divot)
65             , m_initAssignments(initAssignments)
66             , m_op(op)
67         {
68         }
69         ExpressionNode* m_node;
70         int m_start;
71         int m_divot;
72         int m_initAssignments;
73         Operator m_op;
74     };
75 public:
76     ASTBuilder(JSGlobalData* globalData, Lexer* lexer)
77         : m_globalData(globalData)
78         , m_lexer(lexer)
79         , m_scope(globalData)
80         , m_evalCount(0)
81     {
82     }
83     
84     struct BinaryExprContext {
85         BinaryExprContext(ASTBuilder&) {}
86     };
87     struct UnaryExprContext {
88         UnaryExprContext(ASTBuilder&) {}
89     };
90
91     typedef SyntaxChecker FunctionBodyBuilder;
92
93     typedef ExpressionNode* Expression;
94     typedef JSC::SourceElements* SourceElements;
95     typedef ArgumentsNode* Arguments;
96     typedef CommaNode* Comma;
97     typedef PropertyNode* Property;
98     typedef PropertyListNode* PropertyList;
99     typedef ElementNode* ElementList;
100     typedef ArgumentListNode* ArgumentsList;
101     typedef ParameterNode* FormalParameterList;
102     typedef FunctionBodyNode* FunctionBody;
103     typedef StatementNode* Statement;
104     typedef ClauseListNode* ClauseList;
105     typedef CaseClauseNode* Clause;
106     typedef ConstDeclNode* ConstDeclList;
107     typedef std::pair<ExpressionNode*, BinaryOpInfo> BinaryOperand;
108     
109     static const bool CreatesAST = true;
110     static const bool NeedsFreeVariableInfo = true;
111     static const bool CanUseFunctionCache = true;
112     static const int  DontBuildKeywords = 0;
113     static const int  DontBuildStrings = 0;
114
115     ExpressionNode* makeBinaryNode(int token, std::pair<ExpressionNode*, BinaryOpInfo>, std::pair<ExpressionNode*, BinaryOpInfo>);
116     ExpressionNode* makeFunctionCallNode(ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end);
117
118     JSC::SourceElements* createSourceElements() { return new (m_globalData) JSC::SourceElements(m_globalData); }
119
120     ParserArenaData<DeclarationStacks::VarStack>* varDeclarations() { return m_scope.m_varDeclarations; }
121     ParserArenaData<DeclarationStacks::FunctionStack>* funcDeclarations() { return m_scope.m_funcDeclarations; }
122     int features() const { return m_scope.m_features; }
123     int numConstants() const { return m_scope.m_numConstants; }
124
125     void appendToComma(CommaNode* commaNode, ExpressionNode* expr) { commaNode->append(expr); }
126
127     CommaNode* createCommaExpr(ExpressionNode* lhs, ExpressionNode* rhs) { return new (m_globalData) CommaNode(m_globalData, lhs, rhs); }
128
129     ExpressionNode* makeAssignNode(ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, int start, int divot, int end);
130     ExpressionNode* makePrefixNode(ExpressionNode*, Operator, int start, int divot, int end);
131     ExpressionNode* makePostfixNode(ExpressionNode*, Operator, int start, int divot, int end);
132     ExpressionNode* makeTypeOfNode(ExpressionNode*);
133     ExpressionNode* makeDeleteNode(ExpressionNode*, int start, int divot, int end);
134     ExpressionNode* makeNegateNode(ExpressionNode*);
135     ExpressionNode* makeBitwiseNotNode(ExpressionNode*);
136     ExpressionNode* makeMultNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
137     ExpressionNode* makeDivNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
138     ExpressionNode* makeModNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
139     ExpressionNode* makeAddNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
140     ExpressionNode* makeSubNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
141     ExpressionNode* makeBitXOrNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
142     ExpressionNode* makeBitAndNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
143     ExpressionNode* makeBitOrNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
144     ExpressionNode* makeLeftShiftNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
145     ExpressionNode* makeRightShiftNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
146     ExpressionNode* makeURightShiftNode(ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
147
148     ExpressionNode* createLogicalNot(ExpressionNode* expr) { return new (m_globalData) LogicalNotNode(m_globalData, expr); }
149     ExpressionNode* createUnaryPlus(ExpressionNode* expr) { return new (m_globalData) UnaryPlusNode(m_globalData, expr); }
150     ExpressionNode* createVoid(ExpressionNode* expr)
151     {
152         incConstants();
153         return new (m_globalData) VoidNode(m_globalData, expr);
154     }
155     ExpressionNode* thisExpr()
156     {
157         usesThis();
158         return new (m_globalData) ThisNode(m_globalData);
159     }
160     ExpressionNode* createResolve(const Identifier* ident, int start)
161     {
162         if (m_globalData->propertyNames->arguments == *ident)
163             usesArguments();
164         return new (m_globalData) ResolveNode(m_globalData, *ident, start);
165     }
166     ExpressionNode* createObjectLiteral() { return new (m_globalData) ObjectLiteralNode(m_globalData); }
167     ExpressionNode* createObjectLiteral(PropertyListNode* properties) { return new (m_globalData) ObjectLiteralNode(m_globalData, properties); }
168
169     ExpressionNode* createArray(int elisions)
170     {
171         if (elisions)
172             incConstants();
173         return new (m_globalData) ArrayNode(m_globalData, elisions);
174     }
175
176     ExpressionNode* createArray(ElementNode* elems) { return new (m_globalData) ArrayNode(m_globalData, elems); }
177     ExpressionNode* createArray(int elisions, ElementNode* elems)
178     {
179         if (elisions)
180             incConstants();
181         return new (m_globalData) ArrayNode(m_globalData, elisions, elems);
182     }
183     ExpressionNode* createNumberExpr(double d)
184     {
185         incConstants();
186         return new (m_globalData) NumberNode(m_globalData, d);
187     }
188
189     ExpressionNode* createString(const Identifier* string)
190     {
191         incConstants();
192         return new (m_globalData) StringNode(m_globalData, *string);
193     }
194
195     ExpressionNode* createBoolean(bool b)
196     {
197         incConstants();
198         return new (m_globalData) BooleanNode(m_globalData, b);
199     }
200
201     ExpressionNode* createNull()
202     {
203         incConstants();
204         return new (m_globalData) NullNode(m_globalData);
205     }
206
207     ExpressionNode* createBracketAccess(ExpressionNode* base, ExpressionNode* property, bool propertyHasAssignments, int start, int divot, int end)
208     {
209         BracketAccessorNode* node = new (m_globalData) BracketAccessorNode(m_globalData, base, property, propertyHasAssignments);
210         setExceptionLocation(node, start, divot, end);
211         return node;
212     }
213
214     ExpressionNode* createDotAccess(ExpressionNode* base, const Identifier* property, int start, int divot, int end)
215     {
216         DotAccessorNode* node = new (m_globalData) DotAccessorNode(m_globalData, base, *property);
217         setExceptionLocation(node, start, divot, end);
218         return node;
219     }
220
221     ExpressionNode* createRegExp(const Identifier& pattern, const Identifier& flags, int start)
222     {
223         if (Yarr::checkSyntax(pattern.ustring()))
224             return 0;
225         RegExpNode* node = new (m_globalData) RegExpNode(m_globalData, pattern, flags);
226         int size = pattern.length() + 2; // + 2 for the two /'s
227         setExceptionLocation(node, start, start + size, start + size);
228         return node;
229     }
230
231     ExpressionNode* createNewExpr(ExpressionNode* expr, ArgumentsNode* arguments, int start, int divot, int end)
232     {
233         NewExprNode* node = new (m_globalData) NewExprNode(m_globalData, expr, arguments);
234         setExceptionLocation(node, start, divot, end);
235         return node;
236     }
237
238     ExpressionNode* createNewExpr(ExpressionNode* expr, int start, int end)
239     {
240         NewExprNode* node = new (m_globalData) NewExprNode(m_globalData, expr);
241         setExceptionLocation(node, start, end, end);
242         return node;
243     }
244
245     ExpressionNode* createConditionalExpr(ExpressionNode* condition, ExpressionNode* lhs, ExpressionNode* rhs)
246     {
247         return new (m_globalData) ConditionalNode(m_globalData, condition, lhs, rhs);
248     }
249
250     ExpressionNode* createAssignResolve(const Identifier& ident, ExpressionNode* rhs, bool rhsHasAssignment, int start, int divot, int end)
251     {
252         AssignResolveNode* node = new (m_globalData) AssignResolveNode(m_globalData, ident, rhs, rhsHasAssignment);
253         setExceptionLocation(node, start, divot, end);
254         return node;
255     }
256
257     ExpressionNode* createFunctionExpr(const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
258     {
259         FuncExprNode* result = new (m_globalData) FuncExprNode(m_globalData, *name, body, m_lexer->sourceCode(openBracePos, closeBracePos, bodyStartLine), parameters);
260         body->setLoc(bodyStartLine, bodyEndLine);
261         return result;
262     }
263
264     FunctionBodyNode* createFunctionBody(bool inStrictContext)
265     {
266         usesClosures();
267         return FunctionBodyNode::create(m_globalData, inStrictContext);
268     }
269     
270     template <bool> PropertyNode* createGetterOrSetterProperty(PropertyNode::Type type, const Identifier* name, ParameterNode* params, FunctionBodyNode* body, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
271     {
272         ASSERT(name);
273         body->setLoc(bodyStartLine, bodyEndLine);
274         return new (m_globalData) PropertyNode(m_globalData, *name, new (m_globalData) FuncExprNode(m_globalData, m_globalData->propertyNames->nullIdentifier, body, m_lexer->sourceCode(openBracePos, closeBracePos, bodyStartLine), params), type);
275     }
276     
277
278     ArgumentsNode* createArguments() { return new (m_globalData) ArgumentsNode(m_globalData); }
279     ArgumentsNode* createArguments(ArgumentListNode* args) { return new (m_globalData) ArgumentsNode(m_globalData, args); }
280     ArgumentListNode* createArgumentsList(ExpressionNode* arg) { return new (m_globalData) ArgumentListNode(m_globalData, arg); }
281     ArgumentListNode* createArgumentsList(ArgumentListNode* args, ExpressionNode* arg) { return new (m_globalData) ArgumentListNode(m_globalData, args, arg); }
282
283     template <bool> PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type) { return new (m_globalData) PropertyNode(m_globalData, *propertyName, node, type); }
284     template <bool> PropertyNode* createProperty(JSGlobalData*, double propertyName, ExpressionNode* node, PropertyNode::Type type) { return new (m_globalData) PropertyNode(m_globalData, propertyName, node, type); }
285     PropertyListNode* createPropertyList(PropertyNode* property) { return new (m_globalData) PropertyListNode(m_globalData, property); }
286     PropertyListNode* createPropertyList(PropertyNode* property, PropertyListNode* tail) { return new (m_globalData) PropertyListNode(m_globalData, property, tail); }
287
288     ElementNode* createElementList(int elisions, ExpressionNode* expr) { return new (m_globalData) ElementNode(m_globalData, elisions, expr); }
289     ElementNode* createElementList(ElementNode* elems, int elisions, ExpressionNode* expr) { return new (m_globalData) ElementNode(m_globalData, elems, elisions, expr); }
290
291     ParameterNode* createFormalParameterList(const Identifier& ident) { return new (m_globalData) ParameterNode(m_globalData, ident); }
292     ParameterNode* createFormalParameterList(ParameterNode* list, const Identifier& ident) { return new (m_globalData) ParameterNode(m_globalData, list, ident); }
293
294     CaseClauseNode* createClause(ExpressionNode* expr, JSC::SourceElements* statements) { return new (m_globalData) CaseClauseNode(m_globalData, expr, statements); }
295     ClauseListNode* createClauseList(CaseClauseNode* clause) { return new (m_globalData) ClauseListNode(m_globalData, clause); }
296     ClauseListNode* createClauseList(ClauseListNode* tail, CaseClauseNode* clause) { return new (m_globalData) ClauseListNode(m_globalData, tail, clause); }
297
298     void setUsesArguments(FunctionBodyNode* node) { node->setUsesArguments(); }
299
300     StatementNode* createFuncDeclStatement(const Identifier* name, FunctionBodyNode* body, ParameterNode* parameters, int openBracePos, int closeBracePos, int bodyStartLine, int bodyEndLine)
301     {
302         FuncDeclNode* decl = new (m_globalData) FuncDeclNode(m_globalData, *name, body, m_lexer->sourceCode(openBracePos, closeBracePos, bodyStartLine), parameters);
303         if (*name == m_globalData->propertyNames->arguments)
304             usesArguments();
305         m_scope.m_funcDeclarations->data.append(decl->body());
306         body->setLoc(bodyStartLine, bodyEndLine);
307         return decl;
308     }
309
310     StatementNode* createBlockStatement(JSC::SourceElements* elements, int startLine, int endLine)
311     {
312         BlockNode* block = new (m_globalData) BlockNode(m_globalData, elements);
313         block->setLoc(startLine, endLine);
314         return block;
315     }
316
317     StatementNode* createExprStatement(ExpressionNode* expr, int start, int end)
318     {
319         ExprStatementNode* result = new (m_globalData) ExprStatementNode(m_globalData, expr);
320         result->setLoc(start, end);
321         return result;
322     }
323
324     StatementNode* createIfStatement(ExpressionNode* condition, StatementNode* trueBlock, int start, int end)
325     {
326         IfNode* result = new (m_globalData) IfNode(m_globalData, condition, trueBlock);
327         result->setLoc(start, end);
328         return result;
329     }
330
331     StatementNode* createIfStatement(ExpressionNode* condition, StatementNode* trueBlock, StatementNode* falseBlock, int start, int end)
332     {
333         IfNode* result = new (m_globalData) IfElseNode(m_globalData, condition, trueBlock, falseBlock);
334         result->setLoc(start, end);
335         return result;
336     }
337
338     StatementNode* createForLoop(ExpressionNode* initializer, ExpressionNode* condition, ExpressionNode* iter, StatementNode* statements, bool b, int start, int end)
339     {
340         ForNode* result = new (m_globalData) ForNode(m_globalData, initializer, condition, iter, statements, b);
341         result->setLoc(start, end);
342         return result;
343     }
344
345     StatementNode* createForInLoop(const Identifier* ident, ExpressionNode* initializer, ExpressionNode* iter, StatementNode* statements, int start, int divot, int end, int initStart, int initEnd, int startLine, int endLine)
346     {
347         ForInNode* result = new (m_globalData) ForInNode(m_globalData, *ident, initializer, iter, statements, initStart, initStart - start, initEnd - initStart);
348         result->setLoc(startLine, endLine);
349         setExceptionLocation(result, start, divot + 1, end);
350         return result;
351     }
352
353     StatementNode* createForInLoop(ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, int eStart, int eDivot, int eEnd, int start, int end)
354     {
355         ForInNode* result = new (m_globalData) ForInNode(m_globalData, lhs, iter, statements);
356         result->setLoc(start, end);
357         setExceptionLocation(result, eStart, eDivot, eEnd);
358         return result;
359     }
360
361     StatementNode* createEmptyStatement() { return new (m_globalData) EmptyStatementNode(m_globalData); }
362
363     StatementNode* createVarStatement(ExpressionNode* expr, int start, int end)
364     {
365         StatementNode* result;
366         if (!expr)
367             result = new (m_globalData) EmptyStatementNode(m_globalData);
368         else
369             result = new (m_globalData) VarStatementNode(m_globalData, expr);
370         result->setLoc(start, end);
371         return result;
372     }
373
374     StatementNode* createReturnStatement(ExpressionNode* expression, int eStart, int eEnd, int startLine, int endLine)
375     {
376         ReturnNode* result = new (m_globalData) ReturnNode(m_globalData, expression);
377         setExceptionLocation(result, eStart, eEnd, eEnd);
378         result->setLoc(startLine, endLine);
379         return result;
380     }
381
382     StatementNode* createBreakStatement(int eStart, int eEnd, int startLine, int endLine)
383     {
384         BreakNode* result = new (m_globalData) BreakNode(m_globalData);
385         setExceptionLocation(result, eStart, eEnd, eEnd);
386         result->setLoc(startLine, endLine);
387         return result;
388     }
389
390     StatementNode* createBreakStatement(const Identifier* ident, int eStart, int eEnd, int startLine, int endLine)
391     {
392         BreakNode* result = new (m_globalData) BreakNode(m_globalData, *ident);
393         setExceptionLocation(result, eStart, eEnd, eEnd);
394         result->setLoc(startLine, endLine);
395         return result;
396     }
397
398     StatementNode* createContinueStatement(int eStart, int eEnd, int startLine, int endLine)
399     {
400         ContinueNode* result = new (m_globalData) ContinueNode(m_globalData);
401         setExceptionLocation(result, eStart, eEnd, eEnd);
402         result->setLoc(startLine, endLine);
403         return result;
404     }
405
406     StatementNode* createContinueStatement(const Identifier* ident, int eStart, int eEnd, int startLine, int endLine)
407     {
408         ContinueNode* result = new (m_globalData) ContinueNode(m_globalData, *ident);
409         setExceptionLocation(result, eStart, eEnd, eEnd);
410         result->setLoc(startLine, endLine);
411         return result;
412     }
413
414     StatementNode* createTryStatement(StatementNode* tryBlock, const Identifier* ident, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine)
415     {
416         TryNode* result = new (m_globalData) TryNode(m_globalData, tryBlock, *ident, catchHasEval, catchBlock, finallyBlock);
417         if (catchBlock)
418             usesCatch();
419         result->setLoc(startLine, endLine);
420         return result;
421     }
422
423     StatementNode* createSwitchStatement(ExpressionNode* expr, ClauseListNode* firstClauses, CaseClauseNode* defaultClause, ClauseListNode* secondClauses, int startLine, int endLine)
424     {
425         CaseBlockNode* cases = new (m_globalData) CaseBlockNode(m_globalData, firstClauses, defaultClause, secondClauses);
426         SwitchNode* result = new (m_globalData) SwitchNode(m_globalData, expr, cases);
427         result->setLoc(startLine, endLine);
428         return result;
429     }
430
431     StatementNode* createWhileStatement(ExpressionNode* expr, StatementNode* statement, int startLine, int endLine)
432     {
433         WhileNode* result = new (m_globalData) WhileNode(m_globalData, expr, statement);
434         result->setLoc(startLine, endLine);
435         return result;
436     }
437
438     StatementNode* createDoWhileStatement(StatementNode* statement, ExpressionNode* expr, int startLine, int endLine)
439     {
440         DoWhileNode* result = new (m_globalData) DoWhileNode(m_globalData, statement, expr);
441         result->setLoc(startLine, endLine);
442         return result;
443     }
444
445     StatementNode* createLabelStatement(const Identifier* ident, StatementNode* statement, int start, int end)
446     {
447         LabelNode* result = new (m_globalData) LabelNode(m_globalData, *ident, statement);
448         setExceptionLocation(result, start, end, end);
449         return result;
450     }
451
452     StatementNode* createWithStatement(ExpressionNode* expr, StatementNode* statement, int start, int end, int startLine, int endLine)
453     {
454         usesWith();
455         WithNode* result = new (m_globalData) WithNode(m_globalData, expr, statement, end, end - start);
456         result->setLoc(startLine, endLine);
457         return result;
458     }    
459     
460     StatementNode* createThrowStatement(ExpressionNode* expr, int start, int end, int startLine, int endLine)
461     {
462         ThrowNode* result = new (m_globalData) ThrowNode(m_globalData, expr);
463         result->setLoc(startLine, endLine);
464         setExceptionLocation(result, start, end, end);
465         return result;
466     }
467     
468     StatementNode* createDebugger(int startLine, int endLine)
469     {
470         DebuggerStatementNode* result = new (m_globalData) DebuggerStatementNode(m_globalData);
471         result->setLoc(startLine, endLine);
472         return result;
473     }
474     
475     StatementNode* createConstStatement(ConstDeclNode* decls, int startLine, int endLine)
476     {
477         ConstStatementNode* result = new (m_globalData) ConstStatementNode(m_globalData, decls);
478         result->setLoc(startLine, endLine);
479         return result;
480     }
481
482     ConstDeclNode* appendConstDecl(ConstDeclNode* tail, const Identifier* name, ExpressionNode* initializer)
483     {
484         ConstDeclNode* result = new (m_globalData) ConstDeclNode(m_globalData, *name, initializer);
485         if (tail)
486             tail->m_next = result;
487         return result;
488     }
489
490     void appendStatement(JSC::SourceElements* elements, JSC::StatementNode* statement)
491     {
492         elements->append(statement);
493     }
494
495     void addVar(const Identifier* ident, int attrs)
496     {
497         if (m_globalData->propertyNames->arguments == *ident)
498             usesArguments();
499         m_scope.m_varDeclarations->data.append(std::make_pair(ident, attrs));
500     }
501
502     ExpressionNode* combineCommaNodes(ExpressionNode* list, ExpressionNode* init)
503     {
504         if (!list)
505             return init;
506         if (list->isCommaNode()) {
507             static_cast<CommaNode*>(list)->append(init);
508             return list;
509         }
510         return new (m_globalData) CommaNode(m_globalData, list, init);
511     }
512
513     int evalCount() const { return m_evalCount; }
514
515     void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, int exprStart, int lhs, int rhs, bool hasAssignments)
516     {
517         operandStackDepth++;
518         m_binaryOperandStack.append(std::make_pair(current, BinaryOpInfo(exprStart, lhs, rhs, hasAssignments)));
519     }
520
521     // Logic to handle datastructures used during parsing of binary expressions
522     void operatorStackPop(int& operatorStackDepth)
523     {
524         operatorStackDepth--;
525         m_binaryOperatorStack.removeLast();
526     }
527     bool operatorStackHasHigherPrecedence(int&, int precedence)
528     {
529         return precedence <= m_binaryOperatorStack.last().second;
530     }
531     const BinaryOperand& getFromOperandStack(int i) { return m_binaryOperandStack[m_binaryOperandStack.size() + i]; }
532     void shrinkOperandStackBy(int& operandStackDepth, int amount)
533     {
534         operandStackDepth -= amount;
535         ASSERT(operandStackDepth >= 0);
536         m_binaryOperandStack.resize(m_binaryOperandStack.size() - amount);
537     }
538     void appendBinaryOperation(int& operandStackDepth, int&, const BinaryOperand& lhs, const BinaryOperand& rhs)
539     {
540         operandStackDepth++;
541         m_binaryOperandStack.append(std::make_pair(makeBinaryNode(m_binaryOperatorStack.last().first, lhs, rhs), BinaryOpInfo(lhs.second, rhs.second)));
542     }
543     void operatorStackAppend(int& operatorStackDepth, int op, int precedence)
544     {
545         operatorStackDepth++;
546         m_binaryOperatorStack.append(std::make_pair(op, precedence));
547     }
548     ExpressionNode* popOperandStack(int&)
549     {
550         ExpressionNode* result = m_binaryOperandStack.last().first;
551         m_binaryOperandStack.removeLast();
552         return result;
553     }
554     
555     void appendUnaryToken(int& tokenStackDepth, int type, int start)
556     {
557         tokenStackDepth++;
558         m_unaryTokenStack.append(std::make_pair(type, start));
559     }
560
561     int unaryTokenStackLastType(int&)
562     {
563         return m_unaryTokenStack.last().first;
564     }
565     
566     int unaryTokenStackLastStart(int&)
567     {
568         return m_unaryTokenStack.last().second;
569     }
570     
571     void unaryTokenStackRemoveLast(int& tokenStackDepth)
572     {
573         tokenStackDepth--;
574         m_unaryTokenStack.removeLast();
575     }
576     
577     void assignmentStackAppend(int& assignmentStackDepth, ExpressionNode* node, int start, int divot, int assignmentCount, Operator op)
578     {
579         assignmentStackDepth++;
580         m_assignmentInfoStack.append(AssignmentInfo(node, start, divot, assignmentCount, op));
581     }
582
583     ExpressionNode* createAssignment(int& assignmentStackDepth, ExpressionNode* rhs, int initialAssignmentCount, int currentAssignmentCount, int lastTokenEnd)
584     {
585         ExpressionNode* result = makeAssignNode(m_assignmentInfoStack.last().m_node, m_assignmentInfoStack.last().m_op, rhs, m_assignmentInfoStack.last().m_initAssignments != initialAssignmentCount, m_assignmentInfoStack.last().m_initAssignments != currentAssignmentCount, m_assignmentInfoStack.last().m_start, m_assignmentInfoStack.last().m_divot + 1, lastTokenEnd);
586         m_assignmentInfoStack.removeLast();
587         assignmentStackDepth--;
588         return result;
589     }
590     
591     const Identifier& getName(Property property) const { return property->name(); }
592     PropertyNode::Type getType(Property property) const { return property->type(); }
593
594     bool isResolve(ExpressionNode* expr) const { return expr->isResolveNode(); }
595
596 private:
597     struct Scope {
598         Scope(JSGlobalData* globalData)
599             : m_varDeclarations(new (globalData) ParserArenaData<DeclarationStacks::VarStack>)
600             , m_funcDeclarations(new (globalData) ParserArenaData<DeclarationStacks::FunctionStack>)
601             , m_features(0)
602             , m_numConstants(0)
603         {
604         }
605         ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
606         ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
607         int m_features;
608         int m_numConstants;
609     };
610
611     static void setExceptionLocation(ThrowableExpressionData* node, unsigned start, unsigned divot, unsigned end)
612     {
613         node->setExceptionSourceCode(divot, divot - start, end - divot);
614     }
615
616     void incConstants() { m_scope.m_numConstants++; }
617     void usesThis() { m_scope.m_features |= ThisFeature; }
618     void usesCatch() { m_scope.m_features |= CatchFeature; }
619     void usesClosures() { m_scope.m_features |= ClosureFeature; }
620     void usesArguments() { m_scope.m_features |= ArgumentsFeature; }
621     void usesAssignment() { m_scope.m_features |= AssignFeature; }
622     void usesWith() { m_scope.m_features |= WithFeature; }
623     void usesEval() 
624     {
625         m_evalCount++;
626         m_scope.m_features |= EvalFeature;
627     }
628     ExpressionNode* createNumber(double d)
629     {
630         return new (m_globalData) NumberNode(m_globalData, d);
631     }
632     
633     JSGlobalData* m_globalData;
634     Lexer* m_lexer;
635     Scope m_scope;
636     Vector<BinaryOperand, 10> m_binaryOperandStack;
637     Vector<AssignmentInfo, 10> m_assignmentInfoStack;
638     Vector<pair<int, int>, 10> m_binaryOperatorStack;
639     Vector<pair<int, int>, 10> m_unaryTokenStack;
640     int m_evalCount;
641 };
642
643 ExpressionNode* ASTBuilder::makeTypeOfNode(ExpressionNode* expr)
644 {
645     if (expr->isResolveNode()) {
646         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
647         return new (m_globalData) TypeOfResolveNode(m_globalData, resolve->identifier());
648     }
649     return new (m_globalData) TypeOfValueNode(m_globalData, expr);
650 }
651
652 ExpressionNode* ASTBuilder::makeDeleteNode(ExpressionNode* expr, int start, int divot, int end)
653 {
654     if (!expr->isLocation())
655         return new (m_globalData) DeleteValueNode(m_globalData, expr);
656     if (expr->isResolveNode()) {
657         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
658         return new (m_globalData) DeleteResolveNode(m_globalData, resolve->identifier(), divot, divot - start, end - divot);
659     }
660     if (expr->isBracketAccessorNode()) {
661         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
662         return new (m_globalData) DeleteBracketNode(m_globalData, bracket->base(), bracket->subscript(), divot, divot - start, end - divot);
663     }
664     ASSERT(expr->isDotAccessorNode());
665     DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
666     return new (m_globalData) DeleteDotNode(m_globalData, dot->base(), dot->identifier(), divot, divot - start, end - divot);
667 }
668
669 ExpressionNode* ASTBuilder::makeNegateNode(ExpressionNode* n)
670 {
671     if (n->isNumber()) {
672         NumberNode* numberNode = static_cast<NumberNode*>(n);
673         numberNode->setValue(-numberNode->value());
674         return numberNode;
675     }
676
677     return new (m_globalData) NegateNode(m_globalData, n);
678 }
679
680 ExpressionNode* ASTBuilder::makeBitwiseNotNode(ExpressionNode* expr)
681 {
682     if (expr->isNumber())
683         return createNumber(~toInt32(static_cast<NumberNode*>(expr)->value()));
684     return new (m_globalData) BitwiseNotNode(m_globalData, expr);
685 }
686
687 ExpressionNode* ASTBuilder::makeMultNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
688 {
689     expr1 = expr1->stripUnaryPlus();
690     expr2 = expr2->stripUnaryPlus();
691
692     if (expr1->isNumber() && expr2->isNumber())
693         return createNumber(static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value());
694
695     if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1)
696         return new (m_globalData) UnaryPlusNode(m_globalData, expr2);
697
698     if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1)
699         return new (m_globalData) UnaryPlusNode(m_globalData, expr1);
700
701     return new (m_globalData) MultNode(m_globalData, expr1, expr2, rightHasAssignments);
702 }
703
704 ExpressionNode* ASTBuilder::makeDivNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
705 {
706     expr1 = expr1->stripUnaryPlus();
707     expr2 = expr2->stripUnaryPlus();
708
709     if (expr1->isNumber() && expr2->isNumber())
710         return createNumber(static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value());
711     return new (m_globalData) DivNode(m_globalData, expr1, expr2, rightHasAssignments);
712 }
713
714 ExpressionNode* ASTBuilder::makeModNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
715 {
716     expr1 = expr1->stripUnaryPlus();
717     expr2 = expr2->stripUnaryPlus();
718     
719     if (expr1->isNumber() && expr2->isNumber())
720         return createNumber(fmod(static_cast<NumberNode*>(expr1)->value(), static_cast<NumberNode*>(expr2)->value()));
721     return new (m_globalData) ModNode(m_globalData, expr1, expr2, rightHasAssignments);
722 }
723
724 ExpressionNode* ASTBuilder::makeAddNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
725 {
726     if (expr1->isNumber() && expr2->isNumber())
727         return createNumber(static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value());
728     return new (m_globalData) AddNode(m_globalData, expr1, expr2, rightHasAssignments);
729 }
730
731 ExpressionNode* ASTBuilder::makeSubNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
732 {
733     expr1 = expr1->stripUnaryPlus();
734     expr2 = expr2->stripUnaryPlus();
735
736     if (expr1->isNumber() && expr2->isNumber())
737         return createNumber(static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value());
738     return new (m_globalData) SubNode(m_globalData, expr1, expr2, rightHasAssignments);
739 }
740
741 ExpressionNode* ASTBuilder::makeLeftShiftNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
742 {
743     if (expr1->isNumber() && expr2->isNumber())
744         return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
745     return new (m_globalData) LeftShiftNode(m_globalData, expr1, expr2, rightHasAssignments);
746 }
747
748 ExpressionNode* ASTBuilder::makeRightShiftNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
749 {
750     if (expr1->isNumber() && expr2->isNumber())
751         return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
752     return new (m_globalData) RightShiftNode(m_globalData, expr1, expr2, rightHasAssignments);
753 }
754
755 ExpressionNode* ASTBuilder::makeURightShiftNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
756 {
757     if (expr1->isNumber() && expr2->isNumber())
758         return createNumber(toUInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
759     return new (m_globalData) UnsignedRightShiftNode(m_globalData, expr1, expr2, rightHasAssignments);
760 }
761
762 ExpressionNode* ASTBuilder::makeBitOrNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
763 {
764     if (expr1->isNumber() && expr2->isNumber())
765         return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) | toInt32(static_cast<NumberNode*>(expr2)->value()));
766     return new (m_globalData) BitOrNode(m_globalData, expr1, expr2, rightHasAssignments);
767 }
768
769 ExpressionNode* ASTBuilder::makeBitAndNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
770 {
771     if (expr1->isNumber() && expr2->isNumber())
772         return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) & toInt32(static_cast<NumberNode*>(expr2)->value()));
773     return new (m_globalData) BitAndNode(m_globalData, expr1, expr2, rightHasAssignments);
774 }
775
776 ExpressionNode* ASTBuilder::makeBitXOrNode(ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
777 {
778     if (expr1->isNumber() && expr2->isNumber())
779         return createNumber(toInt32(static_cast<NumberNode*>(expr1)->value()) ^ toInt32(static_cast<NumberNode*>(expr2)->value()));
780     return new (m_globalData) BitXOrNode(m_globalData, expr1, expr2, rightHasAssignments);
781 }
782
783 ExpressionNode* ASTBuilder::makeFunctionCallNode(ExpressionNode* func, ArgumentsNode* args, int start, int divot, int end)
784 {
785     if (!func->isLocation())
786         return new (m_globalData) FunctionCallValueNode(m_globalData, func, args, divot, divot - start, end - divot);
787     if (func->isResolveNode()) {
788         ResolveNode* resolve = static_cast<ResolveNode*>(func);
789         const Identifier& identifier = resolve->identifier();
790         if (identifier == m_globalData->propertyNames->eval) {
791             usesEval();
792             return new (m_globalData) EvalFunctionCallNode(m_globalData, args, divot, divot - start, end - divot);
793         }
794         return new (m_globalData) FunctionCallResolveNode(m_globalData, identifier, args, divot, divot - start, end - divot);
795     }
796     if (func->isBracketAccessorNode()) {
797         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func);
798         FunctionCallBracketNode* node = new (m_globalData) FunctionCallBracketNode(m_globalData, bracket->base(), bracket->subscript(), args, divot, divot - start, end - divot);
799         node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
800         return node;
801     }
802     ASSERT(func->isDotAccessorNode());
803     DotAccessorNode* dot = static_cast<DotAccessorNode*>(func);
804     FunctionCallDotNode* node;
805     if (dot->identifier() == m_globalData->propertyNames->call)
806         node = new (m_globalData) CallFunctionCallDotNode(m_globalData, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
807     else if (dot->identifier() == m_globalData->propertyNames->apply)
808         node = new (m_globalData) ApplyFunctionCallDotNode(m_globalData, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
809     else
810         node = new (m_globalData) FunctionCallDotNode(m_globalData, dot->base(), dot->identifier(), args, divot, divot - start, end - divot);
811     node->setSubexpressionInfo(dot->divot(), dot->endOffset());
812     return node;
813 }
814
815 ExpressionNode* ASTBuilder::makeBinaryNode(int token, pair<ExpressionNode*, BinaryOpInfo> lhs, pair<ExpressionNode*, BinaryOpInfo> rhs)
816 {
817     switch (token) {
818     case OR:
819         return new (m_globalData) LogicalOpNode(m_globalData, lhs.first, rhs.first, OpLogicalOr);
820
821     case AND:
822         return new (m_globalData) LogicalOpNode(m_globalData, lhs.first, rhs.first, OpLogicalAnd);
823
824     case BITOR:
825         return makeBitOrNode(lhs.first, rhs.first, rhs.second.hasAssignment);
826
827     case BITXOR:
828         return makeBitXOrNode(lhs.first, rhs.first, rhs.second.hasAssignment);
829
830     case BITAND:
831         return makeBitAndNode(lhs.first, rhs.first, rhs.second.hasAssignment);
832
833     case EQEQ:
834         return new (m_globalData) EqualNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
835
836     case NE:
837         return new (m_globalData) NotEqualNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
838
839     case STREQ:
840         return new (m_globalData) StrictEqualNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
841
842     case STRNEQ:
843         return new (m_globalData) NotStrictEqualNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
844
845     case LT:
846         return new (m_globalData) LessNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
847
848     case GT:
849         return new (m_globalData) GreaterNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
850
851     case LE:
852         return new (m_globalData) LessEqNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
853
854     case GE:
855         return new (m_globalData) GreaterEqNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
856
857     case INSTANCEOF: {
858         InstanceOfNode* node = new (m_globalData) InstanceOfNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
859         setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
860         return node;
861     }
862
863     case INTOKEN: {
864         InNode* node = new (m_globalData) InNode(m_globalData, lhs.first, rhs.first, rhs.second.hasAssignment);
865         setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
866         return node;
867     }
868
869     case LSHIFT:
870         return makeLeftShiftNode(lhs.first, rhs.first, rhs.second.hasAssignment);
871
872     case RSHIFT:
873         return makeRightShiftNode(lhs.first, rhs.first, rhs.second.hasAssignment);
874
875     case URSHIFT:
876         return makeURightShiftNode(lhs.first, rhs.first, rhs.second.hasAssignment);
877
878     case PLUS:
879         return makeAddNode(lhs.first, rhs.first, rhs.second.hasAssignment);
880
881     case MINUS:
882         return makeSubNode(lhs.first, rhs.first, rhs.second.hasAssignment);
883
884     case TIMES:
885         return makeMultNode(lhs.first, rhs.first, rhs.second.hasAssignment);
886
887     case DIVIDE:
888         return makeDivNode(lhs.first, rhs.first, rhs.second.hasAssignment);
889
890     case MOD:
891         return makeModNode(lhs.first, rhs.first, rhs.second.hasAssignment);
892     }
893     CRASH();
894     return 0;
895 }
896
897 ExpressionNode* ASTBuilder::makeAssignNode(ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end)
898 {
899     usesAssignment();
900     if (!loc->isLocation())
901         return new (m_globalData) AssignErrorNode(m_globalData, loc, op, expr, divot, divot - start, end - divot);
902
903     if (loc->isResolveNode()) {
904         ResolveNode* resolve = static_cast<ResolveNode*>(loc);
905         if (op == OpEqual) {
906             AssignResolveNode* node = new (m_globalData) AssignResolveNode(m_globalData, resolve->identifier(), expr, exprHasAssignments);
907             setExceptionLocation(node, start, divot, end);
908             return node;
909         }
910         return new (m_globalData) ReadModifyResolveNode(m_globalData, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
911     }
912     if (loc->isBracketAccessorNode()) {
913         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc);
914         if (op == OpEqual)
915             return new (m_globalData) AssignBracketNode(m_globalData, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot());
916         ReadModifyBracketNode* node = new (m_globalData) ReadModifyBracketNode(m_globalData, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot);
917         node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
918         return node;
919     }
920     ASSERT(loc->isDotAccessorNode());
921     DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc);
922     if (op == OpEqual)
923         return new (m_globalData) AssignDotNode(m_globalData, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot());
924
925     ReadModifyDotNode* node = new (m_globalData) ReadModifyDotNode(m_globalData, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
926     node->setSubexpressionInfo(dot->divot(), dot->endOffset());
927     return node;
928 }
929
930 ExpressionNode* ASTBuilder::makePrefixNode(ExpressionNode* expr, Operator op, int start, int divot, int end)
931 {
932     usesAssignment();
933     if (!expr->isLocation())
934         return new (m_globalData) PrefixErrorNode(m_globalData, expr, op, divot, divot - start, end - divot);
935
936     if (expr->isResolveNode()) {
937         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
938         return new (m_globalData) PrefixResolveNode(m_globalData, resolve->identifier(), op, divot, divot - start, end - divot);
939     }
940     if (expr->isBracketAccessorNode()) {
941         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
942         PrefixBracketNode* node = new (m_globalData) PrefixBracketNode(m_globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
943         node->setSubexpressionInfo(bracket->divot(), bracket->startOffset());
944         return node;
945     }
946     ASSERT(expr->isDotAccessorNode());
947     DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
948     PrefixDotNode* node = new (m_globalData) PrefixDotNode(m_globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
949     node->setSubexpressionInfo(dot->divot(), dot->startOffset());
950     return node;
951 }
952
953 ExpressionNode* ASTBuilder::makePostfixNode(ExpressionNode* expr, Operator op, int start, int divot, int end)
954 {
955     usesAssignment();
956     if (!expr->isLocation())
957         return new (m_globalData) PostfixErrorNode(m_globalData, expr, op, divot, divot - start, end - divot);
958
959     if (expr->isResolveNode()) {
960         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
961         return new (m_globalData) PostfixResolveNode(m_globalData, resolve->identifier(), op, divot, divot - start, end - divot);
962     }
963     if (expr->isBracketAccessorNode()) {
964         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
965         PostfixBracketNode* node = new (m_globalData) PostfixBracketNode(m_globalData, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
966         node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
967         return node;
968
969     }
970     ASSERT(expr->isDotAccessorNode());
971     DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
972     PostfixDotNode* node = new (m_globalData) PostfixDotNode(m_globalData, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
973     node->setSubexpressionInfo(dot->divot(), dot->endOffset());
974     return node;
975 }
976
977 }
978
979 #endif