You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1082 lines
31 KiB
1082 lines
31 KiB
15 years ago
|
/*
|
||
|
* 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
|