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