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