mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Added expression parsing and printing code
This commit is contained in:
parent
f240e58708
commit
66582beffd
File diff suppressed because it is too large
Load Diff
150
js/js2/parser.h
150
js/js2/parser.h
@ -40,7 +40,7 @@ namespace JavaScript {
|
|||||||
const char16 *p; // Position in source text
|
const char16 *p; // Position in source text
|
||||||
const char16 *end; // End of source text; *end is a null character
|
const char16 *end; // End of source text; *end is a null character
|
||||||
public:
|
public:
|
||||||
String source; // Source text
|
const String source; // Source text
|
||||||
const String sourceLocation; // Description of location from which the source text came
|
const String sourceLocation; // Description of location from which the source text came
|
||||||
private:
|
private:
|
||||||
const uint32 initialLineNum; // One-based number of current line
|
const uint32 initialLineNum; // One-based number of current line
|
||||||
@ -85,10 +85,13 @@ namespace JavaScript {
|
|||||||
// Lexer
|
// Lexer
|
||||||
//
|
//
|
||||||
|
|
||||||
|
void escapeString(Formatter &f, const char16 *begin, const char16 *end, char16 quote);
|
||||||
|
void quoteString(Formatter &f, const String &s, char16 quote);
|
||||||
|
|
||||||
|
|
||||||
class Token {
|
class Token {
|
||||||
static const char *const kindNames[];
|
|
||||||
public:
|
public:
|
||||||
enum Kind { // Keep synchronized with kindNames table
|
enum Kind { // Keep synchronized with kindNames and tokenBinaryOperatorInfos tables
|
||||||
// Special
|
// Special
|
||||||
end, // End of token stream
|
end, // End of token stream
|
||||||
|
|
||||||
@ -217,42 +220,42 @@ namespace JavaScript {
|
|||||||
With, // with
|
With, // with
|
||||||
|
|
||||||
// Non-reserved words
|
// Non-reserved words
|
||||||
Box, // box
|
Attribute, // attribute
|
||||||
Constructor, // constructor
|
Constructor, // constructor
|
||||||
Field, // field
|
|
||||||
Get, // get
|
Get, // get
|
||||||
Language, // language
|
Language, // language
|
||||||
Local, // local
|
Local, // local
|
||||||
Method, // method
|
Namespace, // namespace
|
||||||
Override, // override
|
Override, // override
|
||||||
Set, // set
|
Set, // set
|
||||||
Version, // version
|
Use, // use
|
||||||
|
|
||||||
identifier, // Non-keyword identifier (may be same as a keyword if it contains an escape code)
|
identifier, // Non-keyword identifier (may be same as a keyword if it contains an escape code)
|
||||||
|
|
||||||
KindsEnd, // End of token kinds
|
kindsEnd, // End of token kinds
|
||||||
KeywordsBegin = Abstract, // Beginning of range of special identifier tokens
|
keywordsBegin = Abstract, // Beginning of range of special identifier tokens
|
||||||
KeywordsEnd = identifier, // End of range of special identifier tokens
|
keywordsEnd = identifier, // End of range of special identifier tokens
|
||||||
NonReservedBegin = Box, // Beginning of range of non-reserved words
|
nonreservedBegin = Attribute,// Beginning of range of non-reserved words
|
||||||
NonReservedEnd = identifier,// End of range of non-reserved words
|
nonreservedEnd = identifier,// End of range of non-reserved words
|
||||||
KindsWithCharsBegin = number,// Beginning of range of tokens for which the chars field (below) is valid
|
kindsWithCharsBegin = number,// Beginning of range of tokens for which the chars field (below) is valid
|
||||||
KindsWithCharsEnd = regExp+1// End of range of tokens for which the chars field (below) is valid
|
kindsWithCharsEnd = regExp+1// End of range of tokens for which the chars field (below) is valid
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CASE_TOKEN_NONRESERVED \
|
#define CASE_TOKEN_NONRESERVED \
|
||||||
Token::Box: \
|
Token::Attribute: \
|
||||||
case Token::Constructor: \
|
case Token::Constructor: \
|
||||||
case Token::Field: \
|
|
||||||
case Token::Get: \
|
case Token::Get: \
|
||||||
case Token::Language: \
|
case Token::Language: \
|
||||||
case Token::Local: \
|
case Token::Local: \
|
||||||
case Token::Method: \
|
case Token::Namespace: \
|
||||||
case Token::Override: \
|
case Token::Override: \
|
||||||
case Token::Set: \
|
case Token::Set: \
|
||||||
case Token::Version: \
|
case Token::Use: \
|
||||||
case Token::identifier
|
case Token::identifier
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static const char *const kindNames[kindsEnd];
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool valid; // True if this token has been initialized
|
bool valid; // True if this token has been initialized
|
||||||
#endif
|
#endif
|
||||||
@ -269,16 +272,16 @@ namespace JavaScript {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static void initKeywords(World &world);
|
static void initKeywords(World &world);
|
||||||
static bool isIdentifierKind(Kind kind) {ASSERT(NonReservedEnd == identifier && KindsEnd == identifier+1); return kind >= NonReservedBegin;}
|
static bool isIdentifierKind(Kind kind) {ASSERT(nonreservedEnd == identifier && kindsEnd == identifier+1); return kind >= nonreservedBegin;}
|
||||||
static bool isSpecialKind(Kind kind) {return kind <= regExp || kind == identifier;}
|
static bool isSpecialKind(Kind kind) {return kind <= regExp || kind == identifier;}
|
||||||
static const char *kindName(Kind kind) {ASSERT(uint(kind) < KindsEnd); return kindNames[kind];}
|
static const char *kindName(Kind kind) {ASSERT(uint(kind) < kindsEnd); return kindNames[kind];}
|
||||||
|
|
||||||
Kind getKind() const {ASSERT(valid); return kind;}
|
Kind getKind() const {ASSERT(valid); return kind;}
|
||||||
bool hasKind(Kind k) const {ASSERT(valid); return kind == k;}
|
bool hasKind(Kind k) const {ASSERT(valid); return kind == k;}
|
||||||
bool getLineBreak() const {ASSERT(valid); return lineBreak;}
|
bool getLineBreak() const {ASSERT(valid); return lineBreak;}
|
||||||
uint32 getPos() const {ASSERT(valid); return pos;}
|
uint32 getPos() const {ASSERT(valid); return pos;}
|
||||||
const StringAtom &getIdentifier() const {ASSERT(valid && id); return *id;}
|
const StringAtom &getIdentifier() const {ASSERT(valid && id); return *id;}
|
||||||
const String &getChars() const {ASSERT(valid && kind >= KindsWithCharsBegin && kind < KindsWithCharsEnd); return chars;}
|
const String &getChars() const {ASSERT(valid && kind >= kindsWithCharsBegin && kind < kindsWithCharsEnd); return chars;}
|
||||||
float64 getValue() const {ASSERT(valid && kind == number); return value;}
|
float64 getValue() const {ASSERT(valid && kind == number); return value;}
|
||||||
|
|
||||||
friend Formatter &operator<<(Formatter &f, Kind k) {f << kindName(k); return f;}
|
friend Formatter &operator<<(Formatter &f, Kind k) {f << kindName(k); return f;}
|
||||||
@ -434,7 +437,8 @@ namespace JavaScript {
|
|||||||
|
|
||||||
|
|
||||||
struct ExprNode: ParseNode {
|
struct ExprNode: ParseNode {
|
||||||
enum Kind { // Actual class Operands
|
enum Kind { // Actual class Operands // Keep synchronized with kindNames
|
||||||
|
none,
|
||||||
identifier, // IdentifierExprNode <name>
|
identifier, // IdentifierExprNode <name>
|
||||||
number, // NumberExprNode <value>
|
number, // NumberExprNode <value>
|
||||||
string, // StringExprNode <str>
|
string, // StringExprNode <str>
|
||||||
@ -444,12 +448,15 @@ namespace JavaScript {
|
|||||||
False, // ExprNode false
|
False, // ExprNode false
|
||||||
This, // ExprNode this
|
This, // ExprNode this
|
||||||
Super, // ExprNode super
|
Super, // ExprNode super
|
||||||
|
Public, // ExprNode public
|
||||||
|
Package, // ExprNode package
|
||||||
|
Private, // ExprNode private
|
||||||
|
|
||||||
parentheses, // UnaryExprNode (<op>)
|
parentheses, // UnaryExprNode (<op>)
|
||||||
numUnit, // NumUnitExprNode <num> "<str>" or <num><str>
|
numUnit, // NumUnitExprNode <num> "<str>" or <num><str>
|
||||||
exprUnit, // ExprUnitExprNode (<op>) "<str>"
|
exprUnit, // ExprUnitExprNode (<op>) "<str>"
|
||||||
qualifiedIdentifier, // OpIdentifierExprNode <op> :: <name>
|
qualify, // BinaryExprNode <op1> :: <op2> (right-associative: a::b::c represented as a::(b::c))
|
||||||
|
|
||||||
objectLiteral, // PairListExprNode {<field>:<value>, <field>:<value>, ..., <field>:<value>}
|
objectLiteral, // PairListExprNode {<field>:<value>, <field>:<value>, ..., <field>:<value>}
|
||||||
arrayLiteral, // PairListExprNode [<value>, <value>, ..., <value>]
|
arrayLiteral, // PairListExprNode [<value>, <value>, ..., <value>]
|
||||||
functionLiteral, // FunctionExprNode function <function>
|
functionLiteral, // FunctionExprNode function <function>
|
||||||
@ -458,11 +465,11 @@ namespace JavaScript {
|
|||||||
New, // InvokeExprNode new <op>(<field>:<value>, <field>:<value>, ..., <field>:<value>)
|
New, // InvokeExprNode new <op>(<field>:<value>, <field>:<value>, ..., <field>:<value>)
|
||||||
index, // InvokeExprNode <op>[<field>:<value>, <field>:<value>, ..., <field>:<value>]
|
index, // InvokeExprNode <op>[<field>:<value>, <field>:<value>, ..., <field>:<value>]
|
||||||
|
|
||||||
dot, // BinaryExprNode <op1> . <op2> // <op2> must be identifier or qualifiedIdentifier
|
dot, // BinaryExprNode <op1> . <op2> // <op2> must be identifier or qualify
|
||||||
dotParen, // BinaryExprNode <op1> .( <op2> )
|
dotParen, // BinaryExprNode <op1> .( <op2> )
|
||||||
at, // BinaryExprNode <op1> @ <op2> or <op1> @( <op2> )
|
at, // BinaryExprNode <op1> @ <op2> or <op1> @( <op2> )
|
||||||
|
|
||||||
Delete, // UnaryExprNode delete <op>
|
Delete, // UnaryExprNode delete <op> // Begin of isUnaryKind()
|
||||||
Typeof, // UnaryExprNode typeof <op>
|
Typeof, // UnaryExprNode typeof <op>
|
||||||
Eval, // UnaryExprNode eval <op>
|
Eval, // UnaryExprNode eval <op>
|
||||||
preIncrement, // UnaryExprNode ++ <op>
|
preIncrement, // UnaryExprNode ++ <op>
|
||||||
@ -472,7 +479,7 @@ namespace JavaScript {
|
|||||||
plus, // UnaryExprNode + <op>
|
plus, // UnaryExprNode + <op>
|
||||||
minus, // UnaryExprNode - <op>
|
minus, // UnaryExprNode - <op>
|
||||||
complement, // UnaryExprNode ~ <op>
|
complement, // UnaryExprNode ~ <op>
|
||||||
logicalNot, // UnaryExprNode ! <op>
|
logicalNot, // UnaryExprNode ! <op> // End of isUnaryKind()
|
||||||
|
|
||||||
add, // BinaryExprNode <op1> + <op2>
|
add, // BinaryExprNode <op1> + <op2>
|
||||||
subtract, // BinaryExprNode <op1> - <op2>
|
subtract, // BinaryExprNode <op1> - <op2>
|
||||||
@ -500,7 +507,7 @@ namespace JavaScript {
|
|||||||
In, // BinaryExprNode <op1> in <op2>
|
In, // BinaryExprNode <op1> in <op2>
|
||||||
Instanceof, // BinaryExprNode <op1> instanceof <op2>
|
Instanceof, // BinaryExprNode <op1> instanceof <op2>
|
||||||
|
|
||||||
assignment, // BinaryExprNode <op1> = <op2>
|
assignment, // BinaryExprNode <op1> = <op2> // Begin of isAssigningKind()
|
||||||
addEquals, // BinaryExprNode <op1> += <op2>
|
addEquals, // BinaryExprNode <op1> += <op2>
|
||||||
subtractEquals, // BinaryExprNode <op1> -= <op2>
|
subtractEquals, // BinaryExprNode <op1> -= <op2>
|
||||||
multiplyEquals, // BinaryExprNode <op1> *= <op2>
|
multiplyEquals, // BinaryExprNode <op1> *= <op2>
|
||||||
@ -514,14 +521,17 @@ namespace JavaScript {
|
|||||||
bitwiseOrEquals, // BinaryExprNode <op1> |= <op2>
|
bitwiseOrEquals, // BinaryExprNode <op1> |= <op2>
|
||||||
logicalAndEquals, // BinaryExprNode <op1> &&= <op2>
|
logicalAndEquals, // BinaryExprNode <op1> &&= <op2>
|
||||||
logicalXorEquals, // BinaryExprNode <op1> ^^= <op2>
|
logicalXorEquals, // BinaryExprNode <op1> ^^= <op2>
|
||||||
logicalOrEquals, // BinaryExprNode <op1> ||= <op2>
|
logicalOrEquals, // BinaryExprNode <op1> ||= <op2> // End of isAssigningKind()
|
||||||
|
|
||||||
conditional, // TernaryExprNode <op1> ? <op2> : <op3>
|
conditional, // TernaryExprNode <op1> ? <op2> : <op3>
|
||||||
comma // BinaryExprNode <op1> , <op2> // Comma expressions only
|
comma, // BinaryExprNode <op1> , <op2> // Comma expressions only
|
||||||
|
|
||||||
|
kindsEnd
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Kind kind; // The node's kind
|
Kind kind; // The node's kind
|
||||||
|
static const char *const kindNames[kindsEnd];
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ExprNode(uint32 pos, Kind kind): ParseNode(pos), kind(kind) {}
|
ExprNode(uint32 pos, Kind kind): ParseNode(pos), kind(kind) {}
|
||||||
@ -529,33 +539,41 @@ namespace JavaScript {
|
|||||||
Kind getKind() const {return kind;}
|
Kind getKind() const {return kind;}
|
||||||
bool hasKind(Kind k) const {return kind == k;}
|
bool hasKind(Kind k) const {return kind == k;}
|
||||||
|
|
||||||
static bool isFieldKind(Kind kind) {return kind == identifier || kind == number || kind == string || kind == qualifiedIdentifier;}
|
static bool isFieldKind(Kind kind) {return kind == identifier || kind == number || kind == string || kind == qualify;}
|
||||||
|
static bool isAssigningKind(Kind kind) {return kind >= assignment && kind <= logicalOrEquals;}
|
||||||
|
static bool isUnaryKind(Kind kind) {return kind >= Delete && kind <= logicalNot;}
|
||||||
|
static const char *kindName(Kind kind) {ASSERT(uint(kind) < kindsEnd); return kindNames[kind];}
|
||||||
|
|
||||||
|
virtual void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Print e onto f.
|
||||||
|
inline PrettyPrinter &operator<<(PrettyPrinter &f, const ExprNode *e) {ASSERT(e); e->print(f); return f;}
|
||||||
|
|
||||||
|
|
||||||
struct IdentifierExprNode: ExprNode {
|
struct IdentifierExprNode: ExprNode {
|
||||||
const StringAtom &name; // The identifier
|
const StringAtom &name; // The identifier
|
||||||
|
|
||||||
IdentifierExprNode(uint32 pos, Kind kind, const StringAtom &name):
|
IdentifierExprNode(uint32 pos, Kind kind, const StringAtom &name):
|
||||||
ExprNode(pos, kind), name(name) {}
|
ExprNode(pos, kind), name(name) {}
|
||||||
};
|
|
||||||
|
|
||||||
struct OpIdentifierExprNode: IdentifierExprNode {
|
|
||||||
ExprNode *op; // The namespace expression or indexed expression; non-nil only
|
|
||||||
|
|
||||||
OpIdentifierExprNode(uint32 pos, Kind kind, const StringAtom &name, ExprNode *op):
|
void print(PrettyPrinter &f) const;
|
||||||
IdentifierExprNode(pos, kind, name), op(op) {ASSERT(op);}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NumberExprNode: ExprNode {
|
struct NumberExprNode: ExprNode {
|
||||||
float64 value; // The number's value
|
float64 value; // The number's value
|
||||||
|
|
||||||
NumberExprNode(uint32 pos, float64 value): ExprNode(pos, number), value(value) {}
|
NumberExprNode(uint32 pos, float64 value): ExprNode(pos, number), value(value) {}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StringExprNode: ExprNode {
|
struct StringExprNode: ExprNode {
|
||||||
String &str; // The string
|
String &str; // The string
|
||||||
|
|
||||||
StringExprNode(uint32 pos, Kind kind, String &str): ExprNode(pos, kind), str(str) {}
|
StringExprNode(uint32 pos, Kind kind, String &str): ExprNode(pos, kind), str(str) {}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RegExpExprNode: ExprNode {
|
struct RegExpExprNode: ExprNode {
|
||||||
@ -564,6 +582,8 @@ namespace JavaScript {
|
|||||||
|
|
||||||
RegExpExprNode(uint32 pos, Kind kind, const StringAtom ®Exp, String &flags):
|
RegExpExprNode(uint32 pos, Kind kind, const StringAtom ®Exp, String &flags):
|
||||||
ExprNode(pos, kind), regExp(regExp), flags(flags) {}
|
ExprNode(pos, kind), regExp(regExp), flags(flags) {}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NumUnitExprNode: StringExprNode { // str is the unit string
|
struct NumUnitExprNode: StringExprNode { // str is the unit string
|
||||||
@ -572,6 +592,8 @@ namespace JavaScript {
|
|||||||
|
|
||||||
NumUnitExprNode(uint32 pos, Kind kind, String &numStr, float64 num, String &unitStr):
|
NumUnitExprNode(uint32 pos, Kind kind, String &numStr, float64 num, String &unitStr):
|
||||||
StringExprNode(pos, kind, unitStr), numStr(numStr), num(num) {}
|
StringExprNode(pos, kind, unitStr), numStr(numStr), num(num) {}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprUnitExprNode: StringExprNode { // str is the unit string
|
struct ExprUnitExprNode: StringExprNode { // str is the unit string
|
||||||
@ -579,12 +601,16 @@ namespace JavaScript {
|
|||||||
|
|
||||||
ExprUnitExprNode(uint32 pos, Kind kind, ExprNode *op, String &unitStr):
|
ExprUnitExprNode(uint32 pos, Kind kind, ExprNode *op, String &unitStr):
|
||||||
StringExprNode(pos, kind, unitStr), op(op) {ASSERT(op);}
|
StringExprNode(pos, kind, unitStr), op(op) {ASSERT(op);}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FunctionExprNode: ExprNode {
|
struct FunctionExprNode: ExprNode {
|
||||||
FunctionDefinition function; // Function definition
|
FunctionDefinition function; // Function definition
|
||||||
|
|
||||||
FunctionExprNode(uint32 pos, Kind kind): ExprNode(pos, kind) {}
|
FunctionExprNode(uint32 pos, Kind kind): ExprNode(pos, kind) {}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprList: ArenaObject {
|
struct ExprList: ArenaObject {
|
||||||
@ -606,6 +632,8 @@ namespace JavaScript {
|
|||||||
ExprPairList *pairs; // Linked list of pairs
|
ExprPairList *pairs; // Linked list of pairs
|
||||||
|
|
||||||
PairListExprNode(uint32 pos, Kind kind, ExprPairList *pairs): ExprNode(pos, kind), pairs(pairs) {}
|
PairListExprNode(uint32 pos, Kind kind, ExprPairList *pairs): ExprNode(pos, kind), pairs(pairs) {}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InvokeExprNode: PairListExprNode {
|
struct InvokeExprNode: PairListExprNode {
|
||||||
@ -613,12 +641,16 @@ namespace JavaScript {
|
|||||||
|
|
||||||
InvokeExprNode(uint32 pos, Kind kind, ExprNode *op, ExprPairList *pairs):
|
InvokeExprNode(uint32 pos, Kind kind, ExprNode *op, ExprPairList *pairs):
|
||||||
PairListExprNode(pos, kind, pairs), op(op) {ASSERT(op);}
|
PairListExprNode(pos, kind, pairs), op(op) {ASSERT(op);}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UnaryExprNode: ExprNode {
|
struct UnaryExprNode: ExprNode {
|
||||||
ExprNode *op; // The unary operator's operand; non-nil only
|
ExprNode *op; // The unary operator's operand; non-nil only
|
||||||
|
|
||||||
UnaryExprNode(uint32 pos, Kind kind, ExprNode *op): ExprNode(pos, kind), op(op) {ASSERT(op);}
|
UnaryExprNode(uint32 pos, Kind kind, ExprNode *op): ExprNode(pos, kind), op(op) {ASSERT(op);}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BinaryExprNode: ExprNode {
|
struct BinaryExprNode: ExprNode {
|
||||||
@ -627,6 +659,8 @@ namespace JavaScript {
|
|||||||
|
|
||||||
BinaryExprNode(uint32 pos, Kind kind, ExprNode *op1, ExprNode *op2):
|
BinaryExprNode(uint32 pos, Kind kind, ExprNode *op1, ExprNode *op2):
|
||||||
ExprNode(pos, kind), op1(op1), op2(op2) {ASSERT(op1 && op2);}
|
ExprNode(pos, kind), op1(op1), op2(op2) {ASSERT(op1 && op2);}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TernaryExprNode: ExprNode {
|
struct TernaryExprNode: ExprNode {
|
||||||
@ -636,6 +670,8 @@ namespace JavaScript {
|
|||||||
|
|
||||||
TernaryExprNode(uint32 pos, Kind kind, ExprNode *op1, ExprNode *op2, ExprNode *op3):
|
TernaryExprNode(uint32 pos, Kind kind, ExprNode *op1, ExprNode *op2, ExprNode *op3):
|
||||||
ExprNode(pos, kind), op1(op1), op2(op2), op3(op3) {ASSERT(op1 && op2 && op3);}
|
ExprNode(pos, kind), op1(op1), op2(op2), op3(op3) {ASSERT(op1 && op2 && op3);}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -827,17 +863,47 @@ namespace JavaScript {
|
|||||||
|
|
||||||
ExprNode *parseIdentifierQualifiers(ExprNode *e, bool &foundQualifiers);
|
ExprNode *parseIdentifierQualifiers(ExprNode *e, bool &foundQualifiers);
|
||||||
ExprNode *parseParenthesesAndIdentifierQualifiers(const Token &tParen, bool &foundQualifiers);
|
ExprNode *parseParenthesesAndIdentifierQualifiers(const Token &tParen, bool &foundQualifiers);
|
||||||
IdentifierExprNode *parseQualifiedIdentifier(const Token &t);
|
ExprNode *parseQualifiedIdentifier(const Token &t);
|
||||||
PairListExprNode *parseArrayLiteral(const Token &initialToken);
|
PairListExprNode *parseArrayLiteral(const Token &initialToken);
|
||||||
PairListExprNode *parseObjectLiteral(const Token &initialToken);
|
PairListExprNode *parseObjectLiteral(const Token &initialToken);
|
||||||
ExprNode *parsePrimaryExpression();
|
ExprNode *parsePrimaryExpression();
|
||||||
BinaryExprNode *parseMember(ExprNode *target, const Token &tOperator, ExprNode::Kind kind, ExprNode::Kind parenKind);
|
BinaryExprNode *parseMember(ExprNode *target, const Token &tOperator, ExprNode::Kind kind, ExprNode::Kind parenKind);
|
||||||
InvokeExprNode *parseInvoke(ExprNode *target, uint32 pos, Token::Kind closingTokenKind, ExprNode::Kind invokeKind);
|
InvokeExprNode *parseInvoke(ExprNode *target, uint32 pos, Token::Kind closingTokenKind, ExprNode::Kind invokeKind);
|
||||||
public:
|
|
||||||
ExprNode *parsePostfixExpression(bool newExpression = false);
|
ExprNode *parsePostfixExpression(bool newExpression = false);
|
||||||
ExprNode *parseNonAssignmentExpression(bool noIn);
|
ExprNode *parseUnaryExpression();
|
||||||
ExprNode *parseAssignmentExpression(bool noIn);
|
|
||||||
ExprNode *parseExpression(bool noIn);
|
enum Precedence {
|
||||||
|
pNone, // End tag
|
||||||
|
pExpression, // Expression
|
||||||
|
pAssignment, // AssignmentExpression
|
||||||
|
pConditional, // ConditionalExpression
|
||||||
|
pLogicalOr, // LogicalOrExpression
|
||||||
|
pLogicalXor, // LogicalXorExpression
|
||||||
|
pLogicalAnd, // LogicalAndExpression
|
||||||
|
pBitwiseOr, // BitwiseOrExpression
|
||||||
|
pBitwiseXor, // BitwiseXorExpression
|
||||||
|
pBitwiseAnd, // BitwiseAndExpression
|
||||||
|
pEquality, // EqualityExpression
|
||||||
|
pRelational, // RelationalExpression
|
||||||
|
pShift, // ShiftExpression
|
||||||
|
pAdditive, // AdditiveExpression
|
||||||
|
pMultiplicative, // MultiplicativeExpression
|
||||||
|
pUnary, // UnaryExpression
|
||||||
|
pPostfix // PostfixExpression
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BinaryOperatorInfo {
|
||||||
|
ExprNode::Kind kind; // The kind of BinaryExprNode the operator should generate; ExprNode::none if not a binary operator
|
||||||
|
Precedence precedenceLeft; // Operators in this operator's left subexpression with precedenceLeft or higher are reduced
|
||||||
|
Precedence precedenceRight; // This operator's precedence
|
||||||
|
};
|
||||||
|
static const BinaryOperatorInfo tokenBinaryOperatorInfos[Token::kindsEnd];
|
||||||
|
struct StackedSubexpression;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ExprNode *parseExpression(bool noIn, bool noAssignment = false, bool noComma = false);
|
||||||
|
ExprNode *parseNonAssignmentExpression(bool noIn) {return parseExpression(noIn, true, true);}
|
||||||
|
ExprNode *parseAssignmentExpression(bool noIn) {return parseExpression(noIn, false, true);}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
150
js2/src/parser.h
150
js2/src/parser.h
@ -40,7 +40,7 @@ namespace JavaScript {
|
|||||||
const char16 *p; // Position in source text
|
const char16 *p; // Position in source text
|
||||||
const char16 *end; // End of source text; *end is a null character
|
const char16 *end; // End of source text; *end is a null character
|
||||||
public:
|
public:
|
||||||
String source; // Source text
|
const String source; // Source text
|
||||||
const String sourceLocation; // Description of location from which the source text came
|
const String sourceLocation; // Description of location from which the source text came
|
||||||
private:
|
private:
|
||||||
const uint32 initialLineNum; // One-based number of current line
|
const uint32 initialLineNum; // One-based number of current line
|
||||||
@ -85,10 +85,13 @@ namespace JavaScript {
|
|||||||
// Lexer
|
// Lexer
|
||||||
//
|
//
|
||||||
|
|
||||||
|
void escapeString(Formatter &f, const char16 *begin, const char16 *end, char16 quote);
|
||||||
|
void quoteString(Formatter &f, const String &s, char16 quote);
|
||||||
|
|
||||||
|
|
||||||
class Token {
|
class Token {
|
||||||
static const char *const kindNames[];
|
|
||||||
public:
|
public:
|
||||||
enum Kind { // Keep synchronized with kindNames table
|
enum Kind { // Keep synchronized with kindNames and tokenBinaryOperatorInfos tables
|
||||||
// Special
|
// Special
|
||||||
end, // End of token stream
|
end, // End of token stream
|
||||||
|
|
||||||
@ -217,42 +220,42 @@ namespace JavaScript {
|
|||||||
With, // with
|
With, // with
|
||||||
|
|
||||||
// Non-reserved words
|
// Non-reserved words
|
||||||
Box, // box
|
Attribute, // attribute
|
||||||
Constructor, // constructor
|
Constructor, // constructor
|
||||||
Field, // field
|
|
||||||
Get, // get
|
Get, // get
|
||||||
Language, // language
|
Language, // language
|
||||||
Local, // local
|
Local, // local
|
||||||
Method, // method
|
Namespace, // namespace
|
||||||
Override, // override
|
Override, // override
|
||||||
Set, // set
|
Set, // set
|
||||||
Version, // version
|
Use, // use
|
||||||
|
|
||||||
identifier, // Non-keyword identifier (may be same as a keyword if it contains an escape code)
|
identifier, // Non-keyword identifier (may be same as a keyword if it contains an escape code)
|
||||||
|
|
||||||
KindsEnd, // End of token kinds
|
kindsEnd, // End of token kinds
|
||||||
KeywordsBegin = Abstract, // Beginning of range of special identifier tokens
|
keywordsBegin = Abstract, // Beginning of range of special identifier tokens
|
||||||
KeywordsEnd = identifier, // End of range of special identifier tokens
|
keywordsEnd = identifier, // End of range of special identifier tokens
|
||||||
NonReservedBegin = Box, // Beginning of range of non-reserved words
|
nonreservedBegin = Attribute,// Beginning of range of non-reserved words
|
||||||
NonReservedEnd = identifier,// End of range of non-reserved words
|
nonreservedEnd = identifier,// End of range of non-reserved words
|
||||||
KindsWithCharsBegin = number,// Beginning of range of tokens for which the chars field (below) is valid
|
kindsWithCharsBegin = number,// Beginning of range of tokens for which the chars field (below) is valid
|
||||||
KindsWithCharsEnd = regExp+1// End of range of tokens for which the chars field (below) is valid
|
kindsWithCharsEnd = regExp+1// End of range of tokens for which the chars field (below) is valid
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CASE_TOKEN_NONRESERVED \
|
#define CASE_TOKEN_NONRESERVED \
|
||||||
Token::Box: \
|
Token::Attribute: \
|
||||||
case Token::Constructor: \
|
case Token::Constructor: \
|
||||||
case Token::Field: \
|
|
||||||
case Token::Get: \
|
case Token::Get: \
|
||||||
case Token::Language: \
|
case Token::Language: \
|
||||||
case Token::Local: \
|
case Token::Local: \
|
||||||
case Token::Method: \
|
case Token::Namespace: \
|
||||||
case Token::Override: \
|
case Token::Override: \
|
||||||
case Token::Set: \
|
case Token::Set: \
|
||||||
case Token::Version: \
|
case Token::Use: \
|
||||||
case Token::identifier
|
case Token::identifier
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static const char *const kindNames[kindsEnd];
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool valid; // True if this token has been initialized
|
bool valid; // True if this token has been initialized
|
||||||
#endif
|
#endif
|
||||||
@ -269,16 +272,16 @@ namespace JavaScript {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static void initKeywords(World &world);
|
static void initKeywords(World &world);
|
||||||
static bool isIdentifierKind(Kind kind) {ASSERT(NonReservedEnd == identifier && KindsEnd == identifier+1); return kind >= NonReservedBegin;}
|
static bool isIdentifierKind(Kind kind) {ASSERT(nonreservedEnd == identifier && kindsEnd == identifier+1); return kind >= nonreservedBegin;}
|
||||||
static bool isSpecialKind(Kind kind) {return kind <= regExp || kind == identifier;}
|
static bool isSpecialKind(Kind kind) {return kind <= regExp || kind == identifier;}
|
||||||
static const char *kindName(Kind kind) {ASSERT(uint(kind) < KindsEnd); return kindNames[kind];}
|
static const char *kindName(Kind kind) {ASSERT(uint(kind) < kindsEnd); return kindNames[kind];}
|
||||||
|
|
||||||
Kind getKind() const {ASSERT(valid); return kind;}
|
Kind getKind() const {ASSERT(valid); return kind;}
|
||||||
bool hasKind(Kind k) const {ASSERT(valid); return kind == k;}
|
bool hasKind(Kind k) const {ASSERT(valid); return kind == k;}
|
||||||
bool getLineBreak() const {ASSERT(valid); return lineBreak;}
|
bool getLineBreak() const {ASSERT(valid); return lineBreak;}
|
||||||
uint32 getPos() const {ASSERT(valid); return pos;}
|
uint32 getPos() const {ASSERT(valid); return pos;}
|
||||||
const StringAtom &getIdentifier() const {ASSERT(valid && id); return *id;}
|
const StringAtom &getIdentifier() const {ASSERT(valid && id); return *id;}
|
||||||
const String &getChars() const {ASSERT(valid && kind >= KindsWithCharsBegin && kind < KindsWithCharsEnd); return chars;}
|
const String &getChars() const {ASSERT(valid && kind >= kindsWithCharsBegin && kind < kindsWithCharsEnd); return chars;}
|
||||||
float64 getValue() const {ASSERT(valid && kind == number); return value;}
|
float64 getValue() const {ASSERT(valid && kind == number); return value;}
|
||||||
|
|
||||||
friend Formatter &operator<<(Formatter &f, Kind k) {f << kindName(k); return f;}
|
friend Formatter &operator<<(Formatter &f, Kind k) {f << kindName(k); return f;}
|
||||||
@ -434,7 +437,8 @@ namespace JavaScript {
|
|||||||
|
|
||||||
|
|
||||||
struct ExprNode: ParseNode {
|
struct ExprNode: ParseNode {
|
||||||
enum Kind { // Actual class Operands
|
enum Kind { // Actual class Operands // Keep synchronized with kindNames
|
||||||
|
none,
|
||||||
identifier, // IdentifierExprNode <name>
|
identifier, // IdentifierExprNode <name>
|
||||||
number, // NumberExprNode <value>
|
number, // NumberExprNode <value>
|
||||||
string, // StringExprNode <str>
|
string, // StringExprNode <str>
|
||||||
@ -444,12 +448,15 @@ namespace JavaScript {
|
|||||||
False, // ExprNode false
|
False, // ExprNode false
|
||||||
This, // ExprNode this
|
This, // ExprNode this
|
||||||
Super, // ExprNode super
|
Super, // ExprNode super
|
||||||
|
Public, // ExprNode public
|
||||||
|
Package, // ExprNode package
|
||||||
|
Private, // ExprNode private
|
||||||
|
|
||||||
parentheses, // UnaryExprNode (<op>)
|
parentheses, // UnaryExprNode (<op>)
|
||||||
numUnit, // NumUnitExprNode <num> "<str>" or <num><str>
|
numUnit, // NumUnitExprNode <num> "<str>" or <num><str>
|
||||||
exprUnit, // ExprUnitExprNode (<op>) "<str>"
|
exprUnit, // ExprUnitExprNode (<op>) "<str>"
|
||||||
qualifiedIdentifier, // OpIdentifierExprNode <op> :: <name>
|
qualify, // BinaryExprNode <op1> :: <op2> (right-associative: a::b::c represented as a::(b::c))
|
||||||
|
|
||||||
objectLiteral, // PairListExprNode {<field>:<value>, <field>:<value>, ..., <field>:<value>}
|
objectLiteral, // PairListExprNode {<field>:<value>, <field>:<value>, ..., <field>:<value>}
|
||||||
arrayLiteral, // PairListExprNode [<value>, <value>, ..., <value>]
|
arrayLiteral, // PairListExprNode [<value>, <value>, ..., <value>]
|
||||||
functionLiteral, // FunctionExprNode function <function>
|
functionLiteral, // FunctionExprNode function <function>
|
||||||
@ -458,11 +465,11 @@ namespace JavaScript {
|
|||||||
New, // InvokeExprNode new <op>(<field>:<value>, <field>:<value>, ..., <field>:<value>)
|
New, // InvokeExprNode new <op>(<field>:<value>, <field>:<value>, ..., <field>:<value>)
|
||||||
index, // InvokeExprNode <op>[<field>:<value>, <field>:<value>, ..., <field>:<value>]
|
index, // InvokeExprNode <op>[<field>:<value>, <field>:<value>, ..., <field>:<value>]
|
||||||
|
|
||||||
dot, // BinaryExprNode <op1> . <op2> // <op2> must be identifier or qualifiedIdentifier
|
dot, // BinaryExprNode <op1> . <op2> // <op2> must be identifier or qualify
|
||||||
dotParen, // BinaryExprNode <op1> .( <op2> )
|
dotParen, // BinaryExprNode <op1> .( <op2> )
|
||||||
at, // BinaryExprNode <op1> @ <op2> or <op1> @( <op2> )
|
at, // BinaryExprNode <op1> @ <op2> or <op1> @( <op2> )
|
||||||
|
|
||||||
Delete, // UnaryExprNode delete <op>
|
Delete, // UnaryExprNode delete <op> // Begin of isUnaryKind()
|
||||||
Typeof, // UnaryExprNode typeof <op>
|
Typeof, // UnaryExprNode typeof <op>
|
||||||
Eval, // UnaryExprNode eval <op>
|
Eval, // UnaryExprNode eval <op>
|
||||||
preIncrement, // UnaryExprNode ++ <op>
|
preIncrement, // UnaryExprNode ++ <op>
|
||||||
@ -472,7 +479,7 @@ namespace JavaScript {
|
|||||||
plus, // UnaryExprNode + <op>
|
plus, // UnaryExprNode + <op>
|
||||||
minus, // UnaryExprNode - <op>
|
minus, // UnaryExprNode - <op>
|
||||||
complement, // UnaryExprNode ~ <op>
|
complement, // UnaryExprNode ~ <op>
|
||||||
logicalNot, // UnaryExprNode ! <op>
|
logicalNot, // UnaryExprNode ! <op> // End of isUnaryKind()
|
||||||
|
|
||||||
add, // BinaryExprNode <op1> + <op2>
|
add, // BinaryExprNode <op1> + <op2>
|
||||||
subtract, // BinaryExprNode <op1> - <op2>
|
subtract, // BinaryExprNode <op1> - <op2>
|
||||||
@ -500,7 +507,7 @@ namespace JavaScript {
|
|||||||
In, // BinaryExprNode <op1> in <op2>
|
In, // BinaryExprNode <op1> in <op2>
|
||||||
Instanceof, // BinaryExprNode <op1> instanceof <op2>
|
Instanceof, // BinaryExprNode <op1> instanceof <op2>
|
||||||
|
|
||||||
assignment, // BinaryExprNode <op1> = <op2>
|
assignment, // BinaryExprNode <op1> = <op2> // Begin of isAssigningKind()
|
||||||
addEquals, // BinaryExprNode <op1> += <op2>
|
addEquals, // BinaryExprNode <op1> += <op2>
|
||||||
subtractEquals, // BinaryExprNode <op1> -= <op2>
|
subtractEquals, // BinaryExprNode <op1> -= <op2>
|
||||||
multiplyEquals, // BinaryExprNode <op1> *= <op2>
|
multiplyEquals, // BinaryExprNode <op1> *= <op2>
|
||||||
@ -514,14 +521,17 @@ namespace JavaScript {
|
|||||||
bitwiseOrEquals, // BinaryExprNode <op1> |= <op2>
|
bitwiseOrEquals, // BinaryExprNode <op1> |= <op2>
|
||||||
logicalAndEquals, // BinaryExprNode <op1> &&= <op2>
|
logicalAndEquals, // BinaryExprNode <op1> &&= <op2>
|
||||||
logicalXorEquals, // BinaryExprNode <op1> ^^= <op2>
|
logicalXorEquals, // BinaryExprNode <op1> ^^= <op2>
|
||||||
logicalOrEquals, // BinaryExprNode <op1> ||= <op2>
|
logicalOrEquals, // BinaryExprNode <op1> ||= <op2> // End of isAssigningKind()
|
||||||
|
|
||||||
conditional, // TernaryExprNode <op1> ? <op2> : <op3>
|
conditional, // TernaryExprNode <op1> ? <op2> : <op3>
|
||||||
comma // BinaryExprNode <op1> , <op2> // Comma expressions only
|
comma, // BinaryExprNode <op1> , <op2> // Comma expressions only
|
||||||
|
|
||||||
|
kindsEnd
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Kind kind; // The node's kind
|
Kind kind; // The node's kind
|
||||||
|
static const char *const kindNames[kindsEnd];
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ExprNode(uint32 pos, Kind kind): ParseNode(pos), kind(kind) {}
|
ExprNode(uint32 pos, Kind kind): ParseNode(pos), kind(kind) {}
|
||||||
@ -529,33 +539,41 @@ namespace JavaScript {
|
|||||||
Kind getKind() const {return kind;}
|
Kind getKind() const {return kind;}
|
||||||
bool hasKind(Kind k) const {return kind == k;}
|
bool hasKind(Kind k) const {return kind == k;}
|
||||||
|
|
||||||
static bool isFieldKind(Kind kind) {return kind == identifier || kind == number || kind == string || kind == qualifiedIdentifier;}
|
static bool isFieldKind(Kind kind) {return kind == identifier || kind == number || kind == string || kind == qualify;}
|
||||||
|
static bool isAssigningKind(Kind kind) {return kind >= assignment && kind <= logicalOrEquals;}
|
||||||
|
static bool isUnaryKind(Kind kind) {return kind >= Delete && kind <= logicalNot;}
|
||||||
|
static const char *kindName(Kind kind) {ASSERT(uint(kind) < kindsEnd); return kindNames[kind];}
|
||||||
|
|
||||||
|
virtual void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Print e onto f.
|
||||||
|
inline PrettyPrinter &operator<<(PrettyPrinter &f, const ExprNode *e) {ASSERT(e); e->print(f); return f;}
|
||||||
|
|
||||||
|
|
||||||
struct IdentifierExprNode: ExprNode {
|
struct IdentifierExprNode: ExprNode {
|
||||||
const StringAtom &name; // The identifier
|
const StringAtom &name; // The identifier
|
||||||
|
|
||||||
IdentifierExprNode(uint32 pos, Kind kind, const StringAtom &name):
|
IdentifierExprNode(uint32 pos, Kind kind, const StringAtom &name):
|
||||||
ExprNode(pos, kind), name(name) {}
|
ExprNode(pos, kind), name(name) {}
|
||||||
};
|
|
||||||
|
|
||||||
struct OpIdentifierExprNode: IdentifierExprNode {
|
|
||||||
ExprNode *op; // The namespace expression or indexed expression; non-nil only
|
|
||||||
|
|
||||||
OpIdentifierExprNode(uint32 pos, Kind kind, const StringAtom &name, ExprNode *op):
|
void print(PrettyPrinter &f) const;
|
||||||
IdentifierExprNode(pos, kind, name), op(op) {ASSERT(op);}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NumberExprNode: ExprNode {
|
struct NumberExprNode: ExprNode {
|
||||||
float64 value; // The number's value
|
float64 value; // The number's value
|
||||||
|
|
||||||
NumberExprNode(uint32 pos, float64 value): ExprNode(pos, number), value(value) {}
|
NumberExprNode(uint32 pos, float64 value): ExprNode(pos, number), value(value) {}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StringExprNode: ExprNode {
|
struct StringExprNode: ExprNode {
|
||||||
String &str; // The string
|
String &str; // The string
|
||||||
|
|
||||||
StringExprNode(uint32 pos, Kind kind, String &str): ExprNode(pos, kind), str(str) {}
|
StringExprNode(uint32 pos, Kind kind, String &str): ExprNode(pos, kind), str(str) {}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RegExpExprNode: ExprNode {
|
struct RegExpExprNode: ExprNode {
|
||||||
@ -564,6 +582,8 @@ namespace JavaScript {
|
|||||||
|
|
||||||
RegExpExprNode(uint32 pos, Kind kind, const StringAtom ®Exp, String &flags):
|
RegExpExprNode(uint32 pos, Kind kind, const StringAtom ®Exp, String &flags):
|
||||||
ExprNode(pos, kind), regExp(regExp), flags(flags) {}
|
ExprNode(pos, kind), regExp(regExp), flags(flags) {}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NumUnitExprNode: StringExprNode { // str is the unit string
|
struct NumUnitExprNode: StringExprNode { // str is the unit string
|
||||||
@ -572,6 +592,8 @@ namespace JavaScript {
|
|||||||
|
|
||||||
NumUnitExprNode(uint32 pos, Kind kind, String &numStr, float64 num, String &unitStr):
|
NumUnitExprNode(uint32 pos, Kind kind, String &numStr, float64 num, String &unitStr):
|
||||||
StringExprNode(pos, kind, unitStr), numStr(numStr), num(num) {}
|
StringExprNode(pos, kind, unitStr), numStr(numStr), num(num) {}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprUnitExprNode: StringExprNode { // str is the unit string
|
struct ExprUnitExprNode: StringExprNode { // str is the unit string
|
||||||
@ -579,12 +601,16 @@ namespace JavaScript {
|
|||||||
|
|
||||||
ExprUnitExprNode(uint32 pos, Kind kind, ExprNode *op, String &unitStr):
|
ExprUnitExprNode(uint32 pos, Kind kind, ExprNode *op, String &unitStr):
|
||||||
StringExprNode(pos, kind, unitStr), op(op) {ASSERT(op);}
|
StringExprNode(pos, kind, unitStr), op(op) {ASSERT(op);}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FunctionExprNode: ExprNode {
|
struct FunctionExprNode: ExprNode {
|
||||||
FunctionDefinition function; // Function definition
|
FunctionDefinition function; // Function definition
|
||||||
|
|
||||||
FunctionExprNode(uint32 pos, Kind kind): ExprNode(pos, kind) {}
|
FunctionExprNode(uint32 pos, Kind kind): ExprNode(pos, kind) {}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprList: ArenaObject {
|
struct ExprList: ArenaObject {
|
||||||
@ -606,6 +632,8 @@ namespace JavaScript {
|
|||||||
ExprPairList *pairs; // Linked list of pairs
|
ExprPairList *pairs; // Linked list of pairs
|
||||||
|
|
||||||
PairListExprNode(uint32 pos, Kind kind, ExprPairList *pairs): ExprNode(pos, kind), pairs(pairs) {}
|
PairListExprNode(uint32 pos, Kind kind, ExprPairList *pairs): ExprNode(pos, kind), pairs(pairs) {}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InvokeExprNode: PairListExprNode {
|
struct InvokeExprNode: PairListExprNode {
|
||||||
@ -613,12 +641,16 @@ namespace JavaScript {
|
|||||||
|
|
||||||
InvokeExprNode(uint32 pos, Kind kind, ExprNode *op, ExprPairList *pairs):
|
InvokeExprNode(uint32 pos, Kind kind, ExprNode *op, ExprPairList *pairs):
|
||||||
PairListExprNode(pos, kind, pairs), op(op) {ASSERT(op);}
|
PairListExprNode(pos, kind, pairs), op(op) {ASSERT(op);}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UnaryExprNode: ExprNode {
|
struct UnaryExprNode: ExprNode {
|
||||||
ExprNode *op; // The unary operator's operand; non-nil only
|
ExprNode *op; // The unary operator's operand; non-nil only
|
||||||
|
|
||||||
UnaryExprNode(uint32 pos, Kind kind, ExprNode *op): ExprNode(pos, kind), op(op) {ASSERT(op);}
|
UnaryExprNode(uint32 pos, Kind kind, ExprNode *op): ExprNode(pos, kind), op(op) {ASSERT(op);}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BinaryExprNode: ExprNode {
|
struct BinaryExprNode: ExprNode {
|
||||||
@ -627,6 +659,8 @@ namespace JavaScript {
|
|||||||
|
|
||||||
BinaryExprNode(uint32 pos, Kind kind, ExprNode *op1, ExprNode *op2):
|
BinaryExprNode(uint32 pos, Kind kind, ExprNode *op1, ExprNode *op2):
|
||||||
ExprNode(pos, kind), op1(op1), op2(op2) {ASSERT(op1 && op2);}
|
ExprNode(pos, kind), op1(op1), op2(op2) {ASSERT(op1 && op2);}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TernaryExprNode: ExprNode {
|
struct TernaryExprNode: ExprNode {
|
||||||
@ -636,6 +670,8 @@ namespace JavaScript {
|
|||||||
|
|
||||||
TernaryExprNode(uint32 pos, Kind kind, ExprNode *op1, ExprNode *op2, ExprNode *op3):
|
TernaryExprNode(uint32 pos, Kind kind, ExprNode *op1, ExprNode *op2, ExprNode *op3):
|
||||||
ExprNode(pos, kind), op1(op1), op2(op2), op3(op3) {ASSERT(op1 && op2 && op3);}
|
ExprNode(pos, kind), op1(op1), op2(op2), op3(op3) {ASSERT(op1 && op2 && op3);}
|
||||||
|
|
||||||
|
void print(PrettyPrinter &f) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -827,17 +863,47 @@ namespace JavaScript {
|
|||||||
|
|
||||||
ExprNode *parseIdentifierQualifiers(ExprNode *e, bool &foundQualifiers);
|
ExprNode *parseIdentifierQualifiers(ExprNode *e, bool &foundQualifiers);
|
||||||
ExprNode *parseParenthesesAndIdentifierQualifiers(const Token &tParen, bool &foundQualifiers);
|
ExprNode *parseParenthesesAndIdentifierQualifiers(const Token &tParen, bool &foundQualifiers);
|
||||||
IdentifierExprNode *parseQualifiedIdentifier(const Token &t);
|
ExprNode *parseQualifiedIdentifier(const Token &t);
|
||||||
PairListExprNode *parseArrayLiteral(const Token &initialToken);
|
PairListExprNode *parseArrayLiteral(const Token &initialToken);
|
||||||
PairListExprNode *parseObjectLiteral(const Token &initialToken);
|
PairListExprNode *parseObjectLiteral(const Token &initialToken);
|
||||||
ExprNode *parsePrimaryExpression();
|
ExprNode *parsePrimaryExpression();
|
||||||
BinaryExprNode *parseMember(ExprNode *target, const Token &tOperator, ExprNode::Kind kind, ExprNode::Kind parenKind);
|
BinaryExprNode *parseMember(ExprNode *target, const Token &tOperator, ExprNode::Kind kind, ExprNode::Kind parenKind);
|
||||||
InvokeExprNode *parseInvoke(ExprNode *target, uint32 pos, Token::Kind closingTokenKind, ExprNode::Kind invokeKind);
|
InvokeExprNode *parseInvoke(ExprNode *target, uint32 pos, Token::Kind closingTokenKind, ExprNode::Kind invokeKind);
|
||||||
public:
|
|
||||||
ExprNode *parsePostfixExpression(bool newExpression = false);
|
ExprNode *parsePostfixExpression(bool newExpression = false);
|
||||||
ExprNode *parseNonAssignmentExpression(bool noIn);
|
ExprNode *parseUnaryExpression();
|
||||||
ExprNode *parseAssignmentExpression(bool noIn);
|
|
||||||
ExprNode *parseExpression(bool noIn);
|
enum Precedence {
|
||||||
|
pNone, // End tag
|
||||||
|
pExpression, // Expression
|
||||||
|
pAssignment, // AssignmentExpression
|
||||||
|
pConditional, // ConditionalExpression
|
||||||
|
pLogicalOr, // LogicalOrExpression
|
||||||
|
pLogicalXor, // LogicalXorExpression
|
||||||
|
pLogicalAnd, // LogicalAndExpression
|
||||||
|
pBitwiseOr, // BitwiseOrExpression
|
||||||
|
pBitwiseXor, // BitwiseXorExpression
|
||||||
|
pBitwiseAnd, // BitwiseAndExpression
|
||||||
|
pEquality, // EqualityExpression
|
||||||
|
pRelational, // RelationalExpression
|
||||||
|
pShift, // ShiftExpression
|
||||||
|
pAdditive, // AdditiveExpression
|
||||||
|
pMultiplicative, // MultiplicativeExpression
|
||||||
|
pUnary, // UnaryExpression
|
||||||
|
pPostfix // PostfixExpression
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BinaryOperatorInfo {
|
||||||
|
ExprNode::Kind kind; // The kind of BinaryExprNode the operator should generate; ExprNode::none if not a binary operator
|
||||||
|
Precedence precedenceLeft; // Operators in this operator's left subexpression with precedenceLeft or higher are reduced
|
||||||
|
Precedence precedenceRight; // This operator's precedence
|
||||||
|
};
|
||||||
|
static const BinaryOperatorInfo tokenBinaryOperatorInfos[Token::kindsEnd];
|
||||||
|
struct StackedSubexpression;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ExprNode *parseExpression(bool noIn, bool noAssignment = false, bool noComma = false);
|
||||||
|
ExprNode *parseNonAssignmentExpression(bool noIn) {return parseExpression(noIn, true, true);}
|
||||||
|
ExprNode *parseAssignmentExpression(bool noIn) {return parseExpression(noIn, false, true);}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user