summaryrefslogtreecommitdiffstats
path: root/kjs/nodes.h
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch)
tree5ac38a06f3dde268dc7927dc155896926aaf7012 /kjs/nodes.h
downloadtdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz
tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kjs/nodes.h')
-rw-r--r--kjs/nodes.h1082
1 files changed, 1082 insertions, 0 deletions
diff --git a/kjs/nodes.h b/kjs/nodes.h
new file mode 100644
index 000000000..4f7e10d36
--- /dev/null
+++ b/kjs/nodes.h
@@ -0,0 +1,1082 @@
+// -*- c-basic-offset: 2 -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 1999-2000, 2003 Harri Porten (porten@kde.org)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2003 Apple Computer, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef _NODES_H_
+#define _NODES_H_
+
+#include "internal.h"
+//#include "debugger.h"
+#ifndef NDEBUG
+#include <list>
+#include <assert.h>
+#endif
+
+namespace KJS {
+
+ class RegExp;
+ class SourceElementsNode;
+ class ObjectLiteralNode;
+ class PropertyNode;
+ class SourceStream;
+ class PropertyValueNode;
+ class PropertyNode;
+
+ enum Operator { OpEqual,
+ OpEqEq,
+ OpNotEq,
+ OpStrEq,
+ OpStrNEq,
+ OpPlusEq,
+ OpMinusEq,
+ OpMultEq,
+ OpDivEq,
+ OpPlusPlus,
+ OpMinusMinus,
+ OpLess,
+ OpLessEq,
+ OpGreater,
+ OpGreaterEq,
+ OpAndEq,
+ OpXOrEq,
+ OpOrEq,
+ OpModEq,
+ OpAnd,
+ OpOr,
+ OpBitAnd,
+ OpBitXOr,
+ OpBitOr,
+ OpLShift,
+ OpRShift,
+ OpURShift,
+ OpIn,
+ OpInstanceOf
+ };
+
+ class Node {
+ public:
+ Node();
+ virtual ~Node();
+
+ // reusing Value Type here, declare new enum if required
+ virtual Type type() const { return UnspecifiedType; }
+
+ /**
+ * Evaluate this node and return the result, possibly a reference.
+ */
+ virtual Reference evaluateReference(ExecState *exec) const;
+ /**
+ * Returns the value represented by this node. Always dereferenced.
+ */
+ virtual Value evaluate(ExecState *exec) const;
+ virtual bool toBoolean(ExecState *exec) const;
+ virtual double toNumber(ExecState *exec) const;
+ virtual UString toString(ExecState *exec) const;
+
+ UString toCode() const;
+ virtual void streamTo(SourceStream &s) const = 0;
+ virtual void processVarDecls(ExecState* /*exec*/) {}
+ int lineNo() const { return line; }
+
+ public:
+ // reference counting mechanism
+ virtual void ref() { refcount++; }
+#ifdef KJS_DEBUG_MEM
+ virtual bool deref() { assert( refcount > 0 ); return (!--refcount); }
+#else
+ virtual bool deref() { return (!--refcount); }
+#endif
+
+
+#ifdef KJS_DEBUG_MEM
+ static void finalCheck();
+#endif
+ protected:
+ Value throwError(ExecState *exec, ErrorType e, const char *msg) const;
+ Value throwError(ExecState *exec, ErrorType e, const char *msg,
+ const Value &v, const Node *expr) const;
+ Value throwError(ExecState *exec, ErrorType e, const char *msg, Identifier label) const;
+ void setExceptionDetailsIfNeeded(ExecState *exec) const;
+ int line;
+ unsigned int refcount;
+ virtual int sourceId() const { return -1; }
+ private:
+#ifdef KJS_DEBUG_MEM
+ // List of all nodes, for debugging purposes. Don't remove!
+ static std::list<Node *> *s_nodes;
+#endif
+ // disallow assignment
+ Node& operator=(const Node&);
+ Node(const Node &other);
+ };
+
+ class StatementNode : public Node {
+ public:
+ StatementNode();
+ virtual ~StatementNode();
+ void setLoc(int line0, int line1, SourceCode *src);
+ int firstLine() const { return l0; }
+ int lastLine() const { return l1; }
+ int sourceId() const { return sourceCode->sid; }
+ SourceCode *code() const { return sourceCode; }
+ bool hitStatement(ExecState *exec);
+ bool abortStatement(ExecState *exec);
+ virtual Completion execute(ExecState *exec) = 0;
+ void pushLabel(const Identifier &id) { ls.push(id); }
+ virtual void processFuncDecl(ExecState *exec);
+ protected:
+ LabelStack ls;
+ private:
+ Reference evaluateReference(ExecState* /*exec*/) const { return Reference(0,Identifier::null()); }
+ int l0, l1;
+ SourceCode *sourceCode;
+ bool breakPoint;
+ };
+
+ class NullNode : public Node {
+ public:
+ NullNode() {}
+ virtual Value evaluate(ExecState *exec) const;
+ virtual bool toBoolean(ExecState *exec) const;
+ virtual double toNumber(ExecState *exec) const;
+ virtual UString toString(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ };
+
+ class BooleanNode : public Node {
+ public:
+ BooleanNode(bool v) : val(v) {}
+ virtual Type type() const { return BooleanType; }
+ virtual Value evaluate(ExecState *exec) const;
+ virtual bool toBoolean(ExecState *exec) const;
+ virtual double toNumber(ExecState *exec) const;
+ virtual UString toString(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ bool val;
+ };
+
+ class NumberNode : public Node {
+ public:
+ NumberNode(double v) : val(v) { }
+ virtual Type type() const { return NumberType; }
+ virtual Value evaluate(ExecState *exec) const;
+ virtual bool toBoolean(ExecState *exec) const;
+ virtual double toNumber(ExecState *exec) const;
+ virtual UString toString(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ double val;
+ };
+
+ class StringNode : public Node {
+ public:
+ StringNode(const UString *v) : val(*v) { }
+ virtual Type type() const { return StringType; }
+ virtual Value evaluate(ExecState *exec) const;
+ virtual bool toBoolean(ExecState *exec) const;
+ virtual double toNumber(ExecState *exec) const;
+ virtual UString toString(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ UString val;
+ };
+
+ class RegExpNode : public Node {
+ public:
+ RegExpNode(const UString &p, const UString &f)
+ : pattern(p), flags(f) { }
+ virtual Value evaluate(ExecState *exec) const;
+ virtual bool toBoolean(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ UString pattern, flags;
+ };
+
+ class ThisNode : public Node {
+ public:
+ ThisNode() {}
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ };
+
+ class ResolveNode : public Node {
+ public:
+ ResolveNode(const Identifier &s) : ident(s) { }
+ Reference evaluateReference(ExecState *exec) const;
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Identifier ident;
+ };
+
+ class GroupNode : public Node {
+ public:
+ GroupNode(Node *g) : group(g) { }
+ virtual void ref();
+ virtual bool deref();
+ Reference evaluateReference(ExecState *exec) const;
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *group;
+ };
+
+ class ElementNode : public Node {
+ public:
+ // list is circular during construction. cracked in ArrayNode ctor
+ ElementNode(int e, Node *n) : list(this), elision(e), node(n) { }
+ ElementNode(ElementNode *l, int e, Node *n)
+ : list(l->list), elision(e), node(n) { l->list = this; }
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ friend class ArrayNode;
+ ElementNode *list;
+ int elision;
+ Node *node;
+ };
+
+ class ArrayNode : public Node {
+ public:
+ ArrayNode(int e) : element(0L), elision(e), opt(true) { }
+ ArrayNode(ElementNode *ele)
+ : element(ele->list), elision(0), opt(false) { ele->list = 0; }
+ ArrayNode(int eli, ElementNode *ele)
+ : element(ele->list), elision(eli), opt(true) { ele->list = 0; }
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ ElementNode *element;
+ int elision;
+ bool opt;
+ };
+
+ class PropertyValueNode : public Node {
+ public:
+ // list is circular during construction, cut in ObjectLiteralNode ctor
+ PropertyValueNode(PropertyNode *n, Node *a)
+ : name(n), assign(a), list(this) { }
+ PropertyValueNode(PropertyNode *n, Node *a, PropertyValueNode *l)
+ : name(n), assign(a), list(l->list) { l->list = this; }
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ friend class ObjectLiteralNode;
+ PropertyNode *name;
+ Node *assign;
+ PropertyValueNode *list;
+ };
+
+ class PropertyNode : public Node {
+ public:
+ PropertyNode(double d) : numeric(d) { }
+ PropertyNode(const Identifier &s) : str(s) { }
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ double numeric;
+ Identifier str;
+ };
+
+ class ObjectLiteralNode : public Node {
+ public:
+ // empty literal
+ ObjectLiteralNode() : list(0) { }
+ // l points to last list element, get and detach pointer to first one
+ ObjectLiteralNode(PropertyValueNode *l) : list(l->list) { l->list = 0; }
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ PropertyValueNode *list;
+ };
+
+ class AccessorNode1 : public Node {
+ public:
+ AccessorNode1(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
+ virtual void ref();
+ virtual bool deref();
+ Reference evaluateReference(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr1;
+ Node *expr2;
+ };
+
+ class AccessorNode2 : public Node {
+ public:
+ AccessorNode2(Node *e, const Identifier &s) : expr(e), ident(s) { }
+ virtual void ref();
+ virtual bool deref();
+ Reference evaluateReference(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ Identifier ident;
+ };
+
+ class ArgumentListNode : public Node {
+ public:
+ // list is circular during construction. cracked in ArgumentsNode ctor
+ ArgumentListNode(Node *e) : list(this), expr(e) {}
+ ArgumentListNode(ArgumentListNode *l, Node *e)
+ : list(l->list), expr(e) { l->list = this; }
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ List evaluateList(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ friend class ArgumentsNode;
+ ArgumentListNode *list;
+ Node *expr;
+ };
+
+ class ArgumentsNode : public Node {
+ public:
+ ArgumentsNode() : list(0) {}
+ ArgumentsNode(ArgumentListNode *l) : list(l->list) { l->list = 0; }
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ List evaluateList(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ ArgumentListNode *list;
+ };
+
+ class NewExprNode : public Node {
+ public:
+ NewExprNode(Node *e) : expr(e), args(0L) {}
+ NewExprNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ ArgumentsNode *args;
+ };
+
+ class FunctionCallNode : public Node {
+ public:
+ FunctionCallNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ ArgumentsNode *args;
+ };
+
+ class PostfixNode : public Node {
+ public:
+ PostfixNode(Node *e, Operator o) : expr(e), oper(o) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ Operator oper;
+ };
+
+ class DeleteNode : public Node {
+ public:
+ DeleteNode(Node *e) : expr(e) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ };
+
+ class VoidNode : public Node {
+ public:
+ VoidNode(Node *e) : expr(e) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ };
+
+ class TypeOfNode : public Node {
+ public:
+ TypeOfNode(Node *e) : expr(e) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ };
+
+ class PrefixNode : public Node {
+ public:
+ PrefixNode(Operator o, Node *e) : oper(o), expr(e) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Operator oper;
+ Node *expr;
+ };
+
+ class UnaryPlusNode : public Node {
+ public:
+ UnaryPlusNode(Node *e) : expr(e) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual double toNumber(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ };
+
+ class NegateNode : public Node {
+ public:
+ NegateNode(Node *e) : expr(e) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual double toNumber(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ };
+
+ class BitwiseNotNode : public Node {
+ public:
+ BitwiseNotNode(Node *e) : expr(e) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ };
+
+ class LogicalNotNode : public Node {
+ public:
+ LogicalNotNode(Node *e) : expr(e) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual bool toBoolean(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ };
+
+ class MultNode : public Node {
+ public:
+ MultNode(Node *t1, Node *t2, char op) : term1(t1), term2(t2), oper(op) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *term1, *term2;
+ char oper;
+ };
+
+ class AddNode : public Node {
+ public:
+ AddNode(Node *t1, Node *t2, char op) : term1(t1), term2(t2), oper(op) {}
+
+ static Node* create(Node *t1, Node *t2, char op);
+
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *term1, *term2;
+ char oper;
+ };
+
+ class AppendStringNode : public Node {
+ public:
+ AppendStringNode(Node *t, const UString &s) : term(t), str(s) { }
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *term;
+ UString str;
+ };
+
+ class ShiftNode : public Node {
+ public:
+ ShiftNode(Node *t1, Operator o, Node *t2)
+ : term1(t1), term2(t2), oper(o) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *term1, *term2;
+ Operator oper;
+ };
+
+ class RelationalNode : public Node {
+ public:
+ RelationalNode(Node *e1, Operator o, Node *e2) :
+ expr1(e1), expr2(e2), oper(o) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr1, *expr2;
+ Operator oper;
+ };
+
+ class EqualNode : public Node {
+ public:
+ EqualNode(Node *e1, Operator o, Node *e2)
+ : expr1(e1), expr2(e2), oper(o) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr1, *expr2;
+ Operator oper;
+ };
+
+ class BitOperNode : public Node {
+ public:
+ BitOperNode(Node *e1, Operator o, Node *e2) :
+ expr1(e1), expr2(e2), oper(o) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr1, *expr2;
+ Operator oper;
+ };
+
+ /**
+ * expr1 && expr2, expr1 || expr2
+ */
+ class BinaryLogicalNode : public Node {
+ public:
+ BinaryLogicalNode(Node *e1, Operator o, Node *e2) :
+ expr1(e1), expr2(e2), oper(o) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr1, *expr2;
+ Operator oper;
+ };
+
+ /**
+ * The ternary operator, "logical ? expr1 : expr2"
+ */
+ class ConditionalNode : public Node {
+ public:
+ ConditionalNode(Node *l, Node *e1, Node *e2) :
+ logical(l), expr1(e1), expr2(e2) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *logical, *expr1, *expr2;
+ };
+
+ class AssignNode : public Node {
+ public:
+ AssignNode(Node *l, Operator o, Node *e) : left(l), oper(o), expr(e) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *left;
+ Operator oper;
+ Node *expr;
+ };
+
+ class CommaNode : public Node {
+ public:
+ CommaNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr1, *expr2;
+ };
+
+ class StatListNode : public StatementNode {
+ public:
+ // list is circular during construction. cracked in CaseClauseNode ctor
+ StatListNode(StatementNode *s);
+ StatListNode(StatListNode *l, StatementNode *s);
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ friend class CaseClauseNode;
+ StatementNode *statement;
+ StatListNode *list;
+ };
+
+ class AssignExprNode : public Node {
+ public:
+ AssignExprNode(Node *e) : expr(e) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ };
+
+ class VarDeclNode : public Node {
+ public:
+ enum Type { Variable, Constant };
+ VarDeclNode(const Identifier &id, AssignExprNode *in, Type t);
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Type varType;
+ Identifier ident;
+ AssignExprNode *init;
+ };
+
+ class VarDeclListNode : public Node {
+ public:
+ // list pointer is tail of a circular list, cracked in the ForNode/VarStatementNode ctor
+ VarDeclListNode(VarDeclNode *v) : list(this), var(v) {}
+ VarDeclListNode(VarDeclListNode *l, VarDeclNode *v)
+ : list(l->list), var(v) { l->list = this; }
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ friend class ForNode;
+ friend class VarStatementNode;
+ VarDeclListNode *list;
+ VarDeclNode *var;
+ };
+
+ class VarStatementNode : public StatementNode {
+ public:
+ VarStatementNode(VarDeclListNode *l) : list(l->list) { l->list = 0; }
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ VarDeclListNode *list;
+ };
+
+ class BlockNode : public StatementNode {
+ public:
+ BlockNode(SourceElementsNode *s);
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ protected:
+ SourceElementsNode *source;
+ };
+
+ class EmptyStatementNode : public StatementNode {
+ public:
+ EmptyStatementNode() { } // debug
+ virtual Completion execute(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ };
+
+ class ExprStatementNode : public StatementNode {
+ public:
+ ExprStatementNode(Node *e) : expr(e) { }
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ };
+
+ class IfNode : public StatementNode {
+ public:
+ IfNode(Node *e, StatementNode *s1, StatementNode *s2)
+ : expr(e), statement1(s1), statement2(s2) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ StatementNode *statement1, *statement2;
+ };
+
+ class DoWhileNode : public StatementNode {
+ public:
+ DoWhileNode(StatementNode *s, Node *e) : statement(s), expr(e) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ StatementNode *statement;
+ Node *expr;
+ };
+
+ class WhileNode : public StatementNode {
+ public:
+ WhileNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ StatementNode *statement;
+ };
+
+ class ForNode : public StatementNode {
+ public:
+ ForNode(Node *e1, Node *e2, Node *e3, StatementNode *s) :
+ expr1(e1), expr2(e2), expr3(e3), statement(s) {}
+ ForNode(VarDeclListNode *e1, Node *e2, Node *e3, StatementNode *s) :
+ expr1(e1->list), expr2(e2), expr3(e3), statement(s) { e1->list = 0; }
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr1, *expr2, *expr3;
+ StatementNode *statement;
+ };
+
+ class ForInNode : public StatementNode {
+ public:
+ ForInNode(Node *l, Node *e, StatementNode *s);
+ ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s);
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Identifier ident;
+ AssignExprNode *init;
+ Node *lexpr, *expr;
+ VarDeclNode *varDecl;
+ StatementNode *statement;
+ };
+
+ class ContinueNode : public StatementNode {
+ public:
+ ContinueNode() { }
+ ContinueNode(const Identifier &i) : ident(i) { }
+ virtual Completion execute(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Identifier ident;
+ };
+
+ class BreakNode : public StatementNode {
+ public:
+ BreakNode() { }
+ BreakNode(const Identifier &i) : ident(i) { }
+ virtual Completion execute(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Identifier ident;
+ };
+
+ class ReturnNode : public StatementNode {
+ public:
+ ReturnNode(Node *v) : value(v) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *value;
+ };
+
+ class WithNode : public StatementNode {
+ public:
+ WithNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ StatementNode *statement;
+ };
+
+ class CaseClauseNode : public Node {
+ public:
+ CaseClauseNode(Node *e) : expr(e), list(0) { }
+ CaseClauseNode(Node *e, StatListNode *l)
+ : expr(e), list(l->list) { l->list = 0; }
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ Completion evalStatements(ExecState *exec) const;
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ StatListNode *list;
+ };
+
+ class ClauseListNode : public Node {
+ public:
+ // list is circular during construction. cracked in CaseBlockNode ctor
+ ClauseListNode(CaseClauseNode *c) : cl(c), nx(this) { }
+ ClauseListNode(ClauseListNode *n, CaseClauseNode *c)
+ : cl(c), nx(n->nx) { n->nx = this; }
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ CaseClauseNode *clause() const { return cl; }
+ ClauseListNode *next() const { return nx; }
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ friend class CaseBlockNode;
+ CaseClauseNode *cl;
+ ClauseListNode *nx;
+ };
+
+ class CaseBlockNode: public Node {
+ public:
+ CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d, ClauseListNode *l2);
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ Completion evalBlock(ExecState *exec, const Value& input) const;
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ ClauseListNode *list1;
+ CaseClauseNode *def;
+ ClauseListNode *list2;
+ };
+
+ class SwitchNode : public StatementNode {
+ public:
+ SwitchNode(Node *e, CaseBlockNode *b) : expr(e), block(b) { }
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ CaseBlockNode *block;
+ };
+
+ class LabelNode : public StatementNode {
+ public:
+ LabelNode(const Identifier &l, StatementNode *s) : label(l), statement(s) { }
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Identifier label;
+ StatementNode *statement;
+ };
+
+ class ThrowNode : public StatementNode {
+ public:
+ ThrowNode(Node *e) : expr(e) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Node *expr;
+ };
+
+ class CatchNode : public StatementNode {
+ public:
+ CatchNode(const Identifier &i, StatementNode *b) : ident(i), block(b) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ Completion execute(ExecState *exec, const Value &arg);
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Identifier ident;
+ StatementNode *block;
+ };
+
+ class FinallyNode : public StatementNode {
+ public:
+ FinallyNode(StatementNode *b) : block(b) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ StatementNode *block;
+ };
+
+ class TryNode : public StatementNode {
+ public:
+ TryNode(StatementNode *b, CatchNode *c)
+ : block(b), _catch(c), _final(0) {}
+ TryNode(StatementNode *b, FinallyNode *f)
+ : block(b), _catch(0), _final(f) {}
+ TryNode(StatementNode *b, CatchNode *c, FinallyNode *f)
+ : block(b), _catch(c), _final(f) {}
+ virtual void ref();
+ virtual bool deref();
+ virtual Completion execute(ExecState *exec);
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ StatementNode *block;
+ CatchNode *_catch;
+ FinallyNode *_final;
+ };
+
+ class ParameterNode : public Node {
+ public:
+ // list is circular during construction. cracked in FuncDecl/ExprNode ctor.
+ ParameterNode(const Identifier &i) : id(i), next(this) { }
+ ParameterNode(ParameterNode *list, const Identifier &i)
+ : id(i), next(list->next) { list->next = this; }
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ Identifier ident() const { return id; }
+ ParameterNode *nextParam() const { return next; }
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ friend class FuncDeclNode;
+ friend class FuncExprNode;
+ Identifier id;
+ ParameterNode *next;
+ };
+
+ // inherited by ProgramNode
+ class FunctionBodyNode : public BlockNode {
+ public:
+ FunctionBodyNode(SourceElementsNode *s);
+ virtual void processFuncDecl(ExecState *exec);
+ };
+
+ class FuncDeclNode : public StatementNode {
+ public:
+ FuncDeclNode(const Identifier &i, FunctionBodyNode *b)
+ : ident(i), param(0), body(b) { }
+ FuncDeclNode(const Identifier &i, ParameterNode *p, FunctionBodyNode *b)
+ : ident(i), param(p->next), body(b) { p->next = 0; }
+ virtual void ref();
+ virtual bool deref();
+ Completion execute(ExecState* /*exec*/)
+ { /* empty */ return Completion(); }
+ void processFuncDecl(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Identifier ident;
+ ParameterNode *param;
+ FunctionBodyNode *body;
+ };
+
+ class FuncExprNode : public Node {
+ public:
+ FuncExprNode(const Identifier &i, FunctionBodyNode *b)
+ : ident(i), param(0), body(b) { }
+ FuncExprNode(const Identifier &i, ParameterNode *p, FunctionBodyNode *b)
+ : ident(i), param(p->next), body(b) { p->next = 0; }
+ virtual void ref();
+ virtual bool deref();
+ virtual Value evaluate(ExecState *exec) const;
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ Identifier ident;
+ ParameterNode *param;
+ FunctionBodyNode *body;
+ };
+
+ // A linked list of source element nodes
+ class SourceElementsNode : public StatementNode {
+ public:
+ // list is circular until cracked in BlockNode (or subclass) ctor
+ SourceElementsNode(StatementNode *s1);
+ SourceElementsNode(SourceElementsNode *s1, StatementNode *s2);
+ virtual void ref();
+ virtual bool deref();
+ Completion execute(ExecState *exec);
+ virtual void processFuncDecl(ExecState *exec);
+ virtual void processVarDecls(ExecState *exec);
+ virtual void streamTo(SourceStream &s) const;
+ private:
+ friend class BlockNode;
+ StatementNode *element; // 'this' element
+ SourceElementsNode *elements; // pointer to next
+ };
+
+} // namespace
+
+#endif