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