Reviewed by Darin.
[WebKit-https.git] / JavaScriptCore / kjs / nodes.h
1 // -*- c-basic-offset: 2 -*-
2 /*
3  *  This file is part of the KDE libraries
4  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
5  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
6  *  Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Library General Public
10  *  License as published by the Free Software Foundation; either
11  *  version 2 of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Library General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Library General Public License
19  *  along with this library; see the file COPYING.LIB.  If not, write to
20  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  *  Boston, MA 02110-1301, USA.
22  *
23  */
24
25 #ifndef NODES_H_
26 #define NODES_H_
27
28 #include "Parser.h"
29 #include "internal.h"
30 #include <wtf/ListRefPtr.h>
31 #include <wtf/Vector.h>
32
33 namespace KJS {
34
35   class ProgramNode;
36   class PropertyNameNode;
37   class PropertyListNode;
38   class RegExp;
39   class SourceElementsNode;
40   class SourceStream;
41
42   enum Operator { OpEqual,
43                   OpEqEq,
44                   OpNotEq,
45                   OpStrEq,
46                   OpStrNEq,
47                   OpPlusEq,
48                   OpMinusEq,
49                   OpMultEq,
50                   OpDivEq,
51                   OpPlusPlus,
52                   OpMinusMinus,
53                   OpLess,
54                   OpLessEq,
55                   OpGreater,
56                   OpGreaterEq,
57                   OpAndEq,
58                   OpXOrEq,
59                   OpOrEq,
60                   OpModEq,
61                   OpAnd,
62                   OpOr,
63                   OpBitAnd,
64                   OpBitXOr,
65                   OpBitOr,
66                   OpLShift,
67                   OpRShift,
68                   OpURShift,
69                   OpIn,
70                   OpInstanceOf
71   };
72
73   class Node {
74   public:
75     Node();
76     virtual ~Node();
77
78     virtual JSValue *evaluate(ExecState *exec) = 0;
79     UString toString() const;
80     virtual void streamTo(SourceStream&) const = 0;
81     virtual void processVarDecls(ExecState*) {}
82     int lineNo() const { return m_line; }
83
84     void ref();
85     void deref();
86     unsigned refcount();
87     static void clearNewNodes();
88
89     virtual Node *nodeInsideAllParens();
90
91     virtual bool isLocation() const { return false; }
92     virtual bool isResolveNode() const { return false; }
93     virtual bool isBracketAccessorNode() const { return false; }
94     virtual bool isDotAccessorNode() const { return false; }
95     virtual bool isGroupNode() const { return false; }
96
97     virtual void breakCycle() { }
98
99   protected:
100     Completion createErrorCompletion(ExecState *, ErrorType, const char *msg);
101     Completion createErrorCompletion(ExecState *, ErrorType, const char *msg, const Identifier &);
102
103     JSValue *throwError(ExecState *, ErrorType, const char *msg);
104     JSValue* throwError(ExecState *, ErrorType, const char* msg, const char*);
105     JSValue *throwError(ExecState *, ErrorType, const char *msg, JSValue *, Node *);
106     JSValue *throwError(ExecState *, ErrorType, const char *msg, const Identifier &);
107     JSValue *throwError(ExecState *, ErrorType, const char *msg, JSValue *, const Identifier &);
108     JSValue *throwError(ExecState *, ErrorType, const char *msg, JSValue *, Node *, Node *);
109     JSValue *throwError(ExecState *, ErrorType, const char *msg, JSValue *, Node *, const Identifier &);
110
111     JSValue *throwUndefinedVariableError(ExecState *, const Identifier &);
112
113     void handleException(ExecState*);
114     void handleException(ExecState*, JSValue*);
115
116     int m_line;
117   private:
118     // disallow assignment
119     Node& operator=(const Node&);
120     Node(const Node &other);
121   };
122
123   class StatementNode : public Node {
124   public:
125     StatementNode();
126     void setLoc(int line0, int line1);
127     int firstLine() const { return lineNo(); }
128     int lastLine() const { return m_lastLine; }
129     bool hitStatement(ExecState*);
130     virtual Completion execute(ExecState *exec) = 0;
131     void pushLabel(const Identifier &id) { ls.push(id); }
132     virtual void processFuncDecl(ExecState*);
133   protected:
134     LabelStack ls;
135   private:
136     JSValue *evaluate(ExecState*) { return jsUndefined(); }
137     int m_lastLine;
138   };
139
140   class NullNode : public Node {
141   public:
142     NullNode() {}
143     JSValue* evaluate(ExecState*);
144     virtual void streamTo(SourceStream&) const;
145   };
146
147   class BooleanNode : public Node {
148   public:
149     BooleanNode(bool v) : value(v) {}
150     JSValue* evaluate(ExecState*);
151     virtual void streamTo(SourceStream&) const;
152   private:
153     bool value;
154   };
155
156   class NumberNode : public Node {
157   public:
158     NumberNode(double v) : value(v) {}
159     JSValue* evaluate(ExecState*);
160     virtual void streamTo(SourceStream&) const;
161   private:
162     double value;
163   };
164
165   class StringNode : public Node {
166   public:
167     StringNode(const UString *v) { value = *v; }
168     JSValue* evaluate(ExecState*);
169     virtual void streamTo(SourceStream&) const;
170   private:
171     UString value;
172   };
173
174   class RegExpNode : public Node {
175   public:
176     RegExpNode(const UString &p, const UString &f)
177       : pattern(p), flags(f) { }
178     JSValue* evaluate(ExecState*);
179     virtual void streamTo(SourceStream&) const;
180   private:
181     UString pattern, flags;
182   };
183
184   class ThisNode : public Node {
185   public:
186     ThisNode() {}
187     JSValue* evaluate(ExecState*);
188     virtual void streamTo(SourceStream&) const;
189   };
190
191   class ResolveNode : public Node {
192   public:
193     ResolveNode(const Identifier &s) : ident(s) { }
194     JSValue* evaluate(ExecState*);
195     virtual void streamTo(SourceStream&) const;
196
197     virtual bool isLocation() const { return true; }
198     virtual bool isResolveNode() const { return true; }
199     const Identifier& identifier() const { return ident; }
200
201   private:
202     Identifier ident;
203   };
204
205   class GroupNode : public Node {
206   public:
207     GroupNode(Node *g) : group(g) { }
208     virtual JSValue* evaluate(ExecState*);
209     virtual Node *nodeInsideAllParens();
210     virtual void streamTo(SourceStream&) const;
211     virtual bool isGroupNode() const { return true; }
212   private:
213     RefPtr<Node> group;
214   };
215
216   class ElementNode : public Node {
217   public:
218     // list pointer is tail of a circular list, cracked in the ArrayNode ctor
219     ElementNode(int e, Node *n) : next(this), elision(e), node(n) { Parser::noteNodeCycle(this); }
220     ElementNode(ElementNode *l, int e, Node *n)
221       : next(l->next), elision(e), node(n) { l->next = this; }
222     JSValue* evaluate(ExecState*);
223     virtual void streamTo(SourceStream&) const;
224     PassRefPtr<ElementNode> releaseNext() { return next.release(); }
225     virtual void breakCycle();
226   private:
227     friend class ArrayNode;
228     ListRefPtr<ElementNode> next;
229     int elision;
230     RefPtr<Node> node;
231   };
232
233   class ArrayNode : public Node {
234   public:
235     ArrayNode(int e) : elision(e), opt(true) { }
236     ArrayNode(ElementNode *ele)
237       : element(ele->next.release()), elision(0), opt(false) { Parser::removeNodeCycle(element.get()); }
238     ArrayNode(int eli, ElementNode *ele)
239       : element(ele->next.release()), elision(eli), opt(true) { Parser::removeNodeCycle(element.get()); }
240     JSValue* evaluate(ExecState*);
241     virtual void streamTo(SourceStream&) const;
242   private:
243     RefPtr<ElementNode> element;
244     int elision;
245     bool opt;
246   };
247
248   class PropertyNameNode : public Node {
249   public:
250     PropertyNameNode(double d) : numeric(d) { }
251     PropertyNameNode(const Identifier &s) : str(s) { }
252     JSValue* evaluate(ExecState*);
253     virtual void streamTo(SourceStream&) const;
254   private:
255     double numeric;
256     Identifier str;
257   };
258   
259   class PropertyNode : public Node {
260   public:
261     enum Type { Constant, Getter, Setter };
262     PropertyNode(PropertyNameNode *n, Node *a, Type t) 
263       : name(n), assign(a), type(t) { }
264     JSValue* evaluate(ExecState*);
265     virtual void streamTo(SourceStream&) const;
266     friend class PropertyListNode;
267   private:
268     RefPtr<PropertyNameNode> name;
269     RefPtr<Node> assign;
270     Type type;
271   };
272   
273   class PropertyListNode : public Node {
274   public:
275     // list pointer is tail of a circular list, cracked in the ObjectLiteralNode ctor
276     PropertyListNode(PropertyNode *n)
277       : node(n), next(this) { Parser::noteNodeCycle(this); }
278     PropertyListNode(PropertyNode *n, PropertyListNode *l)
279       : node(n), next(l->next) { l->next = this; }
280     JSValue* evaluate(ExecState*);
281     virtual void streamTo(SourceStream&) const;
282     PassRefPtr<PropertyListNode> releaseNext() { return next.release(); }
283     virtual void breakCycle();
284   private:
285     friend class ObjectLiteralNode;
286     RefPtr<PropertyNode> node;
287     ListRefPtr<PropertyListNode> next;
288   };
289
290   class ObjectLiteralNode : public Node {
291   public:
292     ObjectLiteralNode() { }
293     ObjectLiteralNode(PropertyListNode *l) : list(l->next.release()) { Parser::removeNodeCycle(list.get()); }
294     JSValue* evaluate(ExecState*);
295     virtual void streamTo(SourceStream&) const;
296   private:
297     RefPtr<PropertyListNode> list;
298   };
299
300   class BracketAccessorNode : public Node {
301   public:
302     BracketAccessorNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
303     JSValue* evaluate(ExecState*);
304     virtual void streamTo(SourceStream&) const;
305
306     virtual bool isLocation() const { return true; }
307     virtual bool isBracketAccessorNode() const { return true; }
308     Node *base() { return expr1.get(); }
309     Node *subscript() { return expr2.get(); }
310
311   private:
312     RefPtr<Node> expr1;
313     RefPtr<Node> expr2;
314   };
315
316   class DotAccessorNode : public Node {
317   public:
318     DotAccessorNode(Node *e, const Identifier &s) : expr(e), ident(s) { }
319     JSValue* evaluate(ExecState*);
320     virtual void streamTo(SourceStream&) const;
321
322     virtual bool isLocation() const { return true; }
323     virtual bool isDotAccessorNode() const { return true; }
324     Node *base() const { return expr.get(); }
325     const Identifier& identifier() const { return ident; }
326
327   private:
328     RefPtr<Node> expr;
329     Identifier ident;
330   };
331
332   class ArgumentListNode : public Node {
333   public:
334     // list pointer is tail of a circular list, cracked in the ArgumentsNode ctor
335     ArgumentListNode(Node *e) : next(this), expr(e) { Parser::noteNodeCycle(this); }
336     ArgumentListNode(ArgumentListNode *l, Node *e)
337       : next(l->next), expr(e) { l->next = this; }
338     JSValue* evaluate(ExecState*);
339     List evaluateList(ExecState*);
340     virtual void streamTo(SourceStream&) const;
341     PassRefPtr<ArgumentListNode> releaseNext() { return next.release(); }
342     virtual void breakCycle();
343   private:
344     friend class ArgumentsNode;
345     ListRefPtr<ArgumentListNode> next;
346     RefPtr<Node> expr;
347   };
348
349   class ArgumentsNode : public Node {
350   public:
351     ArgumentsNode() { }
352     ArgumentsNode(ArgumentListNode *l)
353       : list(l->next.release()) { Parser::removeNodeCycle(list.get()); }
354     JSValue* evaluate(ExecState*);
355     List evaluateList(ExecState *exec) { return list ? list->evaluateList(exec) : List(); }
356     virtual void streamTo(SourceStream&) const;
357   private:
358     RefPtr<ArgumentListNode> list;
359   };
360
361   class NewExprNode : public Node {
362   public:
363     NewExprNode(Node *e) : expr(e) {}
364     NewExprNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
365     JSValue* evaluate(ExecState*);
366     virtual void streamTo(SourceStream&) const;
367   private:
368     RefPtr<Node> expr;
369     RefPtr<ArgumentsNode> args;
370   };
371
372   class FunctionCallValueNode : public Node {
373   public:
374     FunctionCallValueNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
375     JSValue* evaluate(ExecState*);
376     virtual void streamTo(SourceStream&) const;
377   private:
378     RefPtr<Node> expr;
379     RefPtr<ArgumentsNode> args;
380   };
381
382   class FunctionCallResolveNode : public Node {
383   public:
384     FunctionCallResolveNode(const Identifier& i, ArgumentsNode *a) : ident(i), args(a) {}
385     JSValue* evaluate(ExecState*);
386     virtual void streamTo(SourceStream&) const;
387   private:
388     Identifier ident;
389     RefPtr<ArgumentsNode> args;
390   };
391
392   class FunctionCallBracketNode : public Node {
393   public:
394     FunctionCallBracketNode(Node *b, Node *s, ArgumentsNode *a) : base(b), subscript(s), args(a) {}
395     JSValue* evaluate(ExecState*);
396     virtual void streamTo(SourceStream&) const;
397   protected:
398     RefPtr<Node> base;
399     RefPtr<Node> subscript;
400     RefPtr<ArgumentsNode> args;
401   };
402
403   class FunctionCallParenBracketNode : public FunctionCallBracketNode {
404   public:
405     FunctionCallParenBracketNode(Node *b, Node *s, ArgumentsNode *a) : FunctionCallBracketNode(b, s, a) {}
406     virtual void streamTo(SourceStream&) const;
407   };
408
409   class FunctionCallDotNode : public Node {
410   public:
411     FunctionCallDotNode(Node *b, const Identifier &i, ArgumentsNode *a) : base(b), ident(i), args(a) {}
412     JSValue* evaluate(ExecState*);
413     virtual void streamTo(SourceStream&) const;
414   protected:
415     RefPtr<Node> base;
416     Identifier ident;
417     RefPtr<ArgumentsNode> args;
418   };
419
420   class FunctionCallParenDotNode : public FunctionCallDotNode {
421   public:
422     FunctionCallParenDotNode(Node *b, const Identifier &i, ArgumentsNode *a) : FunctionCallDotNode(b, i, a) {}
423     virtual void streamTo(SourceStream&) const;
424   };
425
426   class PostfixResolveNode : public Node {
427   public:
428     PostfixResolveNode(const Identifier& i, Operator o) : m_ident(i), m_oper(o) {}
429     JSValue* evaluate(ExecState*);
430     virtual void streamTo(SourceStream&) const;
431   private:
432     Identifier m_ident;
433     Operator m_oper;
434   };
435
436   class PostfixBracketNode : public Node {
437   public:
438     PostfixBracketNode(Node *b, Node *s, Operator o) : m_base(b), m_subscript(s), m_oper(o) {}
439     JSValue* evaluate(ExecState*);
440     virtual void streamTo(SourceStream&) const;
441   private:
442     RefPtr<Node> m_base;
443     RefPtr<Node> m_subscript;
444     Operator m_oper;
445   };
446
447   class PostfixDotNode : public Node {
448   public:
449     PostfixDotNode(Node *b, const Identifier& i, Operator o) : m_base(b), m_ident(i), m_oper(o) {}
450     JSValue* evaluate(ExecState*);
451     virtual void streamTo(SourceStream&) const;
452   private:
453     RefPtr<Node> m_base;
454     Identifier m_ident;
455     Operator m_oper;
456   };
457
458   class PostfixErrorNode : public Node {
459   public:
460     PostfixErrorNode(Node* e, Operator o) : m_expr(e), m_oper(o) {}
461     JSValue* evaluate(ExecState*);
462     virtual void streamTo(SourceStream&) const;
463   private:
464     RefPtr<Node> m_expr;
465     Operator m_oper;
466   };
467
468   class DeleteResolveNode : public Node {
469   public:
470     DeleteResolveNode(const Identifier& i) : m_ident(i) {}
471     JSValue* evaluate(ExecState*);
472     virtual void streamTo(SourceStream&) const;
473   private:
474     Identifier m_ident;
475   };
476
477   class DeleteBracketNode : public Node {
478   public:
479     DeleteBracketNode(Node *base, Node *subscript) : m_base(base), m_subscript(subscript) {}
480     JSValue* evaluate(ExecState*);
481     virtual void streamTo(SourceStream&) const;
482   private:
483     RefPtr<Node> m_base;
484     RefPtr<Node> m_subscript;
485   };
486
487   class DeleteDotNode : public Node {
488   public:
489     DeleteDotNode(Node *base, const Identifier& i) : m_base(base), m_ident(i) {}
490     JSValue* evaluate(ExecState*);
491     virtual void streamTo(SourceStream&) const;
492   private:
493     RefPtr<Node> m_base;
494     Identifier m_ident;
495   };
496
497   class DeleteValueNode : public Node {
498   public:
499     DeleteValueNode(Node *e) : m_expr(e) {}
500     JSValue* evaluate(ExecState*);
501     virtual void streamTo(SourceStream&) const;
502   private:
503     RefPtr<Node> m_expr;
504   };
505
506   class VoidNode : public Node {
507   public:
508     VoidNode(Node *e) : expr(e) {}
509     JSValue* evaluate(ExecState*);
510     virtual void streamTo(SourceStream&) const;
511   private:
512     RefPtr<Node> expr;
513   };
514
515   class TypeOfResolveNode : public Node {
516   public:
517     TypeOfResolveNode(const Identifier& i) : m_ident(i) {}
518     JSValue* evaluate(ExecState*);
519     virtual void streamTo(SourceStream&) const;
520   private:
521     Identifier m_ident;
522   };
523
524   class TypeOfValueNode : public Node {
525   public:
526     TypeOfValueNode(Node *e) : m_expr(e) {}
527     JSValue* evaluate(ExecState*);
528     virtual void streamTo(SourceStream&) const;
529   private:
530     RefPtr<Node> m_expr;
531   };
532
533   class PrefixResolveNode : public Node {
534   public:
535     PrefixResolveNode(const Identifier& i, Operator o) : m_ident(i), m_oper(o) {}
536     JSValue* evaluate(ExecState*);
537     virtual void streamTo(SourceStream&) const;
538   private:
539     Identifier m_ident;
540     Operator m_oper;
541   };
542
543   class PrefixBracketNode : public Node {
544   public:
545     PrefixBracketNode(Node *b, Node *s, Operator o) : m_base(b), m_subscript(s), m_oper(o) {}
546     JSValue* evaluate(ExecState*);
547     virtual void streamTo(SourceStream&) const;
548   private:
549     RefPtr<Node> m_base;
550     RefPtr<Node> m_subscript;
551     Operator m_oper;
552   };
553
554   class PrefixDotNode : public Node {
555   public:
556     PrefixDotNode(Node *b, const Identifier& i, Operator o) : m_base(b), m_ident(i), m_oper(o) {}
557     JSValue* evaluate(ExecState*);
558     virtual void streamTo(SourceStream&) const;
559   private:
560     RefPtr<Node> m_base;
561     Identifier m_ident;
562     Operator m_oper;
563   };
564
565   class PrefixErrorNode : public Node {
566   public:
567     PrefixErrorNode(Node* e, Operator o) : m_expr(e), m_oper(o) {}
568     JSValue* evaluate(ExecState*);
569     virtual void streamTo(SourceStream&) const;
570   private:
571     RefPtr<Node> m_expr;
572     Operator m_oper;
573   };
574
575   class UnaryPlusNode : public Node {
576   public:
577     UnaryPlusNode(Node *e) : expr(e) {}
578     JSValue* evaluate(ExecState*);
579     virtual void streamTo(SourceStream&) const;
580   private:
581     RefPtr<Node> expr;
582   };
583
584   class NegateNode : public Node {
585   public:
586     NegateNode(Node *e) : expr(e) {}
587     JSValue* evaluate(ExecState*);
588     virtual void streamTo(SourceStream&) const;
589   private:
590     RefPtr<Node> expr;
591   };
592
593   class BitwiseNotNode : public Node {
594   public:
595     BitwiseNotNode(Node *e) : expr(e) {}
596     JSValue* evaluate(ExecState*);
597     virtual void streamTo(SourceStream&) const;
598   private:
599     RefPtr<Node> expr;
600   };
601
602   class LogicalNotNode : public Node {
603   public:
604     LogicalNotNode(Node *e) : expr(e) {}
605     JSValue* evaluate(ExecState*);
606     virtual void streamTo(SourceStream&) const;
607   private:
608     RefPtr<Node> expr;
609   };
610
611   class MultNode : public Node {
612   public:
613     MultNode(Node *t1, Node *t2, char op) : term1(t1), term2(t2), oper(op) {}
614     JSValue* evaluate(ExecState*);
615     virtual void streamTo(SourceStream&) const;
616   private:
617     RefPtr<Node> term1;
618     RefPtr<Node> term2;
619     char oper;
620   };
621
622   class AddNode : public Node {
623   public:
624     AddNode(Node *t1, Node *t2, char op) : term1(t1), term2(t2), oper(op) {}
625     JSValue* evaluate(ExecState*);
626     virtual void streamTo(SourceStream&) const;
627   private:
628     RefPtr<Node> term1;
629     RefPtr<Node> term2;
630     char oper;
631   };
632
633   class ShiftNode : public Node {
634   public:
635     ShiftNode(Node *t1, Operator o, Node *t2)
636       : term1(t1), term2(t2), oper(o) {}
637     JSValue* evaluate(ExecState*);
638     virtual void streamTo(SourceStream&) const;
639   private:
640     RefPtr<Node> term1;
641     RefPtr<Node> term2;
642     Operator oper;
643   };
644
645   class RelationalNode : public Node {
646   public:
647     RelationalNode(Node *e1, Operator o, Node *e2) :
648       expr1(e1), expr2(e2), oper(o) {}
649     JSValue* evaluate(ExecState*);
650     virtual void streamTo(SourceStream&) const;
651   private:
652     RefPtr<Node> expr1;
653     RefPtr<Node> expr2;
654     Operator oper;
655   };
656
657   class EqualNode : public Node {
658   public:
659     EqualNode(Node *e1, Operator o, Node *e2)
660       : expr1(e1), expr2(e2), oper(o) {}
661     JSValue* evaluate(ExecState*);
662     virtual void streamTo(SourceStream&) const;
663   private:
664     RefPtr<Node> expr1;
665     RefPtr<Node> expr2;
666     Operator oper;
667   };
668
669   class BitOperNode : public Node {
670   public:
671     BitOperNode(Node *e1, Operator o, Node *e2) :
672       expr1(e1), expr2(e2), oper(o) {}
673     JSValue* evaluate(ExecState*);
674     virtual void streamTo(SourceStream&) const;
675   private:
676     RefPtr<Node> expr1;
677     RefPtr<Node> expr2;
678     Operator oper;
679   };
680
681   /**
682    * expr1 && expr2, expr1 || expr2
683    */
684   class BinaryLogicalNode : public Node {
685   public:
686     BinaryLogicalNode(Node *e1, Operator o, Node *e2) :
687       expr1(e1), expr2(e2), oper(o) {}
688     JSValue* evaluate(ExecState*);
689     virtual void streamTo(SourceStream&) const;
690   private:
691     RefPtr<Node> expr1;
692     RefPtr<Node> expr2;
693     Operator oper;
694   };
695
696   /**
697    * The ternary operator, "logical ? expr1 : expr2"
698    */
699   class ConditionalNode : public Node {
700   public:
701     ConditionalNode(Node *l, Node *e1, Node *e2) :
702       logical(l), expr1(e1), expr2(e2) {}
703     JSValue* evaluate(ExecState*);
704     virtual void streamTo(SourceStream&) const;
705   private:
706     RefPtr<Node> logical;
707     RefPtr<Node> expr1;
708     RefPtr<Node> expr2;
709   };
710
711   class AssignResolveNode : public Node {
712   public:
713     AssignResolveNode(const Identifier &ident, Operator oper, Node *right) 
714       : m_ident(ident), m_oper(oper), m_right(right) {}
715     JSValue* evaluate(ExecState*);
716     virtual void streamTo(SourceStream&) const;
717   protected:
718     Identifier m_ident;
719     Operator m_oper;
720     RefPtr<Node> m_right;
721   };
722
723   class AssignBracketNode : public Node {
724   public:
725     AssignBracketNode(Node *base, Node *subscript, Operator oper, Node *right) 
726       : m_base(base), m_subscript(subscript), m_oper(oper), m_right(right) {}
727     JSValue* evaluate(ExecState*);
728     virtual void streamTo(SourceStream&) const;
729   protected:
730     RefPtr<Node> m_base;
731     RefPtr<Node> m_subscript;
732     Operator m_oper;
733     RefPtr<Node> m_right;
734   };
735
736   class AssignDotNode : public Node {
737   public:
738     AssignDotNode(Node *base, const Identifier& ident, Operator oper, Node *right)
739       : m_base(base), m_ident(ident), m_oper(oper), m_right(right) {}
740     JSValue* evaluate(ExecState*);
741     virtual void streamTo(SourceStream&) const;
742   protected:
743     RefPtr<Node> m_base;
744     Identifier m_ident;
745     Operator m_oper;
746     RefPtr<Node> m_right;
747   };
748
749   class AssignErrorNode : public Node {
750   public:
751     AssignErrorNode(Node* left, Operator oper, Node* right)
752       : m_left(left), m_oper(oper), m_right(right) {}
753     JSValue* evaluate(ExecState*);
754     virtual void streamTo(SourceStream&) const;
755   protected:
756     RefPtr<Node> m_left;
757     Operator m_oper;
758     RefPtr<Node> m_right;
759   };
760
761   class CommaNode : public Node {
762   public:
763     CommaNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
764     JSValue* evaluate(ExecState*);
765     virtual void streamTo(SourceStream&) const;
766   private:
767     RefPtr<Node> expr1;
768     RefPtr<Node> expr2;
769   };
770
771   class AssignExprNode : public Node {
772   public:
773     AssignExprNode(Node *e) : expr(e) {}
774     JSValue* evaluate(ExecState*);
775     virtual void streamTo(SourceStream&) const;
776   private:
777     RefPtr<Node> expr;
778   };
779
780   class VarDeclNode : public Node {
781   public:
782     enum Type { Variable, Constant };
783     VarDeclNode(const Identifier &id, AssignExprNode *in, Type t);
784     JSValue* evaluate(ExecState*);
785     virtual void processVarDecls(ExecState*);
786     virtual void streamTo(SourceStream&) const;
787   private:
788     Type varType;
789     Identifier ident;
790     RefPtr<AssignExprNode> init;
791   };
792
793   class VarDeclListNode : public Node {
794   public:
795     // list pointer is tail of a circular list, cracked in the ForNode/VarStatementNode ctor
796     VarDeclListNode(VarDeclNode *v) : next(this), var(v) { Parser::noteNodeCycle(this); }
797     VarDeclListNode(VarDeclListNode *l, VarDeclNode *v)
798       : next(l->next), var(v) { l->next = this; }
799     JSValue* evaluate(ExecState*);
800     virtual void processVarDecls(ExecState*);
801     virtual void streamTo(SourceStream&) const;
802     PassRefPtr<VarDeclListNode> releaseNext() { return next.release(); }
803     virtual void breakCycle();
804   private:
805     friend class ForNode;
806     friend class VarStatementNode;
807     ListRefPtr<VarDeclListNode> next;
808     RefPtr<VarDeclNode> var;
809   };
810
811   class VarStatementNode : public StatementNode {
812   public:
813     VarStatementNode(VarDeclListNode *l) : next(l->next.release()) { Parser::removeNodeCycle(next.get()); }
814     virtual Completion execute(ExecState*);
815     virtual void processVarDecls(ExecState*);
816     virtual void streamTo(SourceStream&) const;
817   private:
818     RefPtr<VarDeclListNode> next;
819   };
820
821   class BlockNode : public StatementNode {
822   public:
823     BlockNode(SourceElementsNode *s);
824     virtual Completion execute(ExecState*);
825     virtual void processVarDecls(ExecState*);
826     virtual void streamTo(SourceStream&) const;
827   protected:
828     RefPtr<SourceElementsNode> source;
829   };
830
831   class EmptyStatementNode : public StatementNode {
832   public:
833     EmptyStatementNode() { } // debug
834     virtual Completion execute(ExecState*);
835     virtual void streamTo(SourceStream&) const;
836   };
837
838   class ExprStatementNode : public StatementNode {
839   public:
840     ExprStatementNode(Node *e) : expr(e) { }
841     virtual Completion execute(ExecState*);
842     virtual void streamTo(SourceStream&) const;
843   private:
844     RefPtr<Node> expr;
845   };
846
847   class IfNode : public StatementNode {
848   public:
849     IfNode(Node *e, StatementNode *s1, StatementNode *s2)
850       : expr(e), statement1(s1), statement2(s2) {}
851     virtual Completion execute(ExecState*);
852     virtual void processVarDecls(ExecState*);
853     virtual void streamTo(SourceStream&) const;
854   private:
855     RefPtr<Node> expr;
856     RefPtr<StatementNode> statement1;
857     RefPtr<StatementNode> statement2;
858   };
859
860   class DoWhileNode : public StatementNode {
861   public:
862     DoWhileNode(StatementNode *s, Node *e) : statement(s), expr(e) {}
863     virtual Completion execute(ExecState*);
864     virtual void processVarDecls(ExecState*);
865     virtual void streamTo(SourceStream&) const;
866   private:
867     RefPtr<StatementNode> statement;
868     RefPtr<Node> expr;
869   };
870
871   class WhileNode : public StatementNode {
872   public:
873     WhileNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
874     virtual Completion execute(ExecState*);
875     virtual void processVarDecls(ExecState*);
876     virtual void streamTo(SourceStream&) const;
877   private:
878     RefPtr<Node> expr;
879     RefPtr<StatementNode> statement;
880   };
881
882   class ForNode : public StatementNode {
883   public:
884     ForNode(Node *e1, Node *e2, Node *e3, StatementNode *s) :
885       expr1(e1), expr2(e2), expr3(e3), statement(s) {}
886     ForNode(VarDeclListNode *e1, Node *e2, Node *e3, StatementNode *s) :
887       expr1(e1->next.release()), expr2(e2), expr3(e3), statement(s) { Parser::removeNodeCycle(expr1.get()); }
888     virtual Completion execute(ExecState*);
889     virtual void processVarDecls(ExecState*);
890     virtual void streamTo(SourceStream&) const;
891   private:
892     RefPtr<Node> expr1;
893     RefPtr<Node> expr2;
894     RefPtr<Node> expr3;
895     RefPtr<StatementNode> statement;
896   };
897
898   class ForInNode : public StatementNode {
899   public:
900     ForInNode(Node *l, Node *e, StatementNode *s);
901     ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s);
902     virtual Completion execute(ExecState*);
903     virtual void processVarDecls(ExecState*);
904     virtual void streamTo(SourceStream&) const;
905   private:
906     Identifier ident;
907     RefPtr<AssignExprNode> init;
908     RefPtr<Node> lexpr;
909     RefPtr<Node> expr;
910     RefPtr<VarDeclNode> varDecl;
911     RefPtr<StatementNode> statement;
912   };
913
914   class ContinueNode : public StatementNode {
915   public:
916     ContinueNode() { }
917     ContinueNode(const Identifier &i) : ident(i) { }
918     virtual Completion execute(ExecState*);
919     virtual void streamTo(SourceStream&) const;
920   private:
921     Identifier ident;
922   };
923
924   class BreakNode : public StatementNode {
925   public:
926     BreakNode() { }
927     BreakNode(const Identifier &i) : ident(i) { }
928     virtual Completion execute(ExecState*);
929     virtual void streamTo(SourceStream&) const;
930   private:
931     Identifier ident;
932   };
933
934   class ReturnNode : public StatementNode {
935   public:
936     ReturnNode(Node *v) : value(v) {}
937     virtual Completion execute(ExecState*);
938     virtual void streamTo(SourceStream&) const;
939   private:
940     RefPtr<Node> value;
941   };
942
943   class WithNode : public StatementNode {
944   public:
945     WithNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
946     virtual Completion execute(ExecState*);
947     virtual void processVarDecls(ExecState*);
948     virtual void streamTo(SourceStream&) const;
949   private:
950     RefPtr<Node> expr;
951     RefPtr<StatementNode> statement;
952   };
953
954   class LabelNode : public StatementNode {
955   public:
956     LabelNode(const Identifier &l, StatementNode *s) : label(l), statement(s) { }
957     virtual Completion execute(ExecState*);
958     virtual void processVarDecls(ExecState*);
959     virtual void streamTo(SourceStream&) const;
960   private:
961     Identifier label;
962     RefPtr<StatementNode> statement;
963   };
964
965   class ThrowNode : public StatementNode {
966   public:
967     ThrowNode(Node *e) : expr(e) {}
968     virtual Completion execute(ExecState*);
969     virtual void streamTo(SourceStream&) const;
970   private:
971     RefPtr<Node> expr;
972   };
973
974   class TryNode : public StatementNode {
975   public:
976     TryNode(StatementNode *b, const Identifier &e, StatementNode *c, StatementNode *f)
977       : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { }
978     virtual Completion execute(ExecState*);
979     virtual void processVarDecls(ExecState*);
980     virtual void streamTo(SourceStream&) const;
981   private:
982     RefPtr<StatementNode> tryBlock;
983     Identifier exceptionIdent;
984     RefPtr<StatementNode> catchBlock;
985     RefPtr<StatementNode> finallyBlock;
986   };
987
988   class ParameterNode : public Node {
989   public:
990     // list pointer is tail of a circular list, cracked in the FuncDeclNode/FuncExprNode ctor
991     ParameterNode(const Identifier &i) : id(i), next(this) { Parser::noteNodeCycle(this); }
992     ParameterNode(ParameterNode *next, const Identifier &i)
993       : id(i), next(next->next) { next->next = this; }
994     JSValue* evaluate(ExecState*);
995     Identifier ident() { return id; }
996     ParameterNode *nextParam() { return next.get(); }
997     virtual void streamTo(SourceStream&) const;
998     PassRefPtr<ParameterNode> releaseNext() { return next.release(); }
999     virtual void breakCycle();
1000   private:
1001     friend class FuncDeclNode;
1002     friend class FuncExprNode;
1003     Identifier id;
1004     ListRefPtr<ParameterNode> next;
1005   };
1006
1007   class Parameter {
1008   public:
1009     Parameter() { }
1010     Parameter(const Identifier& n) : name(n) { }
1011     Identifier name;
1012   };
1013
1014   // inherited by ProgramNode
1015   class FunctionBodyNode : public BlockNode {
1016   public:
1017     FunctionBodyNode(SourceElementsNode *);
1018     virtual void processFuncDecl(ExecState*);
1019     int sourceId() { return m_sourceId; }
1020     const UString& sourceURL() { return m_sourceURL; }
1021
1022     void addParam(const Identifier& ident);
1023     size_t numParams() const { return m_parameters.size(); }
1024     Identifier paramName(size_t pos) const { return m_parameters[pos].name; }
1025     UString paramString() const;
1026     Vector<Parameter>& parameters() { return m_parameters; }
1027   private:
1028     UString m_sourceURL;
1029     int m_sourceId;
1030     Vector<Parameter> m_parameters;
1031   };
1032
1033   class FuncExprNode : public Node {
1034   public:
1035     FuncExprNode(const Identifier &i, FunctionBodyNode *b, ParameterNode *p = 0)
1036       : ident(i), param(p ? p->next.release() : 0), body(b) { if (p) { Parser::removeNodeCycle(param.get()); } addParams(); }
1037     virtual JSValue *evaluate(ExecState*);
1038     virtual void streamTo(SourceStream&) const;
1039   private:
1040     void addParams();
1041     // Used for streamTo
1042     friend class PropertyNode;
1043     Identifier ident;
1044     RefPtr<ParameterNode> param;
1045     RefPtr<FunctionBodyNode> body;
1046   };
1047
1048   class FuncDeclNode : public StatementNode {
1049   public:
1050     FuncDeclNode(const Identifier &i, FunctionBodyNode *b)
1051       : ident(i), body(b) { addParams(); }
1052     FuncDeclNode(const Identifier &i, ParameterNode *p, FunctionBodyNode *b)
1053       : ident(i), param(p->next.release()), body(b) { Parser::removeNodeCycle(param.get()); addParams(); }
1054     virtual Completion execute(ExecState*);
1055     virtual void processFuncDecl(ExecState*);
1056     virtual void streamTo(SourceStream&) const;
1057   private:
1058     void addParams();
1059     Identifier ident;
1060     RefPtr<ParameterNode> param;
1061     RefPtr<FunctionBodyNode> body;
1062   };
1063
1064   // A linked list of source element nodes
1065   class SourceElementsNode : public StatementNode {
1066   public:
1067     static int count;
1068     // list pointer is tail of a circular list, cracked in the BlockNode (or subclass) ctor
1069     SourceElementsNode(StatementNode*);
1070     SourceElementsNode(SourceElementsNode *s1, StatementNode *s2);
1071     
1072     Completion execute(ExecState*);
1073     void processFuncDecl(ExecState*);
1074     virtual void processVarDecls(ExecState*);
1075     virtual void streamTo(SourceStream&) const;
1076     PassRefPtr<SourceElementsNode> releaseNext() { return next.release(); }
1077     virtual void breakCycle();
1078   private:
1079     friend class BlockNode;
1080     friend class CaseClauseNode;
1081     RefPtr<StatementNode> node;
1082     ListRefPtr<SourceElementsNode> next;
1083   };
1084
1085   class CaseClauseNode : public Node {
1086   public:
1087       CaseClauseNode(Node *e) : expr(e) { }
1088       CaseClauseNode(Node *e, SourceElementsNode *s)
1089       : expr(e), source(s->next.release()) { Parser::removeNodeCycle(source.get()); }
1090       JSValue* evaluate(ExecState*);
1091       Completion evalStatements(ExecState*);
1092       void processFuncDecl(ExecState*);
1093       virtual void processVarDecls(ExecState*);
1094       virtual void streamTo(SourceStream&) const;
1095   private:
1096       RefPtr<Node> expr;
1097       RefPtr<SourceElementsNode> source;
1098   };
1099   
1100   class ClauseListNode : public Node {
1101   public:
1102       // list pointer is tail of a circular list, cracked in the CaseBlockNode ctor
1103       ClauseListNode(CaseClauseNode *c) : clause(c), next(this) { Parser::noteNodeCycle(this); }
1104       ClauseListNode(ClauseListNode *n, CaseClauseNode *c)
1105       : clause(c), next(n->next) { n->next = this; }
1106       JSValue* evaluate(ExecState*);
1107       CaseClauseNode *getClause() const { return clause.get(); }
1108       ClauseListNode *getNext() const { return next.get(); }
1109       virtual void processVarDecls(ExecState*);
1110       void processFuncDecl(ExecState*);
1111       virtual void streamTo(SourceStream&) const;
1112       PassRefPtr<ClauseListNode> releaseNext() { return next.release(); }
1113       virtual void breakCycle();
1114   private:
1115       friend class CaseBlockNode;
1116       RefPtr<CaseClauseNode> clause;
1117       ListRefPtr<ClauseListNode> next;
1118   };
1119   
1120   class CaseBlockNode : public Node {
1121   public:
1122       CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d, ClauseListNode *l2);
1123       JSValue* evaluate(ExecState*);
1124       Completion evalBlock(ExecState *exec, JSValue *input);
1125       virtual void processVarDecls(ExecState*);
1126       void processFuncDecl(ExecState*);
1127       virtual void streamTo(SourceStream&) const;
1128   private:
1129       RefPtr<ClauseListNode> list1;
1130       RefPtr<CaseClauseNode> def;
1131       RefPtr<ClauseListNode> list2;
1132   };
1133   
1134   class SwitchNode : public StatementNode {
1135   public:
1136       SwitchNode(Node *e, CaseBlockNode *b) : expr(e), block(b) { }
1137       virtual Completion execute(ExecState*);
1138       virtual void processVarDecls(ExecState*);
1139       virtual void processFuncDecl(ExecState*);
1140       virtual void streamTo(SourceStream&) const;
1141   private:
1142       RefPtr<Node> expr;
1143       RefPtr<CaseBlockNode> block;
1144   };
1145   
1146   class ProgramNode : public FunctionBodyNode {
1147   public:
1148     ProgramNode(SourceElementsNode *s);
1149   };
1150
1151 } // namespace
1152
1153 #endif