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