/* * 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 #include #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 *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