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