e8d0806e017dd3b3b1f49966bf0152af41bcee33
[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     VarDeclNode(const Identifier &id, AssignExprNode *in);
637     virtual void ref();
638     virtual bool deref();
639     Value evaluate(ExecState *exec);
640     virtual void processVarDecls(ExecState *exec);
641     virtual void streamTo(SourceStream &s) const;
642   private:
643     Identifier ident;
644     AssignExprNode *init;
645   };
646
647   class VarDeclListNode : public Node {
648   public:
649     // list pointer is tail of a circular list, cracked in the ForNode/VarStatementNode ctor
650     VarDeclListNode(VarDeclNode *v) : list(this), var(v) {}
651     VarDeclListNode(VarDeclListNode *l, VarDeclNode *v)
652       : list(l->list), var(v) { l->list = this; }
653     virtual void ref();
654     virtual bool deref();
655     Value evaluate(ExecState *exec);
656     virtual void processVarDecls(ExecState *exec);
657     virtual void streamTo(SourceStream &s) const;
658   private:
659     friend class ForNode;
660     friend class VarStatementNode;
661     VarDeclListNode *list;
662     VarDeclNode *var;
663   };
664
665   class VarStatementNode : public StatementNode {
666   public:
667     VarStatementNode(VarDeclListNode *l)
668       : list(l->list) { l->list = 0; }
669     virtual void ref();
670     virtual bool deref();
671     virtual Completion execute(ExecState *exec);
672     virtual void processVarDecls(ExecState *exec);
673     virtual void streamTo(SourceStream &s) const;
674   private:
675     VarDeclListNode *list;
676   };
677
678   class BlockNode : public StatementNode {
679   public:
680     BlockNode(SourceElementsNode *s);
681     virtual void ref();
682     virtual bool deref();
683     virtual Completion execute(ExecState *exec);
684     virtual void processVarDecls(ExecState *exec);
685     virtual void streamTo(SourceStream &s) const;
686   protected:
687     SourceElementsNode *source;
688   };
689
690   class EmptyStatementNode : public StatementNode {
691   public:
692     EmptyStatementNode() { } // debug
693     virtual Completion execute(ExecState *exec);
694     virtual void streamTo(SourceStream &s) const;
695   };
696
697   class ExprStatementNode : public StatementNode {
698   public:
699     ExprStatementNode(Node *e) : expr(e) { }
700     virtual void ref();
701     virtual bool deref();
702     virtual Completion execute(ExecState *exec);
703     virtual void streamTo(SourceStream &s) const;
704   private:
705     Node *expr;
706   };
707
708   class IfNode : public StatementNode {
709   public:
710     IfNode(Node *e, StatementNode *s1, StatementNode *s2)
711       : expr(e), statement1(s1), statement2(s2) {}
712     virtual void ref();
713     virtual bool deref();
714     virtual Completion execute(ExecState *exec);
715     virtual void processVarDecls(ExecState *exec);
716     virtual void streamTo(SourceStream &s) const;
717   private:
718     Node *expr;
719     StatementNode *statement1, *statement2;
720   };
721
722   class DoWhileNode : public StatementNode {
723   public:
724     DoWhileNode(StatementNode *s, Node *e) : statement(s), expr(e) {}
725     virtual void ref();
726     virtual bool deref();
727     virtual Completion execute(ExecState *exec);
728     virtual void processVarDecls(ExecState *exec);
729     virtual void streamTo(SourceStream &s) const;
730   private:
731     StatementNode *statement;
732     Node *expr;
733   };
734
735   class WhileNode : public StatementNode {
736   public:
737     WhileNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
738     virtual void ref();
739     virtual bool deref();
740     virtual Completion execute(ExecState *exec);
741     virtual void processVarDecls(ExecState *exec);
742     virtual void streamTo(SourceStream &s) const;
743   private:
744     Node *expr;
745     StatementNode *statement;
746   };
747
748   class ForNode : public StatementNode {
749   public:
750     ForNode(Node *e1, Node *e2, Node *e3, StatementNode *s) :
751       expr1(e1), expr2(e2), expr3(e3), statement(s) {}
752     ForNode(VarDeclListNode *e1, Node *e2, Node *e3, StatementNode *s) :
753       expr1(e1->list), expr2(e2), expr3(e3), statement(s) { e1->list = 0; }
754     virtual void ref();
755     virtual bool deref();
756     virtual Completion execute(ExecState *exec);
757     virtual void processVarDecls(ExecState *exec);
758     virtual void streamTo(SourceStream &s) const;
759   private:
760     Node *expr1, *expr2, *expr3;
761     StatementNode *statement;
762   };
763
764   class ForInNode : public StatementNode {
765   public:
766     ForInNode(Node *l, Node *e, StatementNode *s);
767     ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s);
768     virtual void ref();
769     virtual bool deref();
770     virtual Completion execute(ExecState *exec);
771     virtual void processVarDecls(ExecState *exec);
772     virtual void streamTo(SourceStream &s) const;
773   private:
774     Identifier ident;
775     AssignExprNode *init;
776     Node *lexpr, *expr;
777     VarDeclNode *varDecl;
778     StatementNode *statement;
779   };
780
781   class ContinueNode : public StatementNode {
782   public:
783     ContinueNode() { }
784     ContinueNode(const Identifier &i) : ident(i) { }
785     virtual Completion execute(ExecState *exec);
786     virtual void streamTo(SourceStream &s) const;
787   private:
788     Identifier ident;
789   };
790
791   class BreakNode : public StatementNode {
792   public:
793     BreakNode() { }
794     BreakNode(const Identifier &i) : ident(i) { }
795     virtual Completion execute(ExecState *exec);
796     virtual void streamTo(SourceStream &s) const;
797   private:
798     Identifier ident;
799   };
800
801   class ReturnNode : public StatementNode {
802   public:
803     ReturnNode(Node *v) : value(v) {}
804     virtual void ref();
805     virtual bool deref();
806     virtual Completion execute(ExecState *exec);
807     virtual void streamTo(SourceStream &s) const;
808   private:
809     Node *value;
810   };
811
812   class WithNode : public StatementNode {
813   public:
814     WithNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
815     virtual void ref();
816     virtual bool deref();
817     virtual Completion execute(ExecState *exec);
818     virtual void processVarDecls(ExecState *exec);
819     virtual void streamTo(SourceStream &s) const;
820   private:
821     Node *expr;
822     StatementNode *statement;
823   };
824
825   class CaseClauseNode : public Node {
826   public:
827     CaseClauseNode(Node *e) : expr(e), list(0) { }
828     CaseClauseNode(Node *e, StatListNode *l)
829       : expr(e), list(l->list) { l->list = 0; }
830     virtual void ref();
831     virtual bool deref();
832     Value evaluate(ExecState *exec);
833     Completion evalStatements(ExecState *exec);
834     virtual void processVarDecls(ExecState *exec);
835     virtual void streamTo(SourceStream &s) const;
836   private:
837     Node *expr;
838     StatListNode *list;
839   };
840
841   class ClauseListNode : public Node {
842   public:
843     // list pointer is tail of a circular list, cracked in the CaseBlockNode ctor
844     ClauseListNode(CaseClauseNode *c) : cl(c), nx(this) { }
845     ClauseListNode(ClauseListNode *n, CaseClauseNode *c)
846       : cl(c), nx(n->nx) { n->nx = this; }
847     virtual void ref();
848     virtual bool deref();
849     Value evaluate(ExecState *exec);
850     CaseClauseNode *clause() const { return cl; }
851     ClauseListNode *next() const { return nx; }
852     virtual void processVarDecls(ExecState *exec);
853     virtual void streamTo(SourceStream &s) const;
854   private:
855     friend class CaseBlockNode;
856     CaseClauseNode *cl;
857     ClauseListNode *nx;
858   };
859
860   class CaseBlockNode : public Node {
861   public:
862     CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d, ClauseListNode *l2);
863     virtual void ref();
864     virtual bool deref();
865     Value evaluate(ExecState *exec);
866     Completion evalBlock(ExecState *exec, const Value& input);
867     virtual void processVarDecls(ExecState *exec);
868     virtual void streamTo(SourceStream &s) const;
869   private:
870     ClauseListNode *list1;
871     CaseClauseNode *def;
872     ClauseListNode *list2;
873   };
874
875   class SwitchNode : public StatementNode {
876   public:
877     SwitchNode(Node *e, CaseBlockNode *b) : expr(e), block(b) { }
878     virtual void ref();
879     virtual bool deref();
880     virtual Completion execute(ExecState *exec);
881     virtual void processVarDecls(ExecState *exec);
882     virtual void streamTo(SourceStream &s) const;
883   private:
884     Node *expr;
885     CaseBlockNode *block;
886   };
887
888   class LabelNode : public StatementNode {
889   public:
890     LabelNode(const Identifier &l, StatementNode *s) : label(l), statement(s) { }
891     virtual void ref();
892     virtual bool deref();
893     virtual Completion execute(ExecState *exec);
894     virtual void processVarDecls(ExecState *exec);
895     virtual void streamTo(SourceStream &s) const;
896   private:
897     Identifier label;
898     StatementNode *statement;
899   };
900
901   class ThrowNode : public StatementNode {
902   public:
903     ThrowNode(Node *e) : expr(e) {}
904     virtual void ref();
905     virtual bool deref();
906     virtual Completion execute(ExecState *exec);
907     virtual void streamTo(SourceStream &s) const;
908   private:
909     Node *expr;
910   };
911
912   class CatchNode : public StatementNode {
913   public:
914     CatchNode(const Identifier &i, StatementNode *b) : ident(i), block(b) {}
915     virtual void ref();
916     virtual bool deref();
917     virtual Completion execute(ExecState *exec);
918     Completion execute(ExecState *exec, const Value &arg);
919     virtual void processVarDecls(ExecState *exec);
920     virtual void streamTo(SourceStream &s) const;
921   private:
922     Identifier ident;
923     StatementNode *block;
924   };
925
926   class FinallyNode : public StatementNode {
927   public:
928     FinallyNode(StatementNode *b) : block(b) {}
929     virtual void ref();
930     virtual bool deref();
931     virtual Completion execute(ExecState *exec);
932     virtual void processVarDecls(ExecState *exec);
933     virtual void streamTo(SourceStream &s) const;
934   private:
935     StatementNode *block;
936   };
937
938   class TryNode : public StatementNode {
939   public:
940     TryNode(StatementNode *b, CatchNode *c)
941       : block(b), _catch(c), _final(0) {}
942     TryNode(StatementNode *b, FinallyNode *f)
943       : block(b), _catch(0), _final(f) {}
944     TryNode(StatementNode *b, CatchNode *c, FinallyNode *f)
945       : block(b), _catch(c), _final(f) {}
946     virtual void ref();
947     virtual bool deref();
948     virtual Completion execute(ExecState *exec);
949     virtual void processVarDecls(ExecState *exec);
950     virtual void streamTo(SourceStream &s) const;
951   private:
952     StatementNode *block;
953     CatchNode *_catch;
954     FinallyNode *_final;
955   };
956
957   class ParameterNode : public Node {
958   public:
959     // list pointer is tail of a circular list, cracked in the FuncDeclNode/FuncExprNode ctor
960     ParameterNode(const Identifier &i) : id(i), next(this) { }
961     ParameterNode(ParameterNode *list, const Identifier &i)
962       : id(i), next(list->next) { list->next = this; }
963     virtual void ref();
964     virtual bool deref();
965     Value evaluate(ExecState *exec);
966     Identifier ident() { return id; }
967     ParameterNode *nextParam() { return next; }
968     virtual void streamTo(SourceStream &s) const;
969   private:
970     friend class FuncDeclNode;
971     friend class FuncExprNode;
972     Identifier id;
973     ParameterNode *next;
974   };
975
976   // inherited by ProgramNode
977   class FunctionBodyNode : public BlockNode {
978   public:
979     FunctionBodyNode(SourceElementsNode *s);
980     void processFuncDecl(ExecState *exec);
981   };
982
983   class FuncDeclNode : public StatementNode {
984   public:
985     FuncDeclNode(const Identifier &i, FunctionBodyNode *b)
986       : ident(i), param(0), body(b) { }
987     FuncDeclNode(const Identifier &i, ParameterNode *p, FunctionBodyNode *b)
988       : ident(i), param(p->next), body(b) { p->next = 0; }
989     virtual void ref();
990     virtual bool deref();
991     Completion execute(ExecState */*exec*/)
992       { /* empty */ return Completion(); }
993     void processFuncDecl(ExecState *exec);
994     virtual void streamTo(SourceStream &s) const;
995   private:
996     Identifier ident;
997     ParameterNode *param;
998     FunctionBodyNode *body;
999   };
1000
1001   class FuncExprNode : public Node {
1002   public:
1003     FuncExprNode(FunctionBodyNode *b) : param(0), body(b) { }
1004     FuncExprNode(ParameterNode *p, FunctionBodyNode *b)
1005       : param(p->next), body(b) { p->next = 0; }
1006     virtual void ref();
1007     virtual bool deref();
1008     Value evaluate(ExecState *exec);
1009     virtual void streamTo(SourceStream &s) const;
1010   private:
1011     ParameterNode *param;
1012     FunctionBodyNode *body;
1013   };
1014
1015   // A linked list of source element nodes
1016   class SourceElementsNode : public StatementNode {
1017   public:
1018     // list pointer is tail of a circular list, cracked in the BlockNode (or subclass) ctor
1019     SourceElementsNode(StatementNode *s1);
1020     SourceElementsNode(SourceElementsNode *s1, StatementNode *s2);
1021     virtual void ref();
1022     virtual bool deref();
1023     Completion execute(ExecState *exec);
1024     void processFuncDecl(ExecState *exec);
1025     virtual void processVarDecls(ExecState *exec);
1026     virtual void streamTo(SourceStream &s) const;
1027   private:
1028     friend class BlockNode;
1029     StatementNode *element; // 'this' element
1030     SourceElementsNode *elements; // pointer to next
1031   };
1032
1033   class ProgramNode : public FunctionBodyNode {
1034   public:
1035     ProgramNode(SourceElementsNode *s);
1036   };
1037
1038 }; // namespace
1039
1040 #endif