From 1eb40cb8ee8d8107a2fcaeee135602fb991db8f7 Mon Sep 17 00:00:00 2001 From: "waldemar%netscape.com" Date: Sat, 7 Jul 2001 01:37:44 +0000 Subject: [PATCH] Changed string offsets to size_t git-svn-id: svn://10.0.0.236/branches/JS2_DIKDIK_BRANCH@98849 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js2/src/exception.cpp | 82 +- mozilla/js2/src/exception.h | 51 +- mozilla/js2/src/lexer.cpp | 4 +- mozilla/js2/src/lexer.h | 4 +- mozilla/js2/src/nodefactory.h | 4 +- mozilla/js2/src/parser.cpp | 3679 ++++++++++++++++----------------- mozilla/js2/src/parser.h | 1219 ++++++----- mozilla/js2/src/reader.cpp | 13 +- mozilla/js2/src/reader.h | 12 +- mozilla/js2/src/token.h | 4 +- 10 files changed, 2528 insertions(+), 2544 deletions(-) diff --git a/mozilla/js2/src/exception.cpp b/mozilla/js2/src/exception.cpp index cf870baf0bc..48e5b53b518 100644 --- a/mozilla/js2/src/exception.cpp +++ b/mozilla/js2/src/exception.cpp @@ -32,60 +32,54 @@ */ #include - #include "exception.h" -namespace JavaScript -{ - +namespace JS = JavaScript; + + // // Exceptions // +static const char *const kindStrings[] = { + "Syntax error", // syntaxError + "Stack overflow", // stackOverflow + "Internal error", // diabetes + "Runtime error", // runtimeError + "Reference error", // referenceError + "Range error", // burnt the beans + "Type error", // Yype error + "Uncaught exception error", // uncaught exception error + "Semantic error", // semantic error +}; - static const char *const kindStrings[] = { - "Syntax error", // syntaxError - "Stack overflow", // stackOverflow - "Internal error", // diabetes - "Runtime error", // runtimeError - "Reference error", // referenceError - "Range error", // burnt the beans - "Type error", // Yype error - "Uncaught exception error", // uncaught exception error - "Semantic error", // semantic error - }; - // Return a null-terminated string describing the exception's kind. - const char * - Exception::kindString() const - { - return kindStrings[kind]; - } +const char *JS::Exception::kindString() const +{ + return kindStrings[kind]; +} // Return the full error message. - String - Exception::fullMessage() const - { - String m(widenCString("In ")); - m += sourceFile; - if (lineNum) { - char b[32]; - sprintf(b, ", line %d:\n", lineNum); - m += b; - m += sourceLine; - m += '\n'; - String sourceLine2(sourceLine); - insertChars(sourceLine2, charNum, "[ERROR]"); - m += sourceLine2; - m += '\n'; - } else - m += ":\n"; - m += kindString(); - m += ": "; - m += message; +JS::String JS::Exception::fullMessage() const +{ + String m(widenCString("In ")); + m += sourceFile; + if (lineNum) { + char b[32]; + sprintf(b, ", line %d:\n", lineNum); + m += b; + m += sourceLine; m += '\n'; - return m; - } - + String sourceLine2(sourceLine); + insertChars(sourceLine2, charNum, "[ERROR]"); + m += sourceLine2; + m += '\n'; + } else + m += ":\n"; + m += kindString(); + m += ": "; + m += message; + m += '\n'; + return m; } diff --git a/mozilla/js2/src/exception.h b/mozilla/js2/src/exception.h index 3fc699f7af4..e32c4ddaf1d 100644 --- a/mozilla/js2/src/exception.h +++ b/mozilla/js2/src/exception.h @@ -38,13 +38,13 @@ namespace JavaScript { - + // // Exceptions // -// A JavaScript exception (other than out-of-memory, for which we use the -// standard C++ exception bad_alloc). + // A JavaScript exception (other than out-of-memory, for which we use the + // standard C++ exception bad_alloc). struct Exception { enum Kind { syntaxError, @@ -58,45 +58,38 @@ namespace JavaScript semanticError }; - Kind kind; // The exception's kind - String message; // The detailed message - String sourceFile; // A description of the source code that caused the - // error - uint32 lineNum; // Number of line that caused the error - uint32 charNum; // Character offset within the line that caused the - // error - uint32 pos; // Offset within the input of the error - String sourceLine; // The text of the source line + Kind kind; // The exception's kind + String message; // The detailed message + String sourceFile; // A description of the source code that caused the error + uint32 lineNum; // Number of line that caused the error + size_t charNum; // Character offset within the line that caused the error + size_t pos; // Offset within the input of the error + String sourceLine; // The text of the source line - Exception (Kind kind, const char *message) : + Exception (Kind kind, const char *message): kind(kind), message(widenCString(message)), lineNum(0), charNum(0) {} - Exception (Kind kind, const String &message) : + Exception (Kind kind, const String &message): kind(kind), message(message), lineNum(0), charNum(0) {} - Exception(Kind kind, const String &message, const String &sourceFile, - uint32 lineNum, uint32 charNum, uint32 pos, - const String &sourceLine) : - kind(kind), message(message), sourceFile(sourceFile), - lineNum(lineNum), charNum(charNum), pos(pos), sourceLine(sourceLine) - {} + Exception(Kind kind, const String &message, const String &sourceFile, uint32 lineNum, size_t charNum, + size_t pos, const String &sourceLine): + kind(kind), message(message), sourceFile(sourceFile), lineNum(lineNum), charNum(charNum), pos(pos), + sourceLine(sourceLine) {} - Exception(Kind kind, const String &message, const String &sourceFile, - uint32 lineNum, uint32 charNum, uint32 pos, - const char16 *sourceLineBegin, const char16 *sourceLineEnd) : - kind(kind), message(message), sourceFile(sourceFile), - lineNum(lineNum), charNum(charNum), pos(pos), - sourceLine(sourceLineBegin, sourceLineEnd) {} + Exception(Kind kind, const String &message, const String &sourceFile, uint32 lineNum, size_t charNum, + size_t pos, const char16 *sourceLineBegin, const char16 *sourceLineEnd): + kind(kind), message(message), sourceFile(sourceFile), lineNum(lineNum), charNum(charNum), pos(pos), + sourceLine(sourceLineBegin, sourceLineEnd) {} bool hasKind(Kind k) const {return kind == k;} const char *kindString() const; String fullMessage() const; }; - -// Throw a stackOverflow exception if the execution stack has gotten too large. + + // Throw a stackOverflow exception if the execution stack has gotten too large. inline void checkStackSize() {} - } #endif /* exception_h___ */ diff --git a/mozilla/js2/src/lexer.cpp b/mozilla/js2/src/lexer.cpp index 0e2f19cd961..72bd1b3504b 100644 --- a/mozilla/js2/src/lexer.cpp +++ b/mozilla/js2/src/lexer.cpp @@ -333,7 +333,7 @@ bool JS::Lexer::lexNumeral() reader.recordChar('0'); ch = getChar(); if ((ch&~0x20) == 'X') { - uint32 pos = reader.getPos(); + size_t pos = reader.getPos(); char16 ch2 = getChar(); if (isASCIIHexDigit(ch2, digit)) { reader.recordChar(ch); @@ -354,7 +354,7 @@ bool JS::Lexer::lexNumeral() ch = getChar(); } if ((ch&~0x20) == 'E') { - uint32 pos = reader.getPos(); + size_t pos = reader.getPos(); char16 ch2 = getChar(); char16 sign = 0; if (ch2 == '+' || ch2 == '-') { diff --git a/mozilla/js2/src/lexer.h b/mozilla/js2/src/lexer.h index 171da41eb94..0acf8125038 100644 --- a/mozilla/js2/src/lexer.h +++ b/mozilla/js2/src/lexer.h @@ -71,7 +71,7 @@ namespace JavaScript const Token &peek(bool preferRegExp); void redesignate(bool preferRegExp); void unget(); - uint32 getPos() const; + size_t getPos() const; private: void syntaxError(const char *message, uint backUp = 1); @@ -95,7 +95,7 @@ namespace JavaScript #endif // Return the position of the first character of the next token, which must have been peeked. - inline uint32 Lexer::getPos() const + inline size_t Lexer::getPos() const { ASSERT(nTokensFwd); return nextToken->getPos(); diff --git a/mozilla/js2/src/nodefactory.h b/mozilla/js2/src/nodefactory.h index 93efd0a48d7..c9fdac7194c 100644 --- a/mozilla/js2/src/nodefactory.h +++ b/mozilla/js2/src/nodefactory.h @@ -97,8 +97,8 @@ namespace JavaScript { } #endif static StringExprNode * - LiteralString(uint32 pos, ExprNode::Kind kind, String &str) { - return new(getArena()) StringExprNode(pos,kind,str); + LiteralString(size_t pos, ExprNode::Kind kind, String &str) { + return new(getArena()) StringExprNode(pos, kind, str); } #if 0 static LiteralTypeNode diff --git a/mozilla/js2/src/parser.cpp b/mozilla/js2/src/parser.cpp index e0908e900ed..e89b1f79c56 100644 --- a/mozilla/js2/src/parser.cpp +++ b/mozilla/js2/src/parser.cpp @@ -6,14 +6,14 @@ * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS -* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the JavaScript 2 Prototype. * * The Initial Developer of the Original Code is Netscape -* Communications Corporation. Portions created by Netscape are +* Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * @@ -49,9 +49,9 @@ JS::NodeFactory *JS::NodeFactory::state; // identifiers, keywords, and regular expressions in the designated world, // and allocating the parse tree in the designated arena. JS::Parser::Parser(World &world, Arena &arena, const String &source, const String &sourceLocation, uint32 initialLineNum): - lexer(world, source, sourceLocation, initialLineNum), arena(arena), lineBreaksSignificant(true) + lexer(world, source, sourceLocation, initialLineNum), arena(arena), lineBreaksSignificant(true) { - NodeFactory::Init(arena); + NodeFactory::Init(arena); } @@ -61,16 +61,16 @@ JS::Parser::Parser(World &world, Arena &arena, const String &source, const Strin // error is at the last token read by the Lexer, and so forth. void JS::Parser::syntaxError(const char *message, uint backUp) { - syntaxError(widenCString(message), backUp); + syntaxError(widenCString(message), backUp); } // Same as above, but the error message is already a String. void JS::Parser::syntaxError(const String &message, uint backUp) { - while (backUp--) - lexer.unget(); - getReader().error(Exception::syntaxError, message, lexer.getPos()); + while (backUp--) + lexer.unget(); + getReader().error(Exception::syntaxError, message, lexer.getPos()); } @@ -79,27 +79,27 @@ void JS::Parser::syntaxError(const String &message, uint backUp) // throw a syntax error. const JS::Token &JS::Parser::require(bool preferRegExp, Token::Kind kind) { - const Token &t = lexer.get(preferRegExp); - if (!t.hasKind(kind)) { - String message; - bool special = Token::isSpecialKind(kind); + const Token &t = lexer.get(preferRegExp); + if (!t.hasKind(kind)) { + String message; + bool special = Token::isSpecialKind(kind); - if (special) - message += '\''; - message += Token::kindName(kind); - if (special) - message += '\''; - message += " expected"; - syntaxError(message); - } - return t; + if (special) + message += '\''; + message += Token::kindName(kind); + if (special) + message += '\''; + message += " expected"; + syntaxError(message); + } + return t; } // Copy the Token's chars into the current arena and return the resulting copy. inline JS::String &JS::Parser::copyTokenChars(const Token &t) { - return newArenaString(arena, t.getChars()); + return newArenaString(arena, t.getChars()); } @@ -107,20 +107,20 @@ inline JS::String &JS::Parser::copyTokenChars(const Token &t) // Otherwise, return null. JS::ExprNode *JS::Parser::makeIdentifierExpression(const Token &t) const { - if (t.hasIdentifierKind()) - return new(arena) IdentifierExprNode(t); - return 0; + if (t.hasIdentifierKind()) + return new(arena) IdentifierExprNode(t); + return 0; } // Parse and return an Identifier. JS::ExprNode *JS::Parser::parseIdentifier() { - const Token &t = lexer.get(true); - ExprNode *e = makeIdentifierExpression(t); - if (!e) - syntaxError("Identifier expected"); - return e; + const Token &t = lexer.get(true); + ExprNode *e = makeIdentifierExpression(t); + if (!e) + syntaxError("Identifier expected"); + return e; } @@ -132,15 +132,15 @@ JS::ExprNode *JS::Parser::parseIdentifier() // peeked with the given preferRegExp setting. JS::ExprNode *JS::Parser::parseIdentifierQualifiers(ExprNode *e, bool &foundQualifiers, bool preferRegExp) { - const Token *tDoubleColon = lexer.eat(preferRegExp, Token::doubleColon); - if (!tDoubleColon) { - foundQualifiers = false; - return e; - } + const Token *tDoubleColon = lexer.eat(preferRegExp, Token::doubleColon); + if (!tDoubleColon) { + foundQualifiers = false; + return e; + } - foundQualifiers = true; - uint32 pos = tDoubleColon->getPos(); - return new(arena) BinaryExprNode(pos, ExprNode::qualify, e, parseIdentifier()); + foundQualifiers = true; + size_t pos = tDoubleColon->getPos(); + return new(arena) BinaryExprNode(pos, ExprNode::qualify, e, parseIdentifier()); } @@ -152,43 +152,43 @@ JS::ExprNode *JS::Parser::parseIdentifierQualifiers(ExprNode *e, bool &foundQual // After parseParenthesesAndIdentifierQualifiers finishes, the next token might have been // peeked with the given preferRegExp setting. JS::ExprNode *JS::Parser::parseParenthesesAndIdentifierQualifiers(const Token &tParen, bool noComma, bool &foundQualifiers, - bool preferRegExp) + bool preferRegExp) { - uint32 pos = tParen.getPos(); - ExprNode *inner = parseGeneralExpression(false, false, false, noComma); - ExprNode *e = new(arena) UnaryExprNode(pos, ExprNode::parentheses, inner); - require(false, Token::closeParenthesis); - if (inner->hasKind(ExprNode::comma)) { - foundQualifiers = false; - return e; - } - return parseIdentifierQualifiers(e, foundQualifiers, preferRegExp); + size_t pos = tParen.getPos(); + ExprNode *inner = parseGeneralExpression(false, false, false, noComma); + ExprNode *e = new(arena) UnaryExprNode(pos, ExprNode::parentheses, inner); + require(false, Token::closeParenthesis); + if (inner->hasKind(ExprNode::comma)) { + foundQualifiers = false; + return e; + } + return parseIdentifierQualifiers(e, foundQualifiers, preferRegExp); } -// Parse and return a qualifiedIdentifier. The first token has already been parsed and is in t. +// Parse and return a qualifiedIdentifier. The first token has already been parsed and is in t. // If the second token was peeked, it should be have been done with the given preferRegExp setting. // After parseQualifiedIdentifier finishes, the next token might have been peeked with the given // preferRegExp setting. JS::ExprNode *JS::Parser::parseQualifiedIdentifier(const Token &t, bool preferRegExp) { - bool foundQualifiers; - ExprNode *e = makeIdentifierExpression(t); - if (e) - return parseIdentifierQualifiers(e, foundQualifiers, preferRegExp); - if (t.hasKind(Token::openParenthesis)) { - e = parseParenthesesAndIdentifierQualifiers(t, true, foundQualifiers, preferRegExp); - goto checkQualifiers; - } - if (t.hasKind(Token::Public) || t.hasKind(Token::Private)) { - e = parseIdentifierQualifiers(new(arena) IdentifierExprNode(t), foundQualifiers, preferRegExp); - checkQualifiers: - if (!foundQualifiers) - syntaxError("'::' expected", 0); - return e; - } - syntaxError("Qualified identifier expected"); - return 0; // Unreachable code here just to shut up compiler warnings + bool foundQualifiers; + ExprNode *e = makeIdentifierExpression(t); + if (e) + return parseIdentifierQualifiers(e, foundQualifiers, preferRegExp); + if (t.hasKind(Token::openParenthesis)) { + e = parseParenthesesAndIdentifierQualifiers(t, true, foundQualifiers, preferRegExp); + goto checkQualifiers; + } + if (t.hasKind(Token::Public) || t.hasKind(Token::Private)) { + e = parseIdentifierQualifiers(new(arena) IdentifierExprNode(t), foundQualifiers, preferRegExp); + checkQualifiers: + if (!foundQualifiers) + syntaxError("'::' expected", 0); + return e; + } + syntaxError("Qualified identifier expected"); + return 0; // Unreachable code here just to shut up compiler warnings } @@ -196,25 +196,25 @@ JS::ExprNode *JS::Parser::parseQualifiedIdentifier(const Token &t, bool preferRe // read into initialToken. JS::PairListExprNode *JS::Parser::parseArrayLiteral(const Token &initialToken) { - uint32 initialPos = initialToken.getPos(); - NodeQueue elements; + size_t initialPos = initialToken.getPos(); + NodeQueue elements; - while (true) { - ExprNode *element = 0; - const Token &t = lexer.peek(true); - if (t.hasKind(Token::comma) || t.hasKind(Token::closeBracket)) - lexer.redesignate(false); // Safe: neither ',' nor '}' starts with a slash. - else - element = parseAssignmentExpression(false); - elements += new(arena) ExprPairList(0, element); + while (true) { + ExprNode *element = 0; + const Token &t = lexer.peek(true); + if (t.hasKind(Token::comma) || t.hasKind(Token::closeBracket)) + lexer.redesignate(false); // Safe: neither ',' nor '}' starts with a slash. + else + element = parseAssignmentExpression(false); + elements += new(arena) ExprPairList(0, element); - const Token &tSeparator = lexer.get(false); - if (tSeparator.hasKind(Token::closeBracket)) - break; - if (!tSeparator.hasKind(Token::comma)) - syntaxError("',' expected"); - } - return new(arena) PairListExprNode(initialPos, ExprNode::arrayLiteral, elements.first); + const Token &tSeparator = lexer.get(false); + if (tSeparator.hasKind(Token::closeBracket)) + break; + if (!tSeparator.hasKind(Token::comma)) + syntaxError("',' expected"); + } + return new(arena) PairListExprNode(initialPos, ExprNode::arrayLiteral, elements.first); } @@ -222,34 +222,34 @@ JS::PairListExprNode *JS::Parser::parseArrayLiteral(const Token &initialToken) // read into initialToken. JS::PairListExprNode *JS::Parser::parseObjectLiteral(const Token &initialToken) { - uint32 initialPos = initialToken.getPos(); - NodeQueue elements; + size_t initialPos = initialToken.getPos(); + NodeQueue elements; - if (!lexer.eat(true, Token::closeBrace)) - while (true) { - const Token &t = lexer.get(true); - ExprNode *field = makeIdentifierExpression(t); - if (!field) { - if (t.hasKind(Token::string)) - field = NodeFactory::LiteralString(t.getPos(), ExprNode::string, copyTokenChars(t)); - else if (t.hasKind(Token::number)) - field = new(arena) NumberExprNode(t); - else if (t.hasKind(Token::openParenthesis)) { - field = parseAssignmentExpression(false); - require(false, Token::closeParenthesis); - } else - syntaxError("Field name expected"); - } - require(false, Token::colon); - elements += new(arena) ExprPairList(field, parseAssignmentExpression(false)); + if (!lexer.eat(true, Token::closeBrace)) + while (true) { + const Token &t = lexer.get(true); + ExprNode *field = makeIdentifierExpression(t); + if (!field) { + if (t.hasKind(Token::string)) + field = NodeFactory::LiteralString(t.getPos(), ExprNode::string, copyTokenChars(t)); + else if (t.hasKind(Token::number)) + field = new(arena) NumberExprNode(t); + else if (t.hasKind(Token::openParenthesis)) { + field = parseAssignmentExpression(false); + require(false, Token::closeParenthesis); + } else + syntaxError("Field name expected"); + } + require(false, Token::colon); + elements += new(arena) ExprPairList(field, parseAssignmentExpression(false)); - const Token &tSeparator = lexer.get(false); - if (tSeparator.hasKind(Token::closeBrace)) - break; - if (!tSeparator.hasKind(Token::comma)) - syntaxError("',' expected"); - } - return new(arena) PairListExprNode(initialPos, ExprNode::objectLiteral, elements.first); + const Token &tSeparator = lexer.get(false); + if (tSeparator.hasKind(Token::closeBrace)) + break; + if (!tSeparator.hasKind(Token::comma)) + syntaxError("',' expected"); + } + return new(arena) PairListExprNode(initialPos, ExprNode::objectLiteral, elements.first); } @@ -259,13 +259,13 @@ JS::PairListExprNode *JS::Parser::parseObjectLiteral(const Token &initialToken) // with preferRegExp set to false. JS::ExprNode *JS::Parser::parseUnitSuffixes(ExprNode *e) { - while (true) { - const Token &t = lexer.peek(false); - if (lineBreakBefore(t) || !t.hasKind(Token::string)) - return e; - lexer.get(false); - e = new(arena) ExprUnitExprNode(t.getPos(), ExprNode::exprUnit, e, copyTokenChars(t)); - } + while (true) { + const Token &t = lexer.peek(false); + if (lineBreakBefore(t) || !t.hasKind(Token::string)) + return e; + lexer.get(false); + e = new(arena) ExprUnitExprNode(t.getPos(), ExprNode::exprUnit, e, copyTokenChars(t)); + } } @@ -275,25 +275,25 @@ JS::ExprNode *JS::Parser::parseUnitSuffixes(ExprNode *e) // the super token. // After parseSuper finishes, the next token might have been peeked with preferRegExp // set to false. -JS::ExprNode *JS::Parser::parseSuper(uint32 pos, SuperState superState) +JS::ExprNode *JS::Parser::parseSuper(size_t pos, SuperState superState) { - ASSERT(superState != ssNone); - ExprNode *e = 0; + ASSERT(superState != ssNone); + ExprNode *e = 0; - if (lexer.eat(false, Token::openParenthesis)) { - if (superState == ssExpr) { - e = parseAssignmentExpression(false); - require(false, Token::closeParenthesis); - } else { - InvokeExprNode *se = parseInvoke(0, pos, Token::closeParenthesis, ExprNode::superStmt); - // Simplify a one-anonymous-argument superStmt into a superExpr. - ExprPairList *pairs = se->pairs; - if (!pairs || pairs->next || pairs->field) - return se; - e = pairs->value; - } - } - return new(arena) SuperExprNode(pos, e); + if (lexer.eat(false, Token::openParenthesis)) { + if (superState == ssExpr) { + e = parseAssignmentExpression(false); + require(false, Token::closeParenthesis); + } else { + InvokeExprNode *se = parseInvoke(0, pos, Token::closeParenthesis, ExprNode::superStmt); + // Simplify a one-anonymous-argument superStmt into a superExpr. + ExprPairList *pairs = se->pairs; + if (!pairs || pairs->next || pairs->field) + return se; + e = pairs->value; + } + } + return new(arena) SuperExprNode(pos, e); } @@ -304,105 +304,105 @@ JS::ExprNode *JS::Parser::parseSuper(uint32 pos, SuperState superState) // set to false. JS::ExprNode *JS::Parser::parsePrimaryExpression(SuperState superState) { - ExprNode *e; - ExprNode::Kind eKind; + ExprNode *e; + ExprNode::Kind eKind; - const Token &t = lexer.get(true); - switch (t.getKind()) { - case Token::Null: - eKind = ExprNode::Null; - goto makeExprNode; + const Token &t = lexer.get(true); + switch (t.getKind()) { + case Token::Null: + eKind = ExprNode::Null; + goto makeExprNode; - case Token::True: - eKind = ExprNode::True; - goto makeExprNode; + case Token::True: + eKind = ExprNode::True; + goto makeExprNode; - case Token::False: - eKind = ExprNode::False; - goto makeExprNode; + case Token::False: + eKind = ExprNode::False; + goto makeExprNode; - case Token::This: - eKind = ExprNode::This; - makeExprNode: - e = new(arena) ExprNode(t.getPos(), eKind); - break; + case Token::This: + eKind = ExprNode::This; + makeExprNode: + e = new(arena) ExprNode(t.getPos(), eKind); + break; - case Token::Public: - if (lexer.peek(false).hasKind(Token::doubleColon)) - goto makeQualifiedIdentifierNode; - e = new(arena) IdentifierExprNode(t); - break; + case Token::Public: + if (lexer.peek(false).hasKind(Token::doubleColon)) + goto makeQualifiedIdentifierNode; + e = new(arena) IdentifierExprNode(t); + break; - case Token::number: - { - const Token &tUnit = lexer.peek(false); - if (!lineBreakBefore(tUnit) && - (tUnit.hasKind(Token::unit) || tUnit.hasKind(Token::string))) { - lexer.get(false); - e = parseUnitSuffixes(new(arena) NumUnitExprNode(t.getPos(), ExprNode::numUnit, copyTokenChars(t), - t.getValue(), copyTokenChars(tUnit))); - } else - e = new(arena) NumberExprNode(t); - } - break; + case Token::number: + { + const Token &tUnit = lexer.peek(false); + if (!lineBreakBefore(tUnit) && + (tUnit.hasKind(Token::unit) || tUnit.hasKind(Token::string))) { + lexer.get(false); + e = parseUnitSuffixes(new(arena) NumUnitExprNode(t.getPos(), ExprNode::numUnit, copyTokenChars(t), + t.getValue(), copyTokenChars(tUnit))); + } else + e = new(arena) NumberExprNode(t); + } + break; - case Token::string: - e = NodeFactory::LiteralString(t.getPos(), ExprNode::string, copyTokenChars(t)); - break; + case Token::string: + e = NodeFactory::LiteralString(t.getPos(), ExprNode::string, copyTokenChars(t)); + break; - case Token::regExp: - e = new(arena) RegExpExprNode(t.getPos(), ExprNode::regExp, t.getIdentifier(), copyTokenChars(t)); - break; + case Token::regExp: + e = new(arena) RegExpExprNode(t.getPos(), ExprNode::regExp, t.getIdentifier(), copyTokenChars(t)); + break; - case Token::Private: - case CASE_TOKEN_NONRESERVED: - makeQualifiedIdentifierNode: - e = parseQualifiedIdentifier(t, false); - break; + case Token::Private: + case CASE_TOKEN_NONRESERVED: + makeQualifiedIdentifierNode: + e = parseQualifiedIdentifier(t, false); + break; - case Token::openParenthesis: - { - bool foundQualifiers; - e = parseParenthesesAndIdentifierQualifiers(t, false, foundQualifiers, false); - if (!foundQualifiers) - e = parseUnitSuffixes(e); - } - break; + case Token::openParenthesis: + { + bool foundQualifiers; + e = parseParenthesesAndIdentifierQualifiers(t, false, foundQualifiers, false); + if (!foundQualifiers) + e = parseUnitSuffixes(e); + } + break; - case Token::openBracket: - e = parseArrayLiteral(t); - break; + case Token::openBracket: + e = parseArrayLiteral(t); + break; - case Token::openBrace: - e = parseObjectLiteral(t); - break; + case Token::openBrace: + e = parseObjectLiteral(t); + break; - case Token::Function: - { - FunctionExprNode *f = new(arena) FunctionExprNode(t.getPos()); - const Token &t2 = lexer.get(true); - f->function.prefix = FunctionName::normal; - if (!(f->function.name = makeIdentifierExpression(t2))) - lexer.unget(); - parseFunctionSignature(f->function); - f->function.body = parseBody(0); - e = f; - } - break; + case Token::Function: + { + FunctionExprNode *f = new(arena) FunctionExprNode(t.getPos()); + const Token &t2 = lexer.get(true); + f->function.prefix = FunctionName::normal; + if (!(f->function.name = makeIdentifierExpression(t2))) + lexer.unget(); + parseFunctionSignature(f->function); + f->function.body = parseBody(0); + e = f; + } + break; - case Token::Super: - if (superState != ssNone) { - e = parseSuper(t.getPos(), superState); - break; - } - // Fall through to a syntax error if super is not allowed. - default: - syntaxError("Expression expected"); - // Unreachable code here just to shut up compiler warnings - e = 0; - } + case Token::Super: + if (superState != ssNone) { + e = parseSuper(t.getPos(), superState); + break; + } + // Fall through to a syntax error if super is not allowed. + default: + syntaxError("Expression expected"); + // Unreachable code here just to shut up compiler warnings + e = 0; + } - return e; + return e; } @@ -414,57 +414,57 @@ JS::ExprNode *JS::Parser::parsePrimaryExpression(SuperState superState) // preferRegExp setting. JS::ExprNode *JS::Parser::parseMember(ExprNode *target, const Token &tOperator, bool preferRegExp) { - uint32 pos = tOperator.getPos(); - const Token &t2 = lexer.get(true); + size_t pos = tOperator.getPos(); + const Token &t2 = lexer.get(true); - if (t2.hasKind(Token::Class) && !target->hasKind(ExprNode::superExpr)) - return new(arena) UnaryExprNode(pos, ExprNode::dotClass, target); + if (t2.hasKind(Token::Class) && !target->hasKind(ExprNode::superExpr)) + return new(arena) UnaryExprNode(pos, ExprNode::dotClass, target); - ExprNode *member; - ExprNode::Kind kind = ExprNode::dot; - if (t2.hasKind(Token::openParenthesis) && !target->hasKind(ExprNode::superExpr)) { - bool foundQualifiers; - member = parseParenthesesAndIdentifierQualifiers(t2, true, foundQualifiers, false); - if (!foundQualifiers) - kind = ExprNode::dotParen; - } else - member = parseQualifiedIdentifier(t2, preferRegExp); - return new(arena) BinaryExprNode(pos, kind, target, member); + ExprNode *member; + ExprNode::Kind kind = ExprNode::dot; + if (t2.hasKind(Token::openParenthesis) && !target->hasKind(ExprNode::superExpr)) { + bool foundQualifiers; + member = parseParenthesesAndIdentifierQualifiers(t2, true, foundQualifiers, false); + if (!foundQualifiers) + kind = ExprNode::dotParen; + } else + member = parseQualifiedIdentifier(t2, preferRegExp); + return new(arena) BinaryExprNode(pos, kind, target, member); } // Parse an ArgumentsList followed by a closing parenthesis or bracket and return the resulting InvokeExprNode. // The target function, indexed object, or created class is supplied. The opening parenthesis // or bracket has already been read. pos is the position to use for the generated node. -JS::InvokeExprNode *JS::Parser::parseInvoke(ExprNode *target, uint32 pos, Token::Kind closingTokenKind, ExprNode::Kind invokeKind) +JS::InvokeExprNode *JS::Parser::parseInvoke(ExprNode *target, size_t pos, Token::Kind closingTokenKind, ExprNode::Kind invokeKind) { - NodeQueue arguments; - bool hasNamedArgument = false; + NodeQueue arguments; + bool hasNamedArgument = false; - if (!lexer.eat(true, closingTokenKind)) - while (true) { - ExprNode *field = 0; - ExprNode *value = parseAssignmentExpression(false); - if (lexer.eat(false, Token::colon)) { - field = value; - if (!(field->hasKind(ExprNode::identifier) || - field->hasKind(ExprNode::number) || - field->hasKind(ExprNode::string) || - field->hasKind(ExprNode::parentheses) && !static_cast(field)->op->hasKind(ExprNode::comma))) - syntaxError("Argument name must be an identifier, string, number, or parenthesized expression"); - hasNamedArgument = true; - value = parseAssignmentExpression(false); - } else if (hasNamedArgument) - syntaxError("Unnamed argument cannot follow named argument", 0); - arguments += new(arena) ExprPairList(field, value); + if (!lexer.eat(true, closingTokenKind)) + while (true) { + ExprNode *field = 0; + ExprNode *value = parseAssignmentExpression(false); + if (lexer.eat(false, Token::colon)) { + field = value; + if (!(field->hasKind(ExprNode::identifier) || + field->hasKind(ExprNode::number) || + field->hasKind(ExprNode::string) || + field->hasKind(ExprNode::parentheses) && !static_cast(field)->op->hasKind(ExprNode::comma))) + syntaxError("Argument name must be an identifier, string, number, or parenthesized expression"); + hasNamedArgument = true; + value = parseAssignmentExpression(false); + } else if (hasNamedArgument) + syntaxError("Unnamed argument cannot follow named argument", 0); + arguments += new(arena) ExprPairList(field, value); - const Token &tSeparator = lexer.get(false); - if (tSeparator.hasKind(closingTokenKind)) - break; - if (!tSeparator.hasKind(Token::comma)) - syntaxError("',' expected"); - } - return new(arena) InvokeExprNode(pos, invokeKind, target, arguments.first); + const Token &tSeparator = lexer.get(false); + if (tSeparator.hasKind(closingTokenKind)) + break; + if (!tSeparator.hasKind(Token::comma)) + syntaxError("',' expected"); + } + return new(arena) InvokeExprNode(pos, invokeKind, target, arguments.first); } @@ -477,42 +477,42 @@ JS::InvokeExprNode *JS::Parser::parseInvoke(ExprNode *target, uint32 pos, Token: // might have been peeked with preferRegExp set to the value of the attribute parameter. JS::ExprNode *JS::Parser::parsePostfixOperator(ExprNode *e, bool newExpression, bool attribute) { - while (true) { - ExprNode::Kind eKind; - const Token &t = lexer.get(attribute); - switch (t.getKind()) { - case Token::openParenthesis: - if (newExpression) - goto other; - e = parseInvoke(e, t.getPos(), Token::closeParenthesis, ExprNode::call); - break; + while (true) { + ExprNode::Kind eKind; + const Token &t = lexer.get(attribute); + switch (t.getKind()) { + case Token::openParenthesis: + if (newExpression) + goto other; + e = parseInvoke(e, t.getPos(), Token::closeParenthesis, ExprNode::call); + break; - case Token::openBracket: - e = parseInvoke(e, t.getPos(), Token::closeBracket, ExprNode::index); - break; + case Token::openBracket: + e = parseInvoke(e, t.getPos(), Token::closeBracket, ExprNode::index); + break; - case Token::dot: - e = parseMember(e, t, attribute); - break; + case Token::dot: + e = parseMember(e, t, attribute); + break; - case Token::increment: - eKind = ExprNode::postIncrement; - incDec: - if (newExpression || attribute || lineBreakBefore(t)) - goto other; - e = new(arena) UnaryExprNode(t.getPos(), eKind, e); - break; + case Token::increment: + eKind = ExprNode::postIncrement; + incDec: + if (newExpression || attribute || lineBreakBefore(t)) + goto other; + e = new(arena) UnaryExprNode(t.getPos(), eKind, e); + break; - case Token::decrement: - eKind = ExprNode::postDecrement; - goto incDec; + case Token::decrement: + eKind = ExprNode::postDecrement; + goto incDec; - default: - other: - lexer.unget(); - return e; - } - } + default: + other: + lexer.unget(); + return e; + } + } } @@ -526,26 +526,26 @@ JS::ExprNode *JS::Parser::parsePostfixOperator(ExprNode *e, bool newExpression, // set to false. JS::ExprNode *JS::Parser::parsePostfixExpression(SuperState superState, bool newExpression) { - ExprNode *e; + ExprNode *e; - const Token *tNew = lexer.eat(true, Token::New); - if (tNew) { - checkStackSize(); - uint32 posNew = tNew->getPos(); - e = parsePostfixExpression(ssExpr, true); - if (lexer.eat(false, Token::openParenthesis)) - e = parseInvoke(e, posNew, Token::closeParenthesis, ExprNode::New); - else - e = new(arena) InvokeExprNode(posNew, ExprNode::New, e, 0); - } else { - e = parsePrimaryExpression(superState); - if (e->hasKind(ExprNode::superStmt)) { - ASSERT(superState == ssStmt); - return e; - } - } + const Token *tNew = lexer.eat(true, Token::New); + if (tNew) { + checkStackSize(); + size_t posNew = tNew->getPos(); + e = parsePostfixExpression(ssExpr, true); + if (lexer.eat(false, Token::openParenthesis)) + e = parseInvoke(e, posNew, Token::closeParenthesis, ExprNode::New); + else + e = new(arena) InvokeExprNode(posNew, ExprNode::New, e, 0); + } else { + e = parsePrimaryExpression(superState); + if (e->hasKind(ExprNode::superStmt)) { + ASSERT(superState == ssStmt); + return e; + } + } - return parsePostfixOperator(e, newExpression, false); + return parsePostfixOperator(e, newExpression, false); } @@ -553,10 +553,10 @@ JS::ExprNode *JS::Parser::parsePostfixExpression(SuperState superState, bool new // the current token. void JS::Parser::ensurePostfix(const ExprNode *e) { - ASSERT(e); - if (!e->isPostfix()) - syntaxError("Only a postfix expression can be used as the target " - "of an assignment; enclose this expression in parentheses", 0); + ASSERT(e); + if (!e->isPostfix()) + syntaxError("Only a postfix expression can be used as the target " + "of an assignment; enclose this expression in parentheses", 0); } @@ -566,69 +566,69 @@ void JS::Parser::ensurePostfix(const ExprNode *e) // set to true. JS::ExprNode *JS::Parser::parseAttribute(const Token &t) { - ExprNode::Kind eKind; + ExprNode::Kind eKind; - switch (t.getKind()) { - case Token::True: - eKind = ExprNode::True; - goto makeExprNode; + switch (t.getKind()) { + case Token::True: + eKind = ExprNode::True; + goto makeExprNode; - case Token::False: - eKind = ExprNode::False; - makeExprNode: - return new(arena) ExprNode(t.getPos(), eKind); + case Token::False: + eKind = ExprNode::False; + makeExprNode: + return new(arena) ExprNode(t.getPos(), eKind); - case Token::Public: - case Token::Private: - if (lexer.peek(true).hasKind(Token::doubleColon)) - break; - case Token::Abstract: - case Token::Final: - case Token::Static: - case Token::Volatile: - return new(arena) IdentifierExprNode(t); + case Token::Public: + case Token::Private: + if (lexer.peek(true).hasKind(Token::doubleColon)) + break; + case Token::Abstract: + case Token::Final: + case Token::Static: + case Token::Volatile: + return new(arena) IdentifierExprNode(t); - case CASE_TOKEN_NONRESERVED: - break; + case CASE_TOKEN_NONRESERVED: + break; - default: - syntaxError("Attribute expected"); - } + default: + syntaxError("Attribute expected"); + } - return parsePostfixOperator(parseQualifiedIdentifier(t, true), false, true); + return parsePostfixOperator(parseQualifiedIdentifier(t, true), false, true); } // e is a parsed ListExpression or SuperStatement. Return true if e is also an Attribute. bool JS::Parser::expressionIsAttribute(const ExprNode *e) { - while (true) - switch (e->getKind()) { - case ExprNode::identifier: - case ExprNode::True: - case ExprNode::False: - return true; + while (true) + switch (e->getKind()) { + case ExprNode::identifier: + case ExprNode::True: + case ExprNode::False: + return true; - case ExprNode::qualify: - return static_cast(e)->op1->hasKind(ExprNode::identifier); + case ExprNode::qualify: + return static_cast(e)->op1->hasKind(ExprNode::identifier); - case ExprNode::call: - case ExprNode::index: - e = static_cast(e)->op; - break; + case ExprNode::call: + case ExprNode::index: + e = static_cast(e)->op; + break; - case ExprNode::dot: - case ExprNode::dotParen: - e = static_cast(e)->op1; - break; + case ExprNode::dot: + case ExprNode::dotParen: + e = static_cast(e)->op1; + break; - case ExprNode::dotClass: - e = static_cast(e)->op; - break; + case ExprNode::dotClass: + e = static_cast(e)->op; + break; - default: - return false; - } + default: + return false; + } } @@ -640,212 +640,212 @@ bool JS::Parser::expressionIsAttribute(const ExprNode *e) // set to false. JS::ExprNode *JS::Parser::parseUnaryExpression(SuperState superState) { - ExprNode::Kind eKind; - ExprNode *e; + ExprNode::Kind eKind; + ExprNode *e; - const Token &t = lexer.peek(true); - uint32 pos = t.getPos(); - switch (t.getKind()) { - case Token::Const: - eKind = ExprNode::Const; - goto getPostfixExpression; + const Token &t = lexer.peek(true); + size_t pos = t.getPos(); + switch (t.getKind()) { + case Token::Const: + eKind = ExprNode::Const; + goto getPostfixExpression; - case Token::Delete: - eKind = ExprNode::Delete; - goto getPostfixExpression; + case Token::Delete: + eKind = ExprNode::Delete; + goto getPostfixExpression; - case Token::increment: - eKind = ExprNode::preIncrement; - goto getPostfixExpression; + case Token::increment: + eKind = ExprNode::preIncrement; + goto getPostfixExpression; - case Token::decrement: - eKind = ExprNode::preDecrement; - getPostfixExpression: - lexer.get(true); - e = parsePostfixExpression(ssExpr, false); - break; + case Token::decrement: + eKind = ExprNode::preDecrement; + getPostfixExpression: + lexer.get(true); + e = parsePostfixExpression(ssExpr, false); + break; - case Token::Void: - eKind = ExprNode::Void; - goto getUnaryExpressionNotSuper; + case Token::Void: + eKind = ExprNode::Void; + goto getUnaryExpressionNotSuper; - case Token::Typeof: - eKind = ExprNode::Typeof; - goto getUnaryExpressionNotSuper; + case Token::Typeof: + eKind = ExprNode::Typeof; + goto getUnaryExpressionNotSuper; - case Token::plus: - eKind = ExprNode::plus; - goto getUnaryExpressionOrSuper; + case Token::plus: + eKind = ExprNode::plus; + goto getUnaryExpressionOrSuper; - case Token::minus: - eKind = ExprNode::minus; - goto getUnaryExpressionOrSuper; + case Token::minus: + eKind = ExprNode::minus; + goto getUnaryExpressionOrSuper; - case Token::complement: - eKind = ExprNode::complement; - getUnaryExpressionOrSuper: - superState = ssExpr; - goto getUnaryExpression; + case Token::complement: + eKind = ExprNode::complement; + getUnaryExpressionOrSuper: + superState = ssExpr; + goto getUnaryExpression; - case Token::logicalNot: - eKind = ExprNode::logicalNot; - getUnaryExpressionNotSuper: - superState = ssNone; - getUnaryExpression: - lexer.get(true); - checkStackSize(); - e = parseUnaryExpression(superState); - break; + case Token::logicalNot: + eKind = ExprNode::logicalNot; + getUnaryExpressionNotSuper: + superState = ssNone; + getUnaryExpression: + lexer.get(true); + checkStackSize(); + e = parseUnaryExpression(superState); + break; - default: - return parsePostfixExpression(superState, false); - } - return new(arena) UnaryExprNode(pos, eKind, e); + default: + return parsePostfixExpression(superState, false); + } + return new(arena) UnaryExprNode(pos, eKind, e); } const JS::Parser::BinaryOperatorInfo JS::Parser::tokenBinaryOperatorInfos[Token::kindsEnd] = { - // Special - {ExprNode::none, pExpression, pNone, false}, // Token::end - {ExprNode::none, pExpression, pNone, false}, // Token::number - {ExprNode::none, pExpression, pNone, false}, // Token::string - {ExprNode::none, pExpression, pNone, false}, // Token::unit - {ExprNode::none, pExpression, pNone, false}, // Token::regExp + // Special + {ExprNode::none, pExpression, pNone, false}, // Token::end + {ExprNode::none, pExpression, pNone, false}, // Token::number + {ExprNode::none, pExpression, pNone, false}, // Token::string + {ExprNode::none, pExpression, pNone, false}, // Token::unit + {ExprNode::none, pExpression, pNone, false}, // Token::regExp - // Punctuators - {ExprNode::none, pExpression, pNone, false}, // Token::openParenthesis - {ExprNode::none, pExpression, pNone, false}, // Token::closeParenthesis - {ExprNode::none, pExpression, pNone, false}, // Token::openBracket - {ExprNode::none, pExpression, pNone, false}, // Token::closeBracket - {ExprNode::none, pExpression, pNone, false}, // Token::openBrace - {ExprNode::none, pExpression, pNone, false}, // Token::closeBrace - {ExprNode::comma, pExpression, pExpression, false}, // Token::comma - {ExprNode::none, pExpression, pNone, false}, // Token::semicolon - {ExprNode::none, pExpression, pNone, false}, // Token::dot - {ExprNode::none, pExpression, pNone, false}, // Token::doubleDot - {ExprNode::none, pExpression, pNone, false}, // Token::tripleDot - {ExprNode::none, pExpression, pNone, false}, // Token::arrow - {ExprNode::none, pExpression, pNone, false}, // Token::colon - {ExprNode::none, pExpression, pNone, false}, // Token::doubleColon - {ExprNode::none, pExpression, pNone, false}, // Token::pound - {ExprNode::none, pExpression, pNone, false}, // Token::at - {ExprNode::none, pExpression, pNone, false}, // Token::increment - {ExprNode::none, pExpression, pNone, false}, // Token::decrement - {ExprNode::none, pExpression, pNone, false}, // Token::complement - {ExprNode::none, pExpression, pNone, false}, // Token::logicalNot - {ExprNode::multiply, pMultiplicative, pMultiplicative, true}, // Token::times - {ExprNode::divide, pMultiplicative, pMultiplicative, true}, // Token::divide - {ExprNode::modulo, pMultiplicative, pMultiplicative, true}, // Token::modulo - {ExprNode::add, pAdditive, pAdditive, true}, // Token::plus - {ExprNode::subtract, pAdditive, pAdditive, true}, // Token::minus - {ExprNode::leftShift, pShift, pShift, true}, // Token::leftShift - {ExprNode::rightShift, pShift, pShift, true}, // Token::rightShift - {ExprNode::logicalRightShift, pShift, pShift, true}, // Token::logicalRightShift - {ExprNode::logicalAnd, pBitwiseOr, pLogicalAnd, false}, // Token::logicalAnd (right-associative for efficiency) - {ExprNode::logicalXor, pLogicalAnd, pLogicalXor, false}, // Token::logicalXor (right-associative for efficiency) - {ExprNode::logicalOr, pLogicalXor, pLogicalOr, false}, // Token::logicalOr (right-associative for efficiency) - {ExprNode::bitwiseAnd, pBitwiseAnd, pBitwiseAnd, true}, // Token::bitwiseAnd - {ExprNode::bitwiseXor, pBitwiseXor, pBitwiseXor, true}, // Token::bitwiseXor - {ExprNode::bitwiseOr, pBitwiseOr, pBitwiseOr, true}, // Token::bitwiseOr - {ExprNode::assignment, pPostfix, pAssignment, false}, // Token::assignment - {ExprNode::multiplyEquals, pPostfix, pAssignment, true}, // Token::timesEquals - {ExprNode::divideEquals, pPostfix, pAssignment, true}, // Token::divideEquals - {ExprNode::moduloEquals, pPostfix, pAssignment, true}, // Token::moduloEquals - {ExprNode::addEquals, pPostfix, pAssignment, true}, // Token::plusEquals - {ExprNode::subtractEquals, pPostfix, pAssignment, true}, // Token::minusEquals - {ExprNode::leftShiftEquals, pPostfix, pAssignment, true}, // Token::leftShiftEquals - {ExprNode::rightShiftEquals, pPostfix, pAssignment, true}, // Token::rightShiftEquals - {ExprNode::logicalRightShiftEquals, pPostfix, pAssignment, true}, // Token::logicalRightShiftEquals - {ExprNode::logicalAndEquals, pPostfix, pAssignment, false}, // Token::logicalAndEquals - {ExprNode::logicalXorEquals, pPostfix, pAssignment, false}, // Token::logicalXorEquals - {ExprNode::logicalOrEquals, pPostfix, pAssignment, false}, // Token::logicalOrEquals - {ExprNode::bitwiseAndEquals, pPostfix, pAssignment, true}, // Token::bitwiseAndEquals - {ExprNode::bitwiseXorEquals, pPostfix, pAssignment, true}, // Token::bitwiseXorEquals - {ExprNode::bitwiseOrEquals, pPostfix, pAssignment, true}, // Token::bitwiseOrEquals - {ExprNode::equal, pEquality, pEquality, true}, // Token::equal - {ExprNode::notEqual, pEquality, pEquality, true}, // Token::notEqual - {ExprNode::lessThan, pRelational, pRelational, true}, // Token::lessThan - {ExprNode::lessThanOrEqual, pRelational, pRelational, true}, // Token::lessThanOrEqual - {ExprNode::greaterThan, pRelational, pRelational, true}, // Token::greaterThan - {ExprNode::greaterThanOrEqual, pRelational, pRelational, true}, // Token::greaterThanOrEqual - {ExprNode::identical, pEquality, pEquality, true}, // Token::identical - {ExprNode::notIdentical, pEquality, pEquality, true}, // Token::notIdentical - {ExprNode::conditional, pLogicalOr, pConditional, false}, // Token::question + // Punctuators + {ExprNode::none, pExpression, pNone, false}, // Token::openParenthesis + {ExprNode::none, pExpression, pNone, false}, // Token::closeParenthesis + {ExprNode::none, pExpression, pNone, false}, // Token::openBracket + {ExprNode::none, pExpression, pNone, false}, // Token::closeBracket + {ExprNode::none, pExpression, pNone, false}, // Token::openBrace + {ExprNode::none, pExpression, pNone, false}, // Token::closeBrace + {ExprNode::comma, pExpression, pExpression, false}, // Token::comma + {ExprNode::none, pExpression, pNone, false}, // Token::semicolon + {ExprNode::none, pExpression, pNone, false}, // Token::dot + {ExprNode::none, pExpression, pNone, false}, // Token::doubleDot + {ExprNode::none, pExpression, pNone, false}, // Token::tripleDot + {ExprNode::none, pExpression, pNone, false}, // Token::arrow + {ExprNode::none, pExpression, pNone, false}, // Token::colon + {ExprNode::none, pExpression, pNone, false}, // Token::doubleColon + {ExprNode::none, pExpression, pNone, false}, // Token::pound + {ExprNode::none, pExpression, pNone, false}, // Token::at + {ExprNode::none, pExpression, pNone, false}, // Token::increment + {ExprNode::none, pExpression, pNone, false}, // Token::decrement + {ExprNode::none, pExpression, pNone, false}, // Token::complement + {ExprNode::none, pExpression, pNone, false}, // Token::logicalNot + {ExprNode::multiply, pMultiplicative, pMultiplicative, true}, // Token::times + {ExprNode::divide, pMultiplicative, pMultiplicative, true}, // Token::divide + {ExprNode::modulo, pMultiplicative, pMultiplicative, true}, // Token::modulo + {ExprNode::add, pAdditive, pAdditive, true}, // Token::plus + {ExprNode::subtract, pAdditive, pAdditive, true}, // Token::minus + {ExprNode::leftShift, pShift, pShift, true}, // Token::leftShift + {ExprNode::rightShift, pShift, pShift, true}, // Token::rightShift + {ExprNode::logicalRightShift, pShift, pShift, true}, // Token::logicalRightShift + {ExprNode::logicalAnd, pBitwiseOr, pLogicalAnd, false}, // Token::logicalAnd (right-associative for efficiency) + {ExprNode::logicalXor, pLogicalAnd, pLogicalXor, false}, // Token::logicalXor (right-associative for efficiency) + {ExprNode::logicalOr, pLogicalXor, pLogicalOr, false}, // Token::logicalOr (right-associative for efficiency) + {ExprNode::bitwiseAnd, pBitwiseAnd, pBitwiseAnd, true}, // Token::bitwiseAnd + {ExprNode::bitwiseXor, pBitwiseXor, pBitwiseXor, true}, // Token::bitwiseXor + {ExprNode::bitwiseOr, pBitwiseOr, pBitwiseOr, true}, // Token::bitwiseOr + {ExprNode::assignment, pPostfix, pAssignment, false}, // Token::assignment + {ExprNode::multiplyEquals, pPostfix, pAssignment, true}, // Token::timesEquals + {ExprNode::divideEquals, pPostfix, pAssignment, true}, // Token::divideEquals + {ExprNode::moduloEquals, pPostfix, pAssignment, true}, // Token::moduloEquals + {ExprNode::addEquals, pPostfix, pAssignment, true}, // Token::plusEquals + {ExprNode::subtractEquals, pPostfix, pAssignment, true}, // Token::minusEquals + {ExprNode::leftShiftEquals, pPostfix, pAssignment, true}, // Token::leftShiftEquals + {ExprNode::rightShiftEquals, pPostfix, pAssignment, true}, // Token::rightShiftEquals + {ExprNode::logicalRightShiftEquals, pPostfix, pAssignment, true}, // Token::logicalRightShiftEquals + {ExprNode::logicalAndEquals, pPostfix, pAssignment, false}, // Token::logicalAndEquals + {ExprNode::logicalXorEquals, pPostfix, pAssignment, false}, // Token::logicalXorEquals + {ExprNode::logicalOrEquals, pPostfix, pAssignment, false}, // Token::logicalOrEquals + {ExprNode::bitwiseAndEquals, pPostfix, pAssignment, true}, // Token::bitwiseAndEquals + {ExprNode::bitwiseXorEquals, pPostfix, pAssignment, true}, // Token::bitwiseXorEquals + {ExprNode::bitwiseOrEquals, pPostfix, pAssignment, true}, // Token::bitwiseOrEquals + {ExprNode::equal, pEquality, pEquality, true}, // Token::equal + {ExprNode::notEqual, pEquality, pEquality, true}, // Token::notEqual + {ExprNode::lessThan, pRelational, pRelational, true}, // Token::lessThan + {ExprNode::lessThanOrEqual, pRelational, pRelational, true}, // Token::lessThanOrEqual + {ExprNode::greaterThan, pRelational, pRelational, true}, // Token::greaterThan + {ExprNode::greaterThanOrEqual, pRelational, pRelational, true}, // Token::greaterThanOrEqual + {ExprNode::identical, pEquality, pEquality, true}, // Token::identical + {ExprNode::notIdentical, pEquality, pEquality, true}, // Token::notIdentical + {ExprNode::conditional, pLogicalOr, pConditional, false}, // Token::question - // Reserved words - {ExprNode::none, pExpression, pNone, false}, // Token::Abstract - {ExprNode::In, pRelational, pRelational, false}, // Token::As - {ExprNode::none, pExpression, pNone, false}, // Token::Break - {ExprNode::none, pExpression, pNone, false}, // Token::Case - {ExprNode::none, pExpression, pNone, false}, // Token::Catch - {ExprNode::none, pExpression, pNone, false}, // Token::Class - {ExprNode::none, pExpression, pNone, false}, // Token::Const - {ExprNode::none, pExpression, pNone, false}, // Token::Continue - {ExprNode::none, pExpression, pNone, false}, // Token::Debugger - {ExprNode::none, pExpression, pNone, false}, // Token::Default - {ExprNode::none, pExpression, pNone, false}, // Token::Delete - {ExprNode::none, pExpression, pNone, false}, // Token::Do - {ExprNode::none, pExpression, pNone, false}, // Token::Else - {ExprNode::none, pExpression, pNone, false}, // Token::Enum - {ExprNode::none, pExpression, pNone, false}, // Token::Export - {ExprNode::none, pExpression, pNone, false}, // Token::Extends - {ExprNode::none, pExpression, pNone, false}, // Token::False - {ExprNode::none, pExpression, pNone, false}, // Token::Final - {ExprNode::none, pExpression, pNone, false}, // Token::Finally - {ExprNode::none, pExpression, pNone, false}, // Token::For - {ExprNode::none, pExpression, pNone, false}, // Token::Function - {ExprNode::none, pExpression, pNone, false}, // Token::Goto - {ExprNode::none, pExpression, pNone, false}, // Token::If - {ExprNode::none, pExpression, pNone, false}, // Token::Implements - {ExprNode::none, pExpression, pNone, false}, // Token::Import - {ExprNode::In, pRelational, pRelational, false}, // Token::In - {ExprNode::Instanceof, pRelational, pRelational, false}, // Token::Instanceof - {ExprNode::none, pExpression, pNone, false}, // Token::Interface - {ExprNode::Is, pRelational, pRelational, false}, // Token::Is - {ExprNode::none, pExpression, pNone, false}, // Token::Namespace - {ExprNode::none, pExpression, pNone, false}, // Token::Native - {ExprNode::none, pExpression, pNone, false}, // Token::New - {ExprNode::none, pExpression, pNone, false}, // Token::Null - {ExprNode::none, pExpression, pNone, false}, // Token::Package - {ExprNode::none, pExpression, pNone, false}, // Token::Private - {ExprNode::none, pExpression, pNone, false}, // Token::Protected - {ExprNode::none, pExpression, pNone, false}, // Token::Public - {ExprNode::none, pExpression, pNone, false}, // Token::Return - {ExprNode::none, pExpression, pNone, false}, // Token::Static - {ExprNode::none, pExpression, pNone, false}, // Token::Super - {ExprNode::none, pExpression, pNone, false}, // Token::Switch - {ExprNode::none, pExpression, pNone, false}, // Token::Synchronized - {ExprNode::none, pExpression, pNone, false}, // Token::This - {ExprNode::none, pExpression, pNone, false}, // Token::Throw - {ExprNode::none, pExpression, pNone, false}, // Token::Throws - {ExprNode::none, pExpression, pNone, false}, // Token::Transient - {ExprNode::none, pExpression, pNone, false}, // Token::True - {ExprNode::none, pExpression, pNone, false}, // Token::Try - {ExprNode::none, pExpression, pNone, false}, // Token::Typeof - {ExprNode::none, pExpression, pNone, false}, // Token::Use - {ExprNode::none, pExpression, pNone, false}, // Token::Var - {ExprNode::none, pExpression, pNone, false}, // Token::Void - {ExprNode::none, pExpression, pNone, false}, // Token::Volatile - {ExprNode::none, pExpression, pNone, false}, // Token::While - {ExprNode::none, pExpression, pNone, false}, // Token::With + // Reserved words + {ExprNode::none, pExpression, pNone, false}, // Token::Abstract + {ExprNode::In, pRelational, pRelational, false}, // Token::As + {ExprNode::none, pExpression, pNone, false}, // Token::Break + {ExprNode::none, pExpression, pNone, false}, // Token::Case + {ExprNode::none, pExpression, pNone, false}, // Token::Catch + {ExprNode::none, pExpression, pNone, false}, // Token::Class + {ExprNode::none, pExpression, pNone, false}, // Token::Const + {ExprNode::none, pExpression, pNone, false}, // Token::Continue + {ExprNode::none, pExpression, pNone, false}, // Token::Debugger + {ExprNode::none, pExpression, pNone, false}, // Token::Default + {ExprNode::none, pExpression, pNone, false}, // Token::Delete + {ExprNode::none, pExpression, pNone, false}, // Token::Do + {ExprNode::none, pExpression, pNone, false}, // Token::Else + {ExprNode::none, pExpression, pNone, false}, // Token::Enum + {ExprNode::none, pExpression, pNone, false}, // Token::Export + {ExprNode::none, pExpression, pNone, false}, // Token::Extends + {ExprNode::none, pExpression, pNone, false}, // Token::False + {ExprNode::none, pExpression, pNone, false}, // Token::Final + {ExprNode::none, pExpression, pNone, false}, // Token::Finally + {ExprNode::none, pExpression, pNone, false}, // Token::For + {ExprNode::none, pExpression, pNone, false}, // Token::Function + {ExprNode::none, pExpression, pNone, false}, // Token::Goto + {ExprNode::none, pExpression, pNone, false}, // Token::If + {ExprNode::none, pExpression, pNone, false}, // Token::Implements + {ExprNode::none, pExpression, pNone, false}, // Token::Import + {ExprNode::In, pRelational, pRelational, false}, // Token::In + {ExprNode::Instanceof, pRelational, pRelational, false}, // Token::Instanceof + {ExprNode::none, pExpression, pNone, false}, // Token::Interface + {ExprNode::Is, pRelational, pRelational, false}, // Token::Is + {ExprNode::none, pExpression, pNone, false}, // Token::Namespace + {ExprNode::none, pExpression, pNone, false}, // Token::Native + {ExprNode::none, pExpression, pNone, false}, // Token::New + {ExprNode::none, pExpression, pNone, false}, // Token::Null + {ExprNode::none, pExpression, pNone, false}, // Token::Package + {ExprNode::none, pExpression, pNone, false}, // Token::Private + {ExprNode::none, pExpression, pNone, false}, // Token::Protected + {ExprNode::none, pExpression, pNone, false}, // Token::Public + {ExprNode::none, pExpression, pNone, false}, // Token::Return + {ExprNode::none, pExpression, pNone, false}, // Token::Static + {ExprNode::none, pExpression, pNone, false}, // Token::Super + {ExprNode::none, pExpression, pNone, false}, // Token::Switch + {ExprNode::none, pExpression, pNone, false}, // Token::Synchronized + {ExprNode::none, pExpression, pNone, false}, // Token::This + {ExprNode::none, pExpression, pNone, false}, // Token::Throw + {ExprNode::none, pExpression, pNone, false}, // Token::Throws + {ExprNode::none, pExpression, pNone, false}, // Token::Transient + {ExprNode::none, pExpression, pNone, false}, // Token::True + {ExprNode::none, pExpression, pNone, false}, // Token::Try + {ExprNode::none, pExpression, pNone, false}, // Token::Typeof + {ExprNode::none, pExpression, pNone, false}, // Token::Use + {ExprNode::none, pExpression, pNone, false}, // Token::Var + {ExprNode::none, pExpression, pNone, false}, // Token::Void + {ExprNode::none, pExpression, pNone, false}, // Token::Volatile + {ExprNode::none, pExpression, pNone, false}, // Token::While + {ExprNode::none, pExpression, pNone, false}, // Token::With - // Non-reserved words - {ExprNode::none, pExpression, pNone, false}, // Token::Eval - {ExprNode::none, pExpression, pNone, false}, // Token::Exclude - {ExprNode::none, pExpression, pNone, false}, // Token::Get - {ExprNode::none, pExpression, pNone, false}, // Token::Include - {ExprNode::none, pExpression, pNone, false}, // Token::Set + // Non-reserved words + {ExprNode::none, pExpression, pNone, false}, // Token::Eval + {ExprNode::none, pExpression, pNone, false}, // Token::Exclude + {ExprNode::none, pExpression, pNone, false}, // Token::Get + {ExprNode::none, pExpression, pNone, false}, // Token::Include + {ExprNode::none, pExpression, pNone, false}, // Token::Set - {ExprNode::none, pExpression, pNone, false} // Token::identifier + {ExprNode::none, pExpression, pNone, false} // Token::identifier }; struct JS::Parser::StackedSubexpression { - ExprNode::Kind kind; // The kind of BinaryExprNode the subexpression should generate - uchar precedence; // Precedence of an operator with respect to operators on its right - bool superRight; // True if the right operand can be super - uint32 pos; // The operator token's position - ExprNode *op1; // First operand of the operator - ExprNode *op2; // Second operand of the operator (used for ?: only) + ExprNode::Kind kind; // The kind of BinaryExprNode the subexpression should generate + uchar precedence; // Precedence of an operator with respect to operators on its right + bool superRight; // True if the right operand can be super + size_t pos; // The operator token's position + ExprNode *op1; // First operand of the operator + ExprNode *op2; // Second operand of the operator (used for ?: only) }; @@ -858,86 +858,86 @@ struct JS::Parser::StackedSubexpression { // set to false. JS::ExprNode *JS::Parser::parseGeneralExpression(bool allowSuperStmt, bool noIn, bool noAssignment, bool noComma) { - ArrayBuffer subexpressionStack; + ArrayBuffer subexpressionStack; - checkStackSize(); - // Push a limiter onto subexpressionStack. - subexpressionStack.reserve_advance_back()->precedence = pNone; + checkStackSize(); + // Push a limiter onto subexpressionStack. + subexpressionStack.reserve_advance_back()->precedence = pNone; - ExprNode *e = parseUnaryExpression(allowSuperStmt ? ssStmt : ssExpr); - if (e->hasKind(ExprNode::superStmt)) { - ASSERT(allowSuperStmt); - return e; - } - while (true) { - const Token &t = lexer.peek(false); - const BinaryOperatorInfo &binOpInfo = tokenBinaryOperatorInfos[t.getKind()]; - Precedence precedence = binOpInfo.precedenceLeft; - ExprNode::Kind kind = binOpInfo.kind; - ASSERT(precedence > pNone); + ExprNode *e = parseUnaryExpression(allowSuperStmt ? ssStmt : ssExpr); + if (e->hasKind(ExprNode::superStmt)) { + ASSERT(allowSuperStmt); + return e; + } + while (true) { + const Token &t = lexer.peek(false); + const BinaryOperatorInfo &binOpInfo = tokenBinaryOperatorInfos[t.getKind()]; + Precedence precedence = binOpInfo.precedenceLeft; + ExprNode::Kind kind = binOpInfo.kind; + ASSERT(precedence > pNone); - // Disqualify assignments, 'in', and comma if the flags indicate that these should end the expression. - if (precedence == pPostfix && noAssignment || kind == ExprNode::In && noIn || kind == ExprNode::comma && noComma) { - kind = ExprNode::none; - precedence = pExpression; - } - - if (precedence == pPostfix) { - // Ensure that the target of an assignment is a postfix subexpression or, where permitted, - // a super subexpression. - if (!(binOpInfo.superLeft && e->hasKind(ExprNode::superExpr))) - ensurePostfix(e); - } else - // Reduce already stacked operators with precedenceLeft or higher precedence - while (subexpressionStack.back().precedence >= precedence) { - StackedSubexpression &s = subexpressionStack.pop_back(); - if (e->hasKind(ExprNode::superExpr) && !s.superRight) - syntaxError("super expression not allowed here", 0); - if (s.kind == ExprNode::conditional) { - if (s.op2) - e = new(arena) TernaryExprNode(s.pos, s.kind, s.op1, s.op2, e); - else { - if (!t.hasKind(Token::colon)) - syntaxError("':' expected", 0); - lexer.get(false); - subexpressionStack.advance_back(); - s.op2 = e; - goto foundColon; - } - } else - e = new(arena) BinaryExprNode(s.pos, s.kind, s.op1, e); - } - - if (kind == ExprNode::none) - break; - - // Push the current operator onto the subexpressionStack. - lexer.get(false); - { - StackedSubexpression &s = *subexpressionStack.reserve_advance_back(); - bool superLeft = binOpInfo.superLeft; - if (e->hasKind(ExprNode::superExpr) && !superLeft) - syntaxError("super expression not allowed here", 1); - s.kind = kind; - s.precedence = binOpInfo.precedenceRight; - s.superRight = superLeft || s.kind == ExprNode::In; - s.pos = t.getPos(); - s.op1 = e; - s.op2 = 0; + // Disqualify assignments, 'in', and comma if the flags indicate that these should end the expression. + if (precedence == pPostfix && noAssignment || kind == ExprNode::In && noIn || kind == ExprNode::comma && noComma) { + kind = ExprNode::none; + precedence = pExpression; } - foundColon: - e = parseUnaryExpression(ssExpr); - } - ASSERT(subexpressionStack.size() == 1); - if (e->hasKind(ExprNode::superExpr)) - if (allowSuperStmt && static_cast(e)->op) { - // Convert the superExpr into a superStmt. - ExprPairList *arg = new(arena) ExprPairList(0, static_cast(e)->op); - e = new(arena) InvokeExprNode(e->pos, ExprNode::superStmt, 0, arg); - } else - syntaxError("super expression not allowed here", 0); - return e; + if (precedence == pPostfix) { + // Ensure that the target of an assignment is a postfix subexpression or, where permitted, + // a super subexpression. + if (!(binOpInfo.superLeft && e->hasKind(ExprNode::superExpr))) + ensurePostfix(e); + } else + // Reduce already stacked operators with precedenceLeft or higher precedence + while (subexpressionStack.back().precedence >= precedence) { + StackedSubexpression &s = subexpressionStack.pop_back(); + if (e->hasKind(ExprNode::superExpr) && !s.superRight) + syntaxError("super expression not allowed here", 0); + if (s.kind == ExprNode::conditional) { + if (s.op2) + e = new(arena) TernaryExprNode(s.pos, s.kind, s.op1, s.op2, e); + else { + if (!t.hasKind(Token::colon)) + syntaxError("':' expected", 0); + lexer.get(false); + subexpressionStack.advance_back(); + s.op2 = e; + goto foundColon; + } + } else + e = new(arena) BinaryExprNode(s.pos, s.kind, s.op1, e); + } + + if (kind == ExprNode::none) + break; + + // Push the current operator onto the subexpressionStack. + lexer.get(false); + { + StackedSubexpression &s = *subexpressionStack.reserve_advance_back(); + bool superLeft = binOpInfo.superLeft; + if (e->hasKind(ExprNode::superExpr) && !superLeft) + syntaxError("super expression not allowed here", 1); + s.kind = kind; + s.precedence = binOpInfo.precedenceRight; + s.superRight = superLeft || s.kind == ExprNode::In; + s.pos = t.getPos(); + s.op1 = e; + s.op2 = 0; + } + foundColon: + e = parseUnaryExpression(ssExpr); + } + + ASSERT(subexpressionStack.size() == 1); + if (e->hasKind(ExprNode::superExpr)) + if (allowSuperStmt && static_cast(e)->op) { + // Convert the superExpr into a superStmt. + ExprPairList *arg = new(arena) ExprPairList(0, static_cast(e)->op); + e = new(arena) InvokeExprNode(e->pos, ExprNode::superStmt, 0, arg); + } else + syntaxError("super expression not allowed here", 0); + return e; } @@ -946,10 +946,10 @@ JS::ExprNode *JS::Parser::parseGeneralExpression(bool allowSuperStmt, bool noIn, // been done with preferRegExp set to true. JS::ExprNode *JS::Parser::parseParenthesizedListExpression() { - require(true, Token::openParenthesis); - ExprNode *e = parseListExpression(false); - require(false, Token::closeParenthesis); - return e; + require(true, Token::openParenthesis); + ExprNode *e = parseListExpression(false); + require(false, Token::closeParenthesis); + return e; } @@ -959,12 +959,12 @@ JS::ExprNode *JS::Parser::parseParenthesizedListExpression() // After parseTypeExpression finishes, the next token might have been peeked with preferRegExp set to true. JS::ExprNode *JS::Parser::parseTypeExpression(bool noIn) { - ExprNode *type = parseNonAssignmentExpression(noIn); - if (lexer.peek(false).hasKind(Token::divideEquals)) - syntaxError("'/=' not allowed here", 0); - lexer.redesignate(true); // Safe: a '/' would have been interpreted as an operator, so it can't be the next - // token; a '/=' was outlawed by the check above. - return type; + ExprNode *type = parseNonAssignmentExpression(noIn); + if (lexer.peek(false).hasKind(Token::divideEquals)) + syntaxError("'/=' not allowed here", 0); + lexer.redesignate(true); // Safe: a '/' would have been interpreted as an operator, so it can't be the next + // token; a '/=' was outlawed by the check above. + return type; } @@ -974,15 +974,15 @@ JS::ExprNode *JS::Parser::parseTypeExpression(bool noIn) // with preferRegExp set to false. const JS::StringAtom &JS::Parser::parseTypedIdentifier(ExprNode *&type) { - const Token &t = lexer.get(true); - if (!t.hasIdentifierKind()) - syntaxError("Identifier expected"); - const StringAtom &name = t.getIdentifier(); + const Token &t = lexer.get(true); + if (!t.hasIdentifierKind()) + syntaxError("Identifier expected"); + const StringAtom &name = t.getIdentifier(); - type = 0; - if (lexer.eat(false, Token::colon)) - type = parseNonAssignmentExpression(false); - return name; + type = 0; + if (lexer.eat(false, Token::colon)) + type = parseNonAssignmentExpression(false); + return name; } @@ -994,10 +994,10 @@ const JS::StringAtom &JS::Parser::parseTypedIdentifier(ExprNode *&type) // After parseTypeBinding finishes, the next token might have been peeked with preferRegExp set to true. JS::ExprNode *JS::Parser::parseTypeBinding(Token::Kind kind, bool noIn) { - ExprNode *type = 0; - if (lexer.eat(true, kind)) - type = parseTypeExpression(noIn); - return type; + ExprNode *type = 0; + if (lexer.eat(true, kind)) + type = parseTypeExpression(noIn); + return type; } @@ -1008,11 +1008,11 @@ JS::ExprNode *JS::Parser::parseTypeBinding(Token::Kind kind, bool noIn) // After parseTypeListBinding finishes, the next token might have been peeked with preferRegExp set to true. JS::ExprList *JS::Parser::parseTypeListBinding(Token::Kind kind) { - NodeQueue types; - if (lexer.eat(true, kind)) - do types += new(arena) ExprList(parseTypeExpression(false)); - while (lexer.eat(true, Token::comma)); - return types.first; + NodeQueue types; + if (lexer.eat(true, kind)) + do types += new(arena) ExprList(parseTypeExpression(false)); + while (lexer.eat(true, Token::comma)); + return types.first; } @@ -1028,27 +1028,27 @@ JS::ExprList *JS::Parser::parseTypeListBinding(Token::Kind kind) // /regexp/ JS::VariableBinding *JS::Parser::parseVariableBinding(bool noQualifiers, bool noIn, bool constant) { - const Token &t = lexer.get(true); - uint32 pos = t.getPos(); + const Token &t = lexer.get(true); + size_t pos = t.getPos(); - ExprNode *name; - if (noQualifiers) { - name = makeIdentifierExpression(t); - if (!name) - syntaxError("Identifier expected"); - } else - name = parseQualifiedIdentifier(t, true); + ExprNode *name; + if (noQualifiers) { + name = makeIdentifierExpression(t); + if (!name) + syntaxError("Identifier expected"); + } else + name = parseQualifiedIdentifier(t, true); - ExprNode *type = parseTypeBinding(Token::colon, noIn); + ExprNode *type = parseTypeBinding(Token::colon, noIn); - ExprNode *initializer = 0; - if (lexer.eat(true, Token::assignment)) { - initializer = parseAssignmentExpression(noIn); - lexer.redesignate(true); // Safe: a '/' or a '/=' would have been interpreted as an operator, so - // it can't be the next token. - } + ExprNode *initializer = 0; + if (lexer.eat(true, Token::assignment)) { + initializer = parseAssignmentExpression(noIn); + lexer.redesignate(true); // Safe: a '/' or a '/=' would have been interpreted as an operator, so + // it can't be the next token. + } - return new(arena) VariableBinding(pos, name, type, initializer, constant); + return new(arena) VariableBinding(pos, name, type, initializer, constant); } @@ -1058,21 +1058,21 @@ JS::VariableBinding *JS::Parser::parseVariableBinding(bool noQualifiers, bool no // After parseFunctionName finishes, the next token might have been peeked with preferRegExp set to true. void JS::Parser::parseFunctionName(FunctionName &fn) { - fn.prefix = FunctionName::normal; - const Token *t = &lexer.get(true); - if (t->hasKind(Token::string)) { - fn.name = NodeFactory::LiteralString(t->getPos(),ExprNode::string,copyTokenChars(*t)); - } - else { - if (t->hasKind(Token::Get) || t->hasKind(Token::Set)) { - const Token *t2 = &lexer.peek(true); - if (!lineBreakBefore(*t2) && t2->getFlag(Token::canFollowGet)) { - fn.prefix = t->hasKind(Token::Get) ? FunctionName::Get : FunctionName::Set; - t = &lexer.get(true); - } - } - fn.name = parseQualifiedIdentifier(*t, true); - } + fn.prefix = FunctionName::normal; + const Token *t = &lexer.get(true); + if (t->hasKind(Token::string)) { + fn.name = NodeFactory::LiteralString(t->getPos(), ExprNode::string, copyTokenChars(*t)); + } + else { + if (t->hasKind(Token::Get) || t->hasKind(Token::Set)) { + const Token *t2 = &lexer.peek(true); + if (!lineBreakBefore(*t2) && t2->getFlag(Token::canFollowGet)) { + fn.prefix = t->hasKind(Token::Get) ? FunctionName::Get : FunctionName::Set; + t = &lexer.get(true); + } + } + fn.name = parseQualifiedIdentifier(*t, true); + } } @@ -1084,60 +1084,60 @@ void JS::Parser::parseFunctionName(FunctionName &fn) // peeked with preferRegExp set to true. void JS::Parser::parseFunctionSignature(FunctionDefinition &fd) { - require(true, Token::openParenthesis); + require(true, Token::openParenthesis); - NodeQueue parameters; - VariableBinding *optParameters = 0; - VariableBinding *namedParameters = 0; - VariableBinding *restParameter = 0; + NodeQueue parameters; + VariableBinding *optParameters = 0; + VariableBinding *namedParameters = 0; + VariableBinding *restParameter = 0; #ifdef NEW_PARSER - fd.optParameters = optParameters; - fd.namedParameters = namedParameters; - fd.restParameter = restParameter; + fd.optParameters = optParameters; + fd.namedParameters = namedParameters; + fd.restParameter = restParameter; #endif - if (!lexer.eat(true, Token::closeParenthesis)) { + if (!lexer.eat(true, Token::closeParenthesis)) { #ifdef NEW_PARSER - parseAllParameters(fd,parameters); - match(Token::closeParenthesis); + parseAllParameters(fd,parameters); + match(Token::closeParenthesis); #else - while (true) { - if (lexer.eat(true, Token::tripleDot)) { - const Token &t1 = lexer.peek(true); - if (t1.hasKind(Token::closeParenthesis)) - restParameter = new(arena) VariableBinding(t1.getPos(), 0, 0, 0, false); - else - restParameter = parseVariableBinding(true, false, lexer.eat(true, Token::Const) != 0); - if (!optParameters) - optParameters = restParameter; - parameters += restParameter; - require(true, Token::closeParenthesis); - break; - } else { - VariableBinding *b = parseVariableBinding(true, false, lexer.eat(true, Token::Const) != 0); - if (b->initializer) { - if (!optParameters) - optParameters = b; - } else - if (optParameters) - syntaxError("'=' expected", 0); - parameters += b; - const Token &t = lexer.get(true); - if (!t.hasKind(Token::comma)) - if (t.hasKind(Token::closeParenthesis)) - break; - else - syntaxError("',' or ')' expected"); - } - } + while (true) { + if (lexer.eat(true, Token::tripleDot)) { + const Token &t1 = lexer.peek(true); + if (t1.hasKind(Token::closeParenthesis)) + restParameter = new(arena) VariableBinding(t1.getPos(), 0, 0, 0, false); + else + restParameter = parseVariableBinding(true, false, lexer.eat(true, Token::Const) != 0); + if (!optParameters) + optParameters = restParameter; + parameters += restParameter; + require(true, Token::closeParenthesis); + break; + } else { + VariableBinding *b = parseVariableBinding(true, false, lexer.eat(true, Token::Const) != 0); + if (b->initializer) { + if (!optParameters) + optParameters = b; + } else + if (optParameters) + syntaxError("'=' expected", 0); + parameters += b; + const Token &t = lexer.get(true); + if (!t.hasKind(Token::comma)) + if (t.hasKind(Token::closeParenthesis)) + break; + else + syntaxError("',' or ')' expected"); + } + } #endif - } - fd.parameters = parameters.first; + } + fd.parameters = parameters.first; #ifndef NEW_PARSER - fd.optParameters = optParameters; - fd.restParameter = restParameter; - fd.resultType = parseTypeBinding(Token::colon, false); + fd.optParameters = optParameters; + fd.restParameter = restParameter; + fd.resultType = parseTypeBinding(Token::colon, false); #endif - fd.resultType = parseResultSignature(); + fd.resultType = parseResultSignature(); } @@ -1150,32 +1150,32 @@ void JS::Parser::parseFunctionSignature(FunctionDefinition &fd) // have been peeked with preferRegExp set to true. JS::StmtNode *JS::Parser::parseBlockContents(bool inSwitch, bool noCloseBrace) { - NodeQueue q; - SemicolonState semicolonState = semiNone; + NodeQueue q; + SemicolonState semicolonState = semiNone; - while (true) { - const Token *t = &lexer.peek(true); - if (t->hasKind(Token::semicolon) && semicolonState != semiNone) { - lexer.get(true); - semicolonState = semiNone; - t = &lexer.peek(true); - } - if (noCloseBrace) { - if (t->hasKind(Token::end)) - return q.first; - } else if (t->hasKind(Token::closeBrace)) { - lexer.get(true); - return q.first; - } - if (!(semicolonState == semiNone || - semicolonState == semiInsertable && lineBreakBefore(*t))) - syntaxError("';' expected", 0); + while (true) { + const Token *t = &lexer.peek(true); + if (t->hasKind(Token::semicolon) && semicolonState != semiNone) { + lexer.get(true); + semicolonState = semiNone; + t = &lexer.peek(true); + } + if (noCloseBrace) { + if (t->hasKind(Token::end)) + return q.first; + } else if (t->hasKind(Token::closeBrace)) { + lexer.get(true); + return q.first; + } + if (!(semicolonState == semiNone || + semicolonState == semiInsertable && lineBreakBefore(*t))) + syntaxError("';' expected", 0); - StmtNode *s = parseStatement(!inSwitch, inSwitch, semicolonState); - if (inSwitch && !q.first && !s->hasKind(StmtNode::Case)) - syntaxError("First statement in a switch block must be 'case expr:' or 'default:'", 0); - q += s; - } + StmtNode *s = parseStatement(!inSwitch, inSwitch, semicolonState); + if (inSwitch && !q.first && !s->hasKind(StmtNode::Case)) + syntaxError("First statement in a switch block must be 'case expr:' or 'default:'", 0); + q += s; + } } @@ -1188,16 +1188,16 @@ JS::StmtNode *JS::Parser::parseBlockContents(bool inSwitch, bool noCloseBrace) // After parseBody finishes, the next token might have been peeked with preferRegExp set to true. JS::BlockStmtNode *JS::Parser::parseBody(SemicolonState *semicolonState) { - const Token *tBrace = lexer.eat(true, Token::openBrace); - if (tBrace) { - uint32 pos = tBrace->getPos(); - return new(arena) BlockStmtNode(pos, StmtNode::block, 0, parseBlockContents(false, false)); - } else { - if (!semicolonState) - syntaxError("'{' expected", 0); - *semicolonState = semiInsertable; - return 0; - } + const Token *tBrace = lexer.eat(true, Token::openBrace); + if (tBrace) { + size_t pos = tBrace->getPos(); + return new(arena) BlockStmtNode(pos, StmtNode::block, 0, parseBlockContents(false, false)); + } else { + if (!semicolonState) + syntaxError("'{' expected", 0); + *semicolonState = semiInsertable; + return 0; + } } @@ -1206,130 +1206,129 @@ JS::BlockStmtNode *JS::Parser::parseBody(SemicolonState *semicolonState) // // If the statement ends with an optional semicolon, then that semicolon is not parsed. // Instead, parseAttributeStatement returns in semicolonState one of three values: -// semiNone: No semicolon is needed to close the statement -// semiNoninsertable: A NoninsertableSemicolon is needed to close the -// statement; a line break is not enough -// semiInsertable: A Semicolon is needed to close the statement; a -// line break is also sufficient +// semiNone: No semicolon is needed to close the statement +// semiNoninsertable: A NoninsertableSemicolon is needed to close the +// statement; a line break is not enough +// semiInsertable: A Semicolon is needed to close the statement; a +// line break is also sufficient // // pos is the position of the beginning of the statement (its first attribute if it has attributes). // The first token of the statement has already been read and is provided in t. // After parseAttributeStatement finishes, the next token might have been peeked with // preferRegExp set to true. -JS::StmtNode *JS::Parser::parseAttributeStatement(uint32 pos, ExprList *attributes, const Token &t, bool noIn, - SemicolonState &semicolonState) +JS::StmtNode *JS::Parser::parseAttributeStatement(size_t pos, ExprList *attributes, const Token &t, bool noIn, + SemicolonState &semicolonState) { - semicolonState = semiNone; - StmtNode::Kind sKind; + semicolonState = semiNone; + StmtNode::Kind sKind; - switch (t.getKind()) { - case Token::openBrace: - return new(arena) BlockStmtNode(pos, StmtNode::block, attributes, parseBlockContents(false, false)); + switch (t.getKind()) { + case Token::openBrace: + return new(arena) BlockStmtNode(pos, StmtNode::block, attributes, parseBlockContents(false, false)); - case Token::Const: - sKind = StmtNode::Const; - goto constOrVar; - case Token::Var: - sKind = StmtNode::Var; - constOrVar: - { - NodeQueue bindings; + case Token::Const: + sKind = StmtNode::Const; + goto constOrVar; + case Token::Var: + sKind = StmtNode::Var; + constOrVar: + { + NodeQueue bindings; - do bindings += parseVariableBinding(false, noIn, sKind == StmtNode::Const); - while (lexer.eat(true, Token::comma)); - semicolonState = semiInsertable; - return new(arena) VariableStmtNode(pos, sKind, attributes, bindings.first); - } + do bindings += parseVariableBinding(false, noIn, sKind == StmtNode::Const); + while (lexer.eat(true, Token::comma)); + semicolonState = semiInsertable; + return new(arena) VariableStmtNode(pos, sKind, attributes, bindings.first); + } - case Token::Function: - sKind = StmtNode::Function; - { - FunctionStmtNode *f = - new(arena) FunctionStmtNode(pos, sKind, attributes); - parseFunctionName(f->function); - parseFunctionSignature(f->function); - f->function.body = parseBody(&semicolonState); - return f; - } + case Token::Function: + sKind = StmtNode::Function; + { + FunctionStmtNode *f = new(arena) FunctionStmtNode(pos, sKind, attributes); + parseFunctionName(f->function); + parseFunctionSignature(f->function); + f->function.body = parseBody(&semicolonState); + return f; + } - case Token::Interface: - sKind = StmtNode::Interface; - goto classOrInterface; - case Token::Class: - sKind = StmtNode::Class; - classOrInterface: - { - ExprNode *name = parseQualifiedIdentifier(lexer.get(true), true); - ExprNode *superclass = 0; - if (sKind == StmtNode::Class) - superclass = parseTypeBinding(Token::Extends, false); - ExprList *superinterfaces = - parseTypeListBinding(sKind == StmtNode::Class ? Token::Implements : Token::Extends); - BlockStmtNode *body = - parseBody(superclass || superinterfaces ? 0 : &semicolonState); - return new(arena) ClassStmtNode(pos, sKind, attributes, name, superclass, superinterfaces, body); - } + case Token::Interface: + sKind = StmtNode::Interface; + goto classOrInterface; + case Token::Class: + sKind = StmtNode::Class; + classOrInterface: + { + ExprNode *name = parseQualifiedIdentifier(lexer.get(true), true); + ExprNode *superclass = 0; + if (sKind == StmtNode::Class) + superclass = parseTypeBinding(Token::Extends, false); + ExprList *superinterfaces = + parseTypeListBinding(sKind == StmtNode::Class ? Token::Implements : Token::Extends); + BlockStmtNode *body = + parseBody(superclass || superinterfaces ? 0 : &semicolonState); + return new(arena) ClassStmtNode(pos, sKind, attributes, name, superclass, superinterfaces, body); + } - case Token::Namespace: - { - const Token &t2 = lexer.get(false); - ExprNode *name; - if (lineBreakBefore(t2) || !(name = makeIdentifierExpression(t2))) - syntaxError("Namespace name expected"); - ExprList *supernamespaces = - parseTypeListBinding(Token::Extends); - semicolonState = semiInsertable; - return new(arena) NamespaceStmtNode(pos, StmtNode::Namespace, attributes, name, supernamespaces); - } + case Token::Namespace: + { + const Token &t2 = lexer.get(false); + ExprNode *name; + if (lineBreakBefore(t2) || !(name = makeIdentifierExpression(t2))) + syntaxError("Namespace name expected"); + ExprList *supernamespaces = + parseTypeListBinding(Token::Extends); + semicolonState = semiInsertable; + return new(arena) NamespaceStmtNode(pos, StmtNode::Namespace, attributes, name, supernamespaces); + } - default: - syntaxError("Bad declaration"); - return 0; - } + default: + syntaxError("Bad declaration"); + return 0; + } } // Parse and return a statement that takes initial attributes. // semicolonState behaves as in parseAttributeStatement. // as restricts the kinds of statements that are allowed after the attributes: -// asAny Any statements that takes attributes can follow -// asBlock Only a block can follow -// asConstVar Only a const or var declaration can follow, and the 'in' -// operator is not allowed at its top level +// asAny Any statements that takes attributes can follow +// asBlock Only a block can follow +// asConstVar Only a const or var declaration can follow, and the 'in' +// operator is not allowed at its top level // // The first attribute has already been read and is provided in e. // pos is the position of the first attribute. // If the next token was peeked, it should be have been done with preferRegExp set to true. // After parseAttributesAndStatement finishes, the next token might have been peeked with // preferRegExp set to true. -JS::StmtNode *JS::Parser::parseAttributesAndStatement(uint32 pos, ExprNode *e, AttributeStatement as, SemicolonState &semicolonState) +JS::StmtNode *JS::Parser::parseAttributesAndStatement(size_t pos, ExprNode *e, AttributeStatement as, SemicolonState &semicolonState) { - NodeQueue attributes; - while (true) { - attributes += new(arena) ExprList(e); - const Token &t = lexer.get(true); - if (lineBreakBefore(t)) - syntaxError("Line break not allowed here"); + NodeQueue attributes; + while (true) { + attributes += new(arena) ExprList(e); + const Token &t = lexer.get(true); + if (lineBreakBefore(t)) + syntaxError("Line break not allowed here"); - if (!t.getFlag(Token::isAttribute)) { - switch (as) { - case asAny: - break; + if (!t.getFlag(Token::isAttribute)) { + switch (as) { + case asAny: + break; - case asBlock: // ***** This is dead code. - if (!t.hasKind(Token::openBrace)) - syntaxError("'{' expected"); - break; + case asBlock: // ***** This is dead code. + if (!t.hasKind(Token::openBrace)) + syntaxError("'{' expected"); + break; - case asConstVar: - if (!t.hasKind(Token::Const) && !t.hasKind(Token::Var)) - syntaxError("const or var expected"); - break; - } - return parseAttributeStatement(pos, attributes.first, t, as == asConstVar, semicolonState); - } - e = parseAttribute(t); - } + case asConstVar: + if (!t.hasKind(Token::Const) && !t.hasKind(Token::Var)) + syntaxError("const or var expected"); + break; + } + return parseAttributeStatement(pos, attributes.first, t, as == asConstVar, semicolonState); + } + e = parseAttribute(t); + } } @@ -1340,106 +1339,106 @@ JS::StmtNode *JS::Parser::parseAttributesAndStatement(uint32 pos, ExprNode *e, A // // After parseFor finishes, the next token might have been peeked with // preferRegExp set to true. -JS::StmtNode *JS::Parser::parseFor(uint32 pos, SemicolonState &semicolonState) +JS::StmtNode *JS::Parser::parseFor(size_t pos, SemicolonState &semicolonState) { - require(true, Token::openParenthesis); - const Token &t = lexer.get(true); - uint32 tPos = t.getPos(); - StmtNode *initializer = 0; - ExprNode *expr1 = 0; - ExprNode *expr2 = 0; - ExprNode *expr3 = 0; - StmtNode::Kind sKind = StmtNode::For; + require(true, Token::openParenthesis); + const Token &t = lexer.get(true); + size_t tPos = t.getPos(); + StmtNode *initializer = 0; + ExprNode *expr1 = 0; + ExprNode *expr2 = 0; + ExprNode *expr3 = 0; + StmtNode::Kind sKind = StmtNode::For; - switch (t.getKind()) { - case Token::semicolon: - goto threeExpr; + switch (t.getKind()) { + case Token::semicolon: + goto threeExpr; - case Token::Const: - case Token::Var: - initializer = parseAttributeStatement(tPos, 0, t, true, semicolonState); - break; + case Token::Const: + case Token::Var: + initializer = parseAttributeStatement(tPos, 0, t, true, semicolonState); + break; - case Token::Abstract: - case Token::Final: - case Token::Static: - case Token::Volatile: - expr1 = new(arena) IdentifierExprNode(t); - makeAttribute: - initializer = parseAttributesAndStatement(tPos, expr1, asConstVar, semicolonState); - expr1 = 0; - break; + case Token::Abstract: + case Token::Final: + case Token::Static: + case Token::Volatile: + expr1 = new(arena) IdentifierExprNode(t); + makeAttribute: + initializer = parseAttributesAndStatement(tPos, expr1, asConstVar, semicolonState); + expr1 = 0; + break; - default: - lexer.unget(); - expr1 = parseListExpression(true); - lexer.redesignate(true); // Safe: a '/' or a '/=' would have been interpreted as an operator, - // so it can't be the next token. - if (expressionIsAttribute(expr1)) { - const Token &t2 = lexer.peek(true); - if (!lineBreakBefore(t2) && t2.getFlag(Token::canFollowAttribute)) - goto makeAttribute; - } - initializer = new(arena) ExprStmtNode(tPos, StmtNode::expression, expr1); - break; - } + default: + lexer.unget(); + expr1 = parseListExpression(true); + lexer.redesignate(true); // Safe: a '/' or a '/=' would have been interpreted as an operator, + // so it can't be the next token. + if (expressionIsAttribute(expr1)) { + const Token &t2 = lexer.peek(true); + if (!lineBreakBefore(t2) && t2.getFlag(Token::canFollowAttribute)) + goto makeAttribute; + } + initializer = new(arena) ExprStmtNode(tPos, StmtNode::expression, expr1); + break; + } - if (lexer.eat(true, Token::semicolon)) - threeExpr: { - if (!lexer.eat(true, Token::semicolon)) { - expr2 = parseListExpression(false); - require(false, Token::semicolon); - } - if (lexer.peek(true).hasKind(Token::closeParenthesis)) - lexer.redesignate(false); // Safe: the token is ')'. - else - expr3 = parseListExpression(false); - } - else if (lexer.eat(true, Token::In)) { - sKind = StmtNode::ForIn; - if (expr1) { - ASSERT(initializer->hasKind(StmtNode::expression)); - ensurePostfix(expr1); - } else { - ASSERT(initializer->hasKind(StmtNode::Const) || initializer->hasKind(StmtNode::Var)); - const VariableBinding *bindings = static_cast(initializer)->bindings; - if (!bindings || bindings->next) - syntaxError("Only one variable binding can be used in a for-in statement", 0); - } - expr2 = parseListExpression(false); - } - else - syntaxError("';' or 'in' expected", 0); + if (lexer.eat(true, Token::semicolon)) + threeExpr: { + if (!lexer.eat(true, Token::semicolon)) { + expr2 = parseListExpression(false); + require(false, Token::semicolon); + } + if (lexer.peek(true).hasKind(Token::closeParenthesis)) + lexer.redesignate(false); // Safe: the token is ')'. + else + expr3 = parseListExpression(false); + } + else if (lexer.eat(true, Token::In)) { + sKind = StmtNode::ForIn; + if (expr1) { + ASSERT(initializer->hasKind(StmtNode::expression)); + ensurePostfix(expr1); + } else { + ASSERT(initializer->hasKind(StmtNode::Const) || initializer->hasKind(StmtNode::Var)); + const VariableBinding *bindings = static_cast(initializer)->bindings; + if (!bindings || bindings->next) + syntaxError("Only one variable binding can be used in a for-in statement", 0); + } + expr2 = parseListExpression(false); + } + else + syntaxError("';' or 'in' expected", 0); - require(false, Token::closeParenthesis); - return new(arena) ForStmtNode(pos, sKind, initializer, expr2, expr3, parseStatement(false, false, semicolonState)); + require(false, Token::closeParenthesis); + return new(arena) ForStmtNode(pos, sKind, initializer, expr2, expr3, parseStatement(false, false, semicolonState)); } // Parse and return a TryStatement. The 'try' token has already been read; // its position is pos. After parseTry finishes, the next token might have // been peeked with preferRegExp set to true. -JS::StmtNode *JS::Parser::parseTry(uint32 pos) +JS::StmtNode *JS::Parser::parseTry(size_t pos) { - StmtNode *tryBlock = parseBody(0); - NodeQueue catches; - const Token *t; + StmtNode *tryBlock = parseBody(0); + NodeQueue catches; + const Token *t; - while ((t = lexer.eat(true, Token::Catch)) != 0) { - uint32 catchPos = t->getPos(); - require(true, Token::openParenthesis); - ExprNode *type; - const StringAtom &name = parseTypedIdentifier(type); - require(false, Token::closeParenthesis); - catches += new(arena) CatchClause(catchPos, name, type, parseBody(0)); - } - StmtNode *finally = 0; - if (lexer.eat(true, Token::Finally)) - finally = parseBody(0); - else if (!catches.first) - syntaxError("A try statement must be followed by at least one catch or finally", 0); + while ((t = lexer.eat(true, Token::Catch)) != 0) { + size_t catchPos = t->getPos(); + require(true, Token::openParenthesis); + ExprNode *type; + const StringAtom &name = parseTypedIdentifier(type); + require(false, Token::closeParenthesis); + catches += new(arena) CatchClause(catchPos, name, type, parseBody(0)); + } + StmtNode *finally = 0; + if (lexer.eat(true, Token::Finally)) + finally = parseBody(0); + else if (!catches.first) + syntaxError("A try statement must be followed by at least one catch or finally", 0); - return new(arena) TryStmtNode(pos, tryBlock, catches.first, finally); + return new(arena) TryStmtNode(pos, tryBlock, catches.first, finally); } @@ -1449,192 +1448,192 @@ JS::StmtNode *JS::Parser::parseTry(uint32 pos) // If the statement ends with an optional semicolon, that semicolon is not // parsed. // Instead, parseStatement returns in semicolonState one of three values: -// semiNone: No semicolon is needed to close the statement -// semiNoninsertable: A NoninsertableSemicolon is needed to close the -// statement; a line break is not enough -// semiInsertable: A Semicolon is needed to close the statement; a -// line break is also sufficient +// semiNone: No semicolon is needed to close the statement +// semiNoninsertable: A NoninsertableSemicolon is needed to close the +// statement; a line break is not enough +// semiInsertable: A Semicolon is needed to close the statement; a +// line break is also sufficient // // If the first token was peeked, it should be have been done with preferRegExp set to true. // After parseStatement finishes, the next token might have been peeked with preferRegExp set to true. JS::StmtNode *JS::Parser::parseStatement(bool /*directive*/, bool inSwitch, SemicolonState &semicolonState) { - StmtNode *s; - ExprNode *e = 0; - StmtNode::Kind sKind; - const Token &t = lexer.get(true); - const Token *t2; - uint32 pos = t.getPos(); - semicolonState = semiNone; + StmtNode *s; + ExprNode *e = 0; + StmtNode::Kind sKind; + const Token &t = lexer.get(true); + const Token *t2; + size_t pos = t.getPos(); + semicolonState = semiNone; - checkStackSize(); - switch (t.getKind()) { - case Token::semicolon: - s = new(arena) StmtNode(pos, StmtNode::empty); - break; + checkStackSize(); + switch (t.getKind()) { + case Token::semicolon: + s = new(arena) StmtNode(pos, StmtNode::empty); + break; - case Token::openBrace: - case Token::Const: - case Token::Var: - case Token::Function: - case Token::Class: - case Token::Interface: - case Token::Namespace: - s = parseAttributeStatement(pos, 0, t, false, semicolonState); - break; + case Token::openBrace: + case Token::Const: + case Token::Var: + case Token::Function: + case Token::Class: + case Token::Interface: + case Token::Namespace: + s = parseAttributeStatement(pos, 0, t, false, semicolonState); + break; - case Token::If: - e = parseParenthesizedListExpression(); - s = parseStatementAndSemicolon(semicolonState); - if (lexer.eat(true, Token::Else)) - s = new(arena) BinaryStmtNode(pos, StmtNode::IfElse, e, s, parseStatement(false, false, semicolonState)); - else { - sKind = StmtNode::If; - goto makeUnary; - } - break; + case Token::If: + e = parseParenthesizedListExpression(); + s = parseStatementAndSemicolon(semicolonState); + if (lexer.eat(true, Token::Else)) + s = new(arena) BinaryStmtNode(pos, StmtNode::IfElse, e, s, parseStatement(false, false, semicolonState)); + else { + sKind = StmtNode::If; + goto makeUnary; + } + break; - case Token::Switch: - e = parseParenthesizedListExpression(); - require(true, Token::openBrace); - s = new(arena) SwitchStmtNode(pos, e, parseBlockContents(true, false)); - break; + case Token::Switch: + e = parseParenthesizedListExpression(); + require(true, Token::openBrace); + s = new(arena) SwitchStmtNode(pos, e, parseBlockContents(true, false)); + break; - case Token::Case: - if (!inSwitch) - goto notInSwitch; - e = parseListExpression(false); - makeSwitchCase: - require(false, Token::colon); - s = new(arena) ExprStmtNode(pos, StmtNode::Case, e); - break; + case Token::Case: + if (!inSwitch) + goto notInSwitch; + e = parseListExpression(false); + makeSwitchCase: + require(false, Token::colon); + s = new(arena) ExprStmtNode(pos, StmtNode::Case, e); + break; - case Token::Default: - if (inSwitch) - goto makeSwitchCase; - notInSwitch: - syntaxError("case and default may only be used inside a switch statement"); - break; + case Token::Default: + if (inSwitch) + goto makeSwitchCase; + notInSwitch: + syntaxError("case and default may only be used inside a switch statement"); + break; - case Token::Do: - { - SemicolonState semiState2; // Ignore semiState2. - s = parseStatementAndSemicolon(semiState2); - require(true, Token::While); - e = parseParenthesizedListExpression(); - sKind = StmtNode::DoWhile; - goto makeUnary; - } - break; + case Token::Do: + { + SemicolonState semiState2; // Ignore semiState2. + s = parseStatementAndSemicolon(semiState2); + require(true, Token::While); + e = parseParenthesizedListExpression(); + sKind = StmtNode::DoWhile; + goto makeUnary; + } + break; - case Token::With: - sKind = StmtNode::With; - goto makeWhileWith; + case Token::With: + sKind = StmtNode::With; + goto makeWhileWith; - case Token::While: - sKind = StmtNode::While; - makeWhileWith: - e = parseParenthesizedListExpression(); - s = parseStatement(false, false, semicolonState); - makeUnary: - s = new(arena) UnaryStmtNode(pos, sKind, e, s); - break; + case Token::While: + sKind = StmtNode::While; + makeWhileWith: + e = parseParenthesizedListExpression(); + s = parseStatement(false, false, semicolonState); + makeUnary: + s = new(arena) UnaryStmtNode(pos, sKind, e, s); + break; - case Token::For: - s = parseFor(pos, semicolonState); - break; + case Token::For: + s = parseFor(pos, semicolonState); + break; - case Token::Continue: - sKind = StmtNode::Continue; - goto makeGo; + case Token::Continue: + sKind = StmtNode::Continue; + goto makeGo; - case Token::Break: - sKind = StmtNode::Break; - makeGo: - { - const StringAtom *label = 0; - t2 = &lexer.peek(true); - if (t2->hasKind(Token::identifier) && !lineBreakBefore(*t2)) { - lexer.get(true); - label = &t2->getIdentifier(); - } - s = new(arena) GoStmtNode(pos, sKind, label); - } - goto insertableSemicolon; + case Token::Break: + sKind = StmtNode::Break; + makeGo: + { + const StringAtom *label = 0; + t2 = &lexer.peek(true); + if (t2->hasKind(Token::identifier) && !lineBreakBefore(*t2)) { + lexer.get(true); + label = &t2->getIdentifier(); + } + s = new(arena) GoStmtNode(pos, sKind, label); + } + goto insertableSemicolon; - case Token::Return: - sKind = StmtNode::Return; - t2 = &lexer.peek(true); - if (lineBreakBefore(*t2) || t2->getFlag(Token::canFollowReturn)) - goto makeExprStmtNode; - makeExpressionNode: - e = parseListExpression(false); - // Safe: a '/' or a '/=' would have been interpreted as an - // operator, so it can't be the next token. - lexer.redesignate(true); - goto makeExprStmtNode; + case Token::Return: + sKind = StmtNode::Return; + t2 = &lexer.peek(true); + if (lineBreakBefore(*t2) || t2->getFlag(Token::canFollowReturn)) + goto makeExprStmtNode; + makeExpressionNode: + e = parseListExpression(false); + // Safe: a '/' or a '/=' would have been interpreted as an + // operator, so it can't be the next token. + lexer.redesignate(true); + goto makeExprStmtNode; - case Token::Throw: - sKind = StmtNode::Throw; - if (lineBreakBefore()) - syntaxError("throw cannot be followed by a line break", 0); - goto makeExpressionNode; + case Token::Throw: + sKind = StmtNode::Throw; + if (lineBreakBefore()) + syntaxError("throw cannot be followed by a line break", 0); + goto makeExpressionNode; - case Token::Try: - s = parseTry(pos); - break; + case Token::Try: + s = parseTry(pos); + break; - case Token::Debugger: - s = new(arena) DebuggerStmtNode(pos, StmtNode::Debugger); - break; + case Token::Debugger: + s = new(arena) DebuggerStmtNode(pos, StmtNode::Debugger); + break; - case Token::Abstract: - case Token::Final: - case Token::Static: - case Token::Volatile: - e = new(arena) IdentifierExprNode(t); - makeAttribute: - s = parseAttributesAndStatement(pos, e, asAny, semicolonState); - break; + case Token::Abstract: + case Token::Final: + case Token::Static: + case Token::Volatile: + e = new(arena) IdentifierExprNode(t); + makeAttribute: + s = parseAttributesAndStatement(pos, e, asAny, semicolonState); + break; - case CASE_TOKEN_NONRESERVED: - t2 = &lexer.peek(false); - if (t2->hasKind(Token::colon)) { - lexer.get(false); - // Must do this now because parseStatement can invalidate t. - const StringAtom &name = t.getIdentifier(); - s = new(arena) LabelStmtNode(pos, name, parseStatement(false, false, semicolonState)); - break; - } - default: - lexer.unget(); - e = parseGeneralExpression(true, false, false, false); - // Safe: a '/' or a '/=' would have been interpreted as an - // operator, so it can't be the next token. - lexer.redesignate(true); - if (expressionIsAttribute(e)) { - t2 = &lexer.peek(true); - if (!lineBreakBefore(*t2) && t2->getFlag(Token::canFollowAttribute)) - goto makeAttribute; - } - sKind = StmtNode::expression; - makeExprStmtNode: - s = new(arena) ExprStmtNode(pos, sKind, e); - insertableSemicolon: - semicolonState = semiInsertable; - break; - } - return s; + case CASE_TOKEN_NONRESERVED: + t2 = &lexer.peek(false); + if (t2->hasKind(Token::colon)) { + lexer.get(false); + // Must do this now because parseStatement can invalidate t. + const StringAtom &name = t.getIdentifier(); + s = new(arena) LabelStmtNode(pos, name, parseStatement(false, false, semicolonState)); + break; + } + default: + lexer.unget(); + e = parseGeneralExpression(true, false, false, false); + // Safe: a '/' or a '/=' would have been interpreted as an + // operator, so it can't be the next token. + lexer.redesignate(true); + if (expressionIsAttribute(e)) { + t2 = &lexer.peek(true); + if (!lineBreakBefore(*t2) && t2->getFlag(Token::canFollowAttribute)) + goto makeAttribute; + } + sKind = StmtNode::expression; + makeExprStmtNode: + s = new(arena) ExprStmtNode(pos, sKind, e); + insertableSemicolon: + semicolonState = semiInsertable; + break; + } + return s; } // Same as parseStatement but also swallow the following semicolon if one is present. JS::StmtNode *JS::Parser::parseStatementAndSemicolon(SemicolonState &semicolonState) { - StmtNode *s = parseStatement(false, false, semicolonState); - if (semicolonState != semiNone && lexer.eat(true, Token::semicolon)) - semicolonState = semiNone; - return s; + StmtNode *s = parseStatement(false, false, semicolonState); + if (semicolonState != semiNone && lexer.eat(true, Token::semicolon)) + semicolonState = semiNone; + return s; } @@ -1642,359 +1641,359 @@ JS::StmtNode *JS::Parser::parseStatementAndSemicolon(SemicolonState &semicolonSt bool JS::Parser::lookahead(Token::Kind kind, bool preferRegExp) { - const Token &t = lexer.peek(preferRegExp); - if (t.getKind() != kind) - return false; - return true; + const Token &t = lexer.peek(preferRegExp); + if (t.getKind() != kind) + return false; + return true; } const JS::Token *JS::Parser::match(Token::Kind kind, bool preferRegExp) { - const Token *t = lexer.eat(preferRegExp,kind); - if (!t || t->getKind() != kind) - return 0; - return t; + const Token *t = lexer.eat(preferRegExp,kind); + if (!t || t->getKind() != kind) + return 0; + return t; } /** * LiteralField -* FieldName : AssignmentExpressionallowIn +* FieldName : AssignmentExpressionallowIn */ JS::ExprPairList *JS::Parser::parseLiteralField() { - ExprPairList *result=NULL; - ExprNode *first; - ExprNode *second; + ExprPairList *result=NULL; + ExprNode *first; + ExprNode *second; - first = parseFieldName(); - match(Token::colon); - second = parseAssignmentExpression(false); - lexer.redesignate(true); // Safe: looking for non-slash punctuation. - result = NodeFactory::LiteralField(first,second); + first = parseFieldName(); + match(Token::colon); + second = parseAssignmentExpression(false); + lexer.redesignate(true); // Safe: looking for non-slash punctuation. + result = NodeFactory::LiteralField(first,second); - return result; + return result; } /** * FieldName -* Identifier -* String -* Number -* ParenthesizedExpression +* Identifier +* String +* Number +* ParenthesizedExpression */ JS::ExprNode *JS::Parser::parseFieldName() { - ExprNode *result; + ExprNode *result; - if( lookahead(Token::string) ) { - const Token *t = match(Token::string); - result = NodeFactory::LiteralString(t->getPos(), ExprNode::string, copyTokenChars(*t)); - } else if(lookahead(Token::number)) { - const Token *t = match(Token::number); - result = NodeFactory::LiteralNumber(*t); - } else if( lookahead(Token::openParenthesis) ) { - result = parseParenthesizedListExpression(); - } else { - result = parseIdentifier(); - } + if( lookahead(Token::string) ) { + const Token *t = match(Token::string); + result = NodeFactory::LiteralString(t->getPos(), ExprNode::string, copyTokenChars(*t)); + } else if(lookahead(Token::number)) { + const Token *t = match(Token::number); + result = NodeFactory::LiteralNumber(*t); + } else if( lookahead(Token::openParenthesis) ) { + result = parseParenthesizedListExpression(); + } else { + result = parseIdentifier(); + } - return result; + return result; } /** * AllParameters -* Parameter -* Parameter , AllParameters -* Parameter OptionalParameterPrime -* Parameter OptionalParameterPrime , OptionalNamedRestParameters -* | NamedRestParameters -* RestParameter -* RestParameter , | NamedParameters +* Parameter +* Parameter , AllParameters +* Parameter OptionalParameterPrime +* Parameter OptionalParameterPrime , OptionalNamedRestParameters +* | NamedRestParameters +* RestParameter +* RestParameter , | NamedParameters */ JS::VariableBinding *JS::Parser::parseAllParameters(FunctionDefinition &fd, NodeQueue ¶ms) { - VariableBinding *result; + VariableBinding *result; - if(lookahead(Token::tripleDot)) { - fd.restParameter = parseRestParameter(); - params += fd.restParameter; - if( lookahead(Token::comma) ) { - match(Token::comma); - match(Token::bitwiseOr); - result = parseNamedParameters(fd,params); - } else { - result = params.first; - } - } else if( lookahead(Token::bitwiseOr) ) { - match(Token::bitwiseOr); - result = parseNamedRestParameters(fd,params); - } else { - VariableBinding *first; - first = parseParameter(); - if( lookahead(Token::comma) ) { - params += first; - match(Token::comma); - result = parseAllParameters(fd,params); - } else if( lookahead(Token::assignment) ) { - first = parseOptionalParameterPrime(first); - if (!fd.optParameters) { - fd.optParameters = first; - } - params += first; - if( lookahead(Token::comma) ) { - match(Token::comma); - result = parseOptionalNamedRestParameters(fd,params); - } - } else { - params += first; - result = params.first; - } - } + if(lookahead(Token::tripleDot)) { + fd.restParameter = parseRestParameter(); + params += fd.restParameter; + if( lookahead(Token::comma) ) { + match(Token::comma); + match(Token::bitwiseOr); + result = parseNamedParameters(fd,params); + } else { + result = params.first; + } + } else if( lookahead(Token::bitwiseOr) ) { + match(Token::bitwiseOr); + result = parseNamedRestParameters(fd,params); + } else { + VariableBinding *first; + first = parseParameter(); + if( lookahead(Token::comma) ) { + params += first; + match(Token::comma); + result = parseAllParameters(fd,params); + } else if( lookahead(Token::assignment) ) { + first = parseOptionalParameterPrime(first); + if (!fd.optParameters) { + fd.optParameters = first; + } + params += first; + if( lookahead(Token::comma) ) { + match(Token::comma); + result = parseOptionalNamedRestParameters(fd,params); + } + } else { + params += first; + result = params.first; + } + } - return result; + return result; } /** * OptionalNamedRestParameters -* OptionalParameter -* OptionalParameter , OptionalNamedRestParameters -* | NamedRestParameters -* RestParameter -* RestParameter , | NamedParameters +* OptionalParameter +* OptionalParameter , OptionalNamedRestParameters +* | NamedRestParameters +* RestParameter +* RestParameter , | NamedParameters */ JS::VariableBinding *JS::Parser::parseOptionalNamedRestParameters (FunctionDefinition &fd, NodeQueue ¶ms) { - VariableBinding *result; + VariableBinding *result; - if( lookahead(Token::tripleDot) ) { - fd.restParameter = parseRestParameter(); - params += fd.restParameter; - if( lookahead(Token::comma) ) { - match(Token::comma); - match(Token::bitwiseOr); - result = parseNamedParameters(fd,params); - } else { - result = params.first; - } - } else if( lookahead(Token::bitwiseOr) ) { - match(Token::bitwiseOr); - result = parseNamedRestParameters(fd,params); - } else { - VariableBinding *first; - first = parseOptionalParameter(); - if (!fd.optParameters) { - fd.optParameters = first; - } - params += first; - if( lookahead(Token::comma) ) { - match(Token::comma); - result = parseOptionalNamedRestParameters(fd,params); - } else { - result = params.first; - } - } + if( lookahead(Token::tripleDot) ) { + fd.restParameter = parseRestParameter(); + params += fd.restParameter; + if( lookahead(Token::comma) ) { + match(Token::comma); + match(Token::bitwiseOr); + result = parseNamedParameters(fd,params); + } else { + result = params.first; + } + } else if( lookahead(Token::bitwiseOr) ) { + match(Token::bitwiseOr); + result = parseNamedRestParameters(fd,params); + } else { + VariableBinding *first; + first = parseOptionalParameter(); + if (!fd.optParameters) { + fd.optParameters = first; + } + params += first; + if( lookahead(Token::comma) ) { + match(Token::comma); + result = parseOptionalNamedRestParameters(fd,params); + } else { + result = params.first; + } + } - return result; + return result; } /** * NamedRestParameters -* NamedParameter -* NamedParameter , NamedRestParameters -* RestParameter +* NamedParameter +* NamedParameter , NamedRestParameters +* RestParameter */ JS::VariableBinding *JS::Parser::parseNamedRestParameters(FunctionDefinition &fd, NodeQueue ¶ms) { - VariableBinding *result; + VariableBinding *result; - if (lookahead(Token::tripleDot)) { - fd.restParameter = parseRestParameter(); - params += fd.restParameter; - result = params.first; - } else { - NodeQueue aliases; - VariableBinding *first; - first = parseNamedParameter(aliases); - // The following marks the position in the list that named - // parameters may occur. It is not required that this - // particular parameter has - // aliases associated with it. - if (!fd.namedParameters) { - fd.namedParameters = first; - } - if (!fd.optParameters && first->initializer) { - fd.optParameters = first; - } - if( lookahead(Token::comma) ) { - params += first; - match(Token::comma); - result = parseNamedRestParameters(fd,params); - } else { - params += first; - result = params.first; - } - } + if (lookahead(Token::tripleDot)) { + fd.restParameter = parseRestParameter(); + params += fd.restParameter; + result = params.first; + } else { + NodeQueue aliases; + VariableBinding *first; + first = parseNamedParameter(aliases); + // The following marks the position in the list that named + // parameters may occur. It is not required that this + // particular parameter has + // aliases associated with it. + if (!fd.namedParameters) { + fd.namedParameters = first; + } + if (!fd.optParameters && first->initializer) { + fd.optParameters = first; + } + if( lookahead(Token::comma) ) { + params += first; + match(Token::comma); + result = parseNamedRestParameters(fd,params); + } else { + params += first; + result = params.first; + } + } - return result; + return result; } /** * NamedParameters -* NamedParameter -* NamedParameter , NamedParameters +* NamedParameter +* NamedParameter , NamedParameters */ JS::VariableBinding *JS::Parser::parseNamedParameters(FunctionDefinition &fd, NodeQueue ¶ms) { - VariableBinding *result,*first; - NodeQueue aliases; // List of aliases. - first = parseNamedParameter(aliases); - // The following marks the position in the list that named parameters - // may occur. It is not required that this particular parameter has - // aliases associated with it. - if (!fd.namedParameters) { - fd.namedParameters = first; - } - if (!fd.optParameters && first->initializer) { - fd.optParameters = first; - } - if (lookahead(Token::comma)) { - params += first; - match(Token::comma); - result = parseNamedParameters(fd,params); - } else { - params += first; - result = params.first; - } + VariableBinding *result,*first; + NodeQueue aliases; // List of aliases. + first = parseNamedParameter(aliases); + // The following marks the position in the list that named parameters + // may occur. It is not required that this particular parameter has + // aliases associated with it. + if (!fd.namedParameters) { + fd.namedParameters = first; + } + if (!fd.optParameters && first->initializer) { + fd.optParameters = first; + } + if (lookahead(Token::comma)) { + params += first; + match(Token::comma); + result = parseNamedParameters(fd,params); + } else { + params += first; + result = params.first; + } - return result; + return result; } /** * RestParameter -* ... -* ... Parameter +* ... +* ... Parameter */ JS::VariableBinding *JS::Parser::parseRestParameter() { - VariableBinding *result; + VariableBinding *result; - match(Token::tripleDot); - if (lookahead(Token::closeParenthesis) || - lookahead(Token::comma)) { - result = NodeFactory::Parameter(0, 0, false); - } else { - result = parseParameter(); - } + match(Token::tripleDot); + if (lookahead(Token::closeParenthesis) || + lookahead(Token::comma)) { + result = NodeFactory::Parameter(0, 0, false); + } else { + result = parseParameter(); + } - return result; + return result; } /** * Parameter -* Identifier -* Identifier : TypeExpression[allowIn] +* Identifier +* Identifier : TypeExpression[allowIn] */ JS::VariableBinding *JS::Parser::parseParameter() { - bool constant = lexer.eat(true, Token::Const) != 0; - ExprNode *first = parseIdentifier(); - ExprNode *second = parseTypeBinding (Token::colon, false); + bool constant = lexer.eat(true, Token::Const) != 0; + ExprNode *first = parseIdentifier(); + ExprNode *second = parseTypeBinding (Token::colon, false); - return NodeFactory::Parameter(first, second, constant); + return NodeFactory::Parameter(first, second, constant); } /** * OptionalParameter -* Parameter = AssignmentExpression[allowIn] +* Parameter = AssignmentExpression[allowIn] */ JS::VariableBinding *JS::Parser::parseOptionalParameter() { - VariableBinding *result,*first; + VariableBinding *result,*first; - first = parseParameter(); - result = parseOptionalParameterPrime(first); + first = parseParameter(); + result = parseOptionalParameterPrime(first); - return result; + return result; } JS::VariableBinding *JS::Parser::parseOptionalParameterPrime(VariableBinding *first) { - VariableBinding* result=NULL; + VariableBinding* result=NULL; - match(Token::assignment); - first->initializer = parseAssignmentExpression(false); - lexer.redesignate(true); // Safe: looking for non-slash puncutation. - result = first; + match(Token::assignment); + first->initializer = parseAssignmentExpression(false); + lexer.redesignate(true); // Safe: looking for non-slash puncutation. + result = first; - return result; + return result; } /** * NamedParameter -* Parameter -* OptionalParameter -* String NamedParameter +* Parameter +* OptionalParameter +* String NamedParameter */ JS::VariableBinding *JS::Parser::parseNamedParameter(NodeQueue &aliases) { - VariableBinding *result; + VariableBinding *result; - if(lookahead(Token::string)) { - const Token *t = match(Token::string); - aliases += new(arena) IdentifierList(*new StringAtom(copyTokenChars(*t))); - result = parseNamedParameter(aliases); - } else { - result = parseParameter(); - // ****** result->aliases = aliases.first; - if(lookahead(Token::assignment)) { - result = parseOptionalParameterPrime(result); - } - } - return result; + if(lookahead(Token::string)) { + const Token *t = match(Token::string); + aliases += new(arena) IdentifierList(*new StringAtom(copyTokenChars(*t))); + result = parseNamedParameter(aliases); + } else { + result = parseParameter(); + // ****** result->aliases = aliases.first; + if(lookahead(Token::assignment)) { + result = parseOptionalParameterPrime(result); + } + } + return result; } /** * ResultSignature -* -* : TypeExpression[allowIn] +* +* : TypeExpression[allowIn] */ JS::ExprNode *JS::Parser::parseResultSignature() { - ExprNode* result=NULL; + ExprNode* result=NULL; - if (lookahead(Token::colon)) - { - match(Token::colon); - result = parseTypeExpression(); // allowIn is default. - } else { - result = NULL; - } + if (lookahead(Token::colon)) + { + match(Token::colon); + result = parseTypeExpression(); // allowIn is default. + } else { + result = NULL; + } - return result; + return result; } @@ -2025,8 +2024,8 @@ static const char functionPrefixNames[3][5] = {"", "get ", "set " }; // Print this onto f. name must be non-nil. void JS::FunctionName::print(PrettyPrinter &f) const { - f << functionPrefixNames[prefix]; - f << name; + f << functionPrefixNames[prefix]; + f << name; } @@ -2034,37 +2033,37 @@ void JS::FunctionName::print(PrettyPrinter &f) const // const keyword. void JS::VariableBinding::print(PrettyPrinter &f, bool printConst) const { - PrettyPrinter::Block b(f); + PrettyPrinter::Block b(f); #ifdef NEW_PARSER - if (aliases) { - IdentifierList *id = aliases; - f << "| "; - while (id) { - f << "'"; - f << id->name; - f << "' "; - id = id->next; - } - } + if (aliases) { + IdentifierList *id = aliases; + f << "| "; + while (id) { + f << "'"; + f << id->name; + f << "' "; + id = id->next; + } + } #endif - if (printConst && constant) - f << "const "; + if (printConst && constant) + f << "const "; - if (name) - f << name; - PrettyPrinter::Indent i(f, subexpressionIndent); - if (type) { - f.fillBreak(0); - f << ": "; - f << type; - } - if (initializer) { - f.linearBreak(1); - f << "= "; - f << initializer; - } + if (name) + f << name; + PrettyPrinter::Indent i(f, subexpressionIndent); + if (type) { + f.fillBreak(0); + f << ": "; + f << type; + } + if (initializer) { + f.linearBreak(1); + f << "= "; + f << initializer; + } } @@ -2075,51 +2074,51 @@ void JS::VariableBinding::print(PrettyPrinter &f, bool printConst) const // true. void JS::FunctionDefinition::print(PrettyPrinter &f, const AttributeStmtNode *attributes, bool noSemi) const { - PrettyPrinter::Block b(f); - if (attributes) - attributes->printAttributes(f); + PrettyPrinter::Block b(f); + if (attributes) + attributes->printAttributes(f); - f << "function"; + f << "function"; - if (name) { - f << ' '; - FunctionName::print(f); - } - { - PrettyPrinter::Indent i(f, functionHeaderIndent); - f.fillBreak(0); - f << '('; - { - PrettyPrinter::Block b2(f); - const VariableBinding *p = parameters; - if (p) - while (true) { - if (p == restParameter) { - f << "..."; - if (p->name) - f << ' '; - } - p->print(f, true); - p = p->next; - if (!p) - break; - f << ','; - f.fillBreak(1); - } - f << ')'; - } - if (resultType) { - f.fillBreak(0); - f << ": "; - f << resultType; - } - } - if (body) { - bool loose = attributes != 0; - f.linearBreak(1, loose); - body->printBlock(f, loose); - } else - StmtNode::printSemi(f, noSemi); + if (name) { + f << ' '; + FunctionName::print(f); + } + { + PrettyPrinter::Indent i(f, functionHeaderIndent); + f.fillBreak(0); + f << '('; + { + PrettyPrinter::Block b2(f); + const VariableBinding *p = parameters; + if (p) + while (true) { + if (p == restParameter) { + f << "..."; + if (p->name) + f << ' '; + } + p->print(f, true); + p = p->next; + if (!p) + break; + f << ','; + f.fillBreak(1); + } + f << ')'; + } + if (resultType) { + f.fillBreak(0); + f << ": "; + f << resultType; + } + } + if (body) { + bool loose = attributes != 0; + f.linearBreak(1, loose); + body->printBlock(f, loose); + } else + StmtNode::printSemi(f, noSemi); } @@ -2128,279 +2127,279 @@ void JS::FunctionDefinition::print(PrettyPrinter &f, const AttributeStmtNode *at // const char *const JS::ExprNode::kindNames[kindsEnd] = { - "NIL", // none - 0, // identifier - 0, // number - 0, // string - 0, // regExp - "null", // Null - "true", // True - "false", // False - "this", // This + "NIL", // none + 0, // identifier + 0, // number + 0, // string + 0, // regExp + "null", // Null + "true", // True + "false", // False + "this", // This - 0, // parentheses - 0, // numUnit - 0, // exprUnit - "::", // qualify + 0, // parentheses + 0, // numUnit + 0, // exprUnit + "::", // qualify - 0, // objectLiteral - 0, // arrayLiteral - 0, // functionLiteral + 0, // objectLiteral + 0, // arrayLiteral + 0, // functionLiteral - 0, // call - 0, // New - 0, // index + 0, // call + 0, // New + 0, // index - ".", // dot - ".class", // dotClass - ".(", // dotParen + ".", // dot + ".class", // dotClass + ".(", // dotParen - 0, // superExpr - 0, // superStmt + 0, // superExpr + 0, // superStmt - "const ", // Const - "delete ", // Delete - "void ", // Void - "typeof ", // Typeof - "++ ", // preIncrement - "-- ", // preDecrement - " ++", // postIncrement - " --", // postDecrement - "+ ", // plus - "- ", // minus - "~ ", // complement - "! ", // logicalNot + "const ", // Const + "delete ", // Delete + "void ", // Void + "typeof ", // Typeof + "++ ", // preIncrement + "-- ", // preDecrement + " ++", // postIncrement + " --", // postDecrement + "+ ", // plus + "- ", // minus + "~ ", // complement + "! ", // logicalNot - "+", // add - "-", // subtract - "*", // multiply - "/", // divide - "%", // modulo - "<<", // leftShift - ">>", // rightShift - ">>>", // logicalRightShift - "&", // bitwiseAnd - "^", // bitwiseXor - "|", // bitwiseOr - "&&", // logicalAnd - "^^", // logicalXor - "||", // logicalOr + "+", // add + "-", // subtract + "*", // multiply + "/", // divide + "%", // modulo + "<<", // leftShift + ">>", // rightShift + ">>>", // logicalRightShift + "&", // bitwiseAnd + "^", // bitwiseXor + "|", // bitwiseOr + "&&", // logicalAnd + "^^", // logicalXor + "||", // logicalOr - "==", // equal - "!=", // notEqual - "<", // lessThan - "<=", // lessThanOrEqual - ">", // greaterThan - ">=", // greaterThanOrEqual - "===", // identical - "!==", // notIdentical - "as", // As - "in", // In - "instanceof", // Instanceof - "is", // Is + "==", // equal + "!=", // notEqual + "<", // lessThan + "<=", // lessThanOrEqual + ">", // greaterThan + ">=", // greaterThanOrEqual + "===", // identical + "!==", // notIdentical + "as", // As + "in", // In + "instanceof", // Instanceof + "is", // Is - "=", // assignment - "+=", // addEquals - "-=", // subtractEquals - "*=", // multiplyEquals - "/=", // divideEquals - "%=", // moduloEquals - "<<=", // leftShiftEquals - ">>=", // rightShiftEquals - ">>>=", // logicalRightShiftEquals - "&=", // bitwiseAndEquals - "^=", // bitwiseXorEquals - "|=", // bitwiseOrEquals - "&&=", // logicalAndEquals - "^^=", // logicalXorEquals - "||=", // logicalOrEquals + "=", // assignment + "+=", // addEquals + "-=", // subtractEquals + "*=", // multiplyEquals + "/=", // divideEquals + "%=", // moduloEquals + "<<=", // leftShiftEquals + ">>=", // rightShiftEquals + ">>>=", // logicalRightShiftEquals + "&=", // bitwiseAndEquals + "^=", // bitwiseXorEquals + "|=", // bitwiseOrEquals + "&&=", // logicalAndEquals + "^^=", // logicalXorEquals + "||=", // logicalOrEquals - "?", // conditional - "," // comma + "?", // conditional + "," // comma }; // Print this onto f. void JS::ExprNode::print(PrettyPrinter &f) const { - f << kindName(kind); + f << kindName(kind); } void JS::IdentifierExprNode::print(PrettyPrinter &f) const { - f << name; + f << name; } void JS::NumberExprNode::print(PrettyPrinter &f) const { - f << value; + f << value; } void JS::StringExprNode::print(PrettyPrinter &f) const { - quoteString(f, str, '"'); + quoteString(f, str, '"'); } void JS::RegExpExprNode::print(PrettyPrinter &f) const { - f << '/' << re << '/' << flags; + f << '/' << re << '/' << flags; } void JS::NumUnitExprNode::print(PrettyPrinter &f) const { - f << numStr; - StringExprNode::print(f); + f << numStr; + StringExprNode::print(f); } void JS::ExprUnitExprNode::print(PrettyPrinter &f) const { - f << op; - StringExprNode::print(f); + f << op; + StringExprNode::print(f); } void JS::FunctionExprNode::print(PrettyPrinter &f) const { - function.print(f, 0, false); + function.print(f, 0, false); } void JS::PairListExprNode::print(PrettyPrinter &f) const { - char beginBracket; - char endBracket; + char beginBracket; + char endBracket; - switch (getKind()) { - case objectLiteral: - beginBracket = '{'; - endBracket = '}'; - break; + switch (getKind()) { + case objectLiteral: + beginBracket = '{'; + endBracket = '}'; + break; - case arrayLiteral: - case index: - beginBracket = '['; - endBracket = ']'; - break; + case arrayLiteral: + case index: + beginBracket = '['; + endBracket = ']'; + break; - case superStmt: - case call: - case New: - beginBracket = '('; - endBracket = ')'; - break; + case superStmt: + case call: + case New: + beginBracket = '('; + endBracket = ')'; + break; - default: - NOT_REACHED("Bad kind"); - return; - } + default: + NOT_REACHED("Bad kind"); + return; + } - f << beginBracket; - PrettyPrinter::Block b(f); - const ExprPairList *p = pairs; - if (p) - while (true) { - const ExprNode *field = p->field; - if (field) { - f << field << ':'; - f.fillBreak(0); - } + f << beginBracket; + PrettyPrinter::Block b(f); + const ExprPairList *p = pairs; + if (p) + while (true) { + const ExprNode *field = p->field; + if (field) { + f << field << ':'; + f.fillBreak(0); + } - const ExprNode *value = p->value; - if (value) - f << value; + const ExprNode *value = p->value; + if (value) + f << value; - p = p->next; - if (!p) - break; - f << ','; - f.linearBreak(static_cast(field || value)); - } - f << endBracket; + p = p->next; + if (!p) + break; + f << ','; + f.linearBreak(static_cast(field || value)); + } + f << endBracket; } void JS::InvokeExprNode::print(PrettyPrinter &f) const { - PrettyPrinter::Block b(f); - if (hasKind(New)) - f << "new "; - if (hasKind(superStmt)) - f << "super"; - else - f << op; - PrettyPrinter::Indent i(f, subexpressionIndent); - f.fillBreak(0); - PairListExprNode::print(f); + PrettyPrinter::Block b(f); + if (hasKind(New)) + f << "new "; + if (hasKind(superStmt)) + f << "super"; + else + f << op; + PrettyPrinter::Indent i(f, subexpressionIndent); + f.fillBreak(0); + PairListExprNode::print(f); } void JS::SuperExprNode::print(PrettyPrinter &f) const { - f << "super"; - if (op) { - f << '('; - f << op; - f << ')'; - } + f << "super"; + if (op) { + f << '('; + f << op; + f << ')'; + } } void JS::UnaryExprNode::print(PrettyPrinter &f) const { - if (hasKind(parentheses)) { - f << '('; - f << op; - f << ')'; - } else { - if (debugExprNodePrint) - f << '('; - const char *name = kindName(getKind()); - if (hasKind(postIncrement) || hasKind(postDecrement) || hasKind(dotClass)) { - f << op; - f << name; - } else { - f << name; - f << op; - } - if (debugExprNodePrint) - f << ')'; - } + if (hasKind(parentheses)) { + f << '('; + f << op; + f << ')'; + } else { + if (debugExprNodePrint) + f << '('; + const char *name = kindName(getKind()); + if (hasKind(postIncrement) || hasKind(postDecrement) || hasKind(dotClass)) { + f << op; + f << name; + } else { + f << name; + f << op; + } + if (debugExprNodePrint) + f << ')'; + } } void JS::BinaryExprNode::print(PrettyPrinter &f) const { - if (debugExprNodePrint && !hasKind(qualify)) - f << '('; - PrettyPrinter::Block b(f); - f << op1; - uint32 nSpaces = hasKind(dot) || hasKind(dotParen) || hasKind(qualify) ? (uint32)0 : (uint32)1; - f.fillBreak(nSpaces); - f << kindName(getKind()); - f.fillBreak(nSpaces); - f << op2; - if (hasKind(dotParen)) - f << ')'; - if (debugExprNodePrint && !hasKind(qualify)) - f << ')'; + if (debugExprNodePrint && !hasKind(qualify)) + f << '('; + PrettyPrinter::Block b(f); + f << op1; + uint32 nSpaces = hasKind(dot) || hasKind(dotParen) || hasKind(qualify) ? (uint32)0 : (uint32)1; + f.fillBreak(nSpaces); + f << kindName(getKind()); + f.fillBreak(nSpaces); + f << op2; + if (hasKind(dotParen)) + f << ')'; + if (debugExprNodePrint && !hasKind(qualify)) + f << ')'; } void JS::TernaryExprNode::print(PrettyPrinter &f) const { - if (debugExprNodePrint) - f << '('; - PrettyPrinter::Block b(f); - f << op1; - f.fillBreak(1); - f << '?'; - f.fillBreak(1); - f << op2; - f.fillBreak(1); - f << ':'; - f.fillBreak(1); - f << op3; - if (debugExprNodePrint) - f << ')'; + if (debugExprNodePrint) + f << '('; + PrettyPrinter::Block b(f); + f << op1; + f.fillBreak(1); + f << '?'; + f.fillBreak(1); + f << op2; + f.fillBreak(1); + f << ':'; + f.fillBreak(1); + f << op3; + if (debugExprNodePrint) + f << ')'; } @@ -2413,28 +2412,28 @@ void JS::TernaryExprNode::print(PrettyPrinter &f) const // on nil, the list has at least one element. void JS::ExprList::printCommaList(PrettyPrinter &f) const { - PrettyPrinter::Block b(f); - const ExprList *list = this; - while (true) { - f << list->expr; - list = list->next; - if (!list) - break; - f << ','; - f.fillBreak(1); - } + PrettyPrinter::Block b(f); + const ExprList *list = this; + while (true) { + f << list->expr; + list = list->next; + if (!list) + break; + f << ','; + f.fillBreak(1); + } } -// If list is nil, do nothing. Otherwise, emit a linear line break of size 1, +// If list is nil, do nothing. Otherwise, emit a linear line break of size 1, // the name, a space, and the contents of list separated by commas. void JS::ExprList::printOptionalCommaList(PrettyPrinter &f, const char *name, const ExprList *list) { - if (list) { - f.linearBreak(1); - f << name << ' '; - list->printCommaList(f); - } + if (list) { + f.linearBreak(1); + f << name << ' '; + list->printCommaList(f); + } } @@ -2447,17 +2446,17 @@ void JS::ExprList::printOptionalCommaList(PrettyPrinter &f, const char *name, co // after the last statement. void JS::StmtNode::printStatements(PrettyPrinter &f, const StmtNode *statements) { - if (statements) { - PrettyPrinter::Block b(f); - while (true) { - const StmtNode *next = statements->next; - statements->print(f, !next); - statements = next; - if (!statements) - break; - f.requiredBreak(); - } - } + if (statements) { + PrettyPrinter::Block b(f); + while (true) { + const StmtNode *next = statements->next; + statements->print(f, !next); + statements = next; + if (!statements) + break; + f.requiredBreak(); + } + } } @@ -2468,36 +2467,36 @@ void JS::StmtNode::printStatements(PrettyPrinter &f, const StmtNode *statements) // call inside a PrettyPrinter::Block scope. void JS::StmtNode::printBlockStatements(PrettyPrinter &f, const StmtNode *statements, bool loose) { - f << '{'; - if (statements) { - { - PrettyPrinter::Indent i(f, basicIndent); - uint32 nSpaces = 0; - while (statements) { - if (statements->hasKind(Case)) { - PrettyPrinter::Indent i2(f, caseIndent - basicIndent); - f.linearBreak(nSpaces, loose); - statements->print(f, false); - } else { - f.linearBreak(nSpaces, loose); - statements->print(f, !statements->next); - } - statements = statements->next; - nSpaces = 1; - } - } - f.linearBreak(0, loose); - } else - f.fillBreak(0); - f << '}'; + f << '{'; + if (statements) { + { + PrettyPrinter::Indent i(f, basicIndent); + uint32 nSpaces = 0; + while (statements) { + if (statements->hasKind(Case)) { + PrettyPrinter::Indent i2(f, caseIndent - basicIndent); + f.linearBreak(nSpaces, loose); + statements->print(f, false); + } else { + f.linearBreak(nSpaces, loose); + statements->print(f, !statements->next); + } + statements = statements->next; + nSpaces = 1; + } + } + f.linearBreak(0, loose); + } else + f.fillBreak(0); + f << '}'; } // Print a closing statement semicolon onto f unless noSemi is true. void JS::StmtNode::printSemi(PrettyPrinter &f, bool noSemi) { - if (!noSemi) - f << ';'; + if (!noSemi) + f << ';'; } @@ -2514,23 +2513,23 @@ void JS::StmtNode::printSemi(PrettyPrinter &f, bool noSemi) // PrettyPrinter::Block scope that encloses the containining statement. void JS::StmtNode::printSubstatement(PrettyPrinter &f, bool noSemi, const char *continuation) const { - if (hasKind(block) && - !static_cast(this)->attributes) { - f << ' '; - static_cast(this)->printBlock(f, true); - if (continuation) - f << ' ' << continuation; - } else { - { - PrettyPrinter::Indent i(f, basicIndent); - f.requiredBreak(); - this->print(f, noSemi); - } - if (continuation) { - f.requiredBreak(); - f << continuation; - } - } + if (hasKind(block) && + !static_cast(this)->attributes) { + f << ' '; + static_cast(this)->printBlock(f, true); + if (continuation) + f << ' ' << continuation; + } else { + { + PrettyPrinter::Indent i(f, basicIndent); + f.requiredBreak(); + this->print(f, noSemi); + } + if (continuation) { + f.requiredBreak(); + f << continuation; + } + } } @@ -2538,8 +2537,8 @@ void JS::StmtNode::printSubstatement(PrettyPrinter &f, bool noSemi, const char * // space. void JS::AttributeStmtNode::printAttributes(PrettyPrinter &f) const { - for (const ExprList *a = attributes; a; a = a->next) - f << a->expr << ' '; + for (const ExprList *a = attributes; a; a = a->next) + f << a->expr << ' '; } @@ -2550,8 +2549,8 @@ void JS::AttributeStmtNode::printAttributes(PrettyPrinter &f) const // The caller must have placed this call inside a PrettyPrinter::Block scope. void JS::BlockStmtNode::printBlock(PrettyPrinter &f, bool loose) const { - printAttributes(f); - printBlockStatements(f, statements, loose); + printAttributes(f); + printBlockStatements(f, statements, loose); } @@ -2560,284 +2559,284 @@ void JS::BlockStmtNode::printBlock(PrettyPrinter &f, bool loose) const // required by the statement. void JS::StmtNode::print(PrettyPrinter &f, bool /*noSemi*/) const { - ASSERT(hasKind(empty)); - f << ';'; + ASSERT(hasKind(empty)); + f << ';'; } void JS::ExprStmtNode::print(PrettyPrinter &f, bool noSemi) const { - const ExprNode *e = expr; + const ExprNode *e = expr; - switch (getKind()) { - case Case: - if (e) { - f << "case "; - f << e; - } else - f << "default"; - f << ':'; - break; + switch (getKind()) { + case Case: + if (e) { + f << "case "; + f << e; + } else + f << "default"; + f << ':'; + break; - case Return: - f << "return"; - if (e) { - f << ' '; - goto showExpr; - } else - goto showSemicolon; + case Return: + f << "return"; + if (e) { + f << ' '; + goto showExpr; + } else + goto showSemicolon; - case Throw: - f << "throw "; - case expression: - showExpr: - f << e; - showSemicolon: - printSemi(f, noSemi); - break; + case Throw: + f << "throw "; + case expression: + showExpr: + f << e; + showSemicolon: + printSemi(f, noSemi); + break; - default: - NOT_REACHED("Bad kind"); - } + default: + NOT_REACHED("Bad kind"); + } } void JS::DebuggerStmtNode::print(PrettyPrinter &f, bool) const { - f << "debugger;"; + f << "debugger;"; } void JS::BlockStmtNode::print(PrettyPrinter &f, bool) const { - PrettyPrinter::Block b(f, 0); - printBlock(f, true); + PrettyPrinter::Block b(f, 0); + printBlock(f, true); } void JS::LabelStmtNode::print(PrettyPrinter &f, bool noSemi) const { - PrettyPrinter::Block b(f, basicIndent); - f << name << ':'; - f.linearBreak(1); - stmt->print(f, noSemi); + PrettyPrinter::Block b(f, basicIndent); + f << name << ':'; + f.linearBreak(1); + stmt->print(f, noSemi); } void JS::UnaryStmtNode::print(PrettyPrinter &f, bool noSemi) const { - PrettyPrinter::Block b(f, 0); - printContents(f, noSemi); + PrettyPrinter::Block b(f, 0); + printContents(f, noSemi); } // Same as print except that uses the caller's PrettyPrinter::Block. void JS::UnaryStmtNode::printContents(PrettyPrinter &f, bool noSemi) const { - ASSERT(stmt); - const char *kindName = 0; + ASSERT(stmt); + const char *kindName = 0; - switch (getKind()) { - case If: - kindName = "if"; - break; + switch (getKind()) { + case If: + kindName = "if"; + break; - case While: - kindName = "while"; - break; + case While: + kindName = "while"; + break; - case DoWhile: - f << "do"; - stmt->printSubstatement(f, true, "while ("); - f << expr << ')'; - printSemi(f, noSemi); - return; + case DoWhile: + f << "do"; + stmt->printSubstatement(f, true, "while ("); + f << expr << ')'; + printSemi(f, noSemi); + return; - case With: - kindName = "with"; - break; + case With: + kindName = "with"; + break; - default: - NOT_REACHED("Bad kind"); - } + default: + NOT_REACHED("Bad kind"); + } - f << kindName << " ("; - f << expr << ')'; - stmt->printSubstatement(f, noSemi); + f << kindName << " ("; + f << expr << ')'; + stmt->printSubstatement(f, noSemi); } void JS::BinaryStmtNode::printContents(PrettyPrinter &f, bool noSemi) const { - ASSERT(stmt && stmt2 && hasKind(IfElse)); + ASSERT(stmt && stmt2 && hasKind(IfElse)); - f << "if ("; - f << expr << ')'; - stmt->printSubstatement(f, true, "else"); - if (stmt2->hasKind(If) || stmt2->hasKind(IfElse)) { - f << ' '; - static_cast(stmt2)->printContents(f, noSemi); - } else - stmt2->printSubstatement(f, noSemi); + f << "if ("; + f << expr << ')'; + stmt->printSubstatement(f, true, "else"); + if (stmt2->hasKind(If) || stmt2->hasKind(IfElse)) { + f << ' '; + static_cast(stmt2)->printContents(f, noSemi); + } else + stmt2->printSubstatement(f, noSemi); } void JS::ForStmtNode::print(PrettyPrinter &f, bool noSemi) const { - ASSERT(stmt && (hasKind(For) || hasKind(ForIn))); + ASSERT(stmt && (hasKind(For) || hasKind(ForIn))); - PrettyPrinter::Block b(f, 0); - f << "for ("; - { - PrettyPrinter::Block b2(f); - if (initializer) - initializer->print(f, true); - if (hasKind(ForIn)) { - f.fillBreak(1); - f << "in"; - f.fillBreak(1); - ASSERT(expr2 && !expr3); - f << expr2; - } else { - f << ';'; - if (expr2) { - f.linearBreak(1); - f << expr2; - } - f << ';'; - if (expr3) { - f.linearBreak(1); - f << expr3; - } - } - f << ')'; - } - stmt->printSubstatement(f, noSemi); + PrettyPrinter::Block b(f, 0); + f << "for ("; + { + PrettyPrinter::Block b2(f); + if (initializer) + initializer->print(f, true); + if (hasKind(ForIn)) { + f.fillBreak(1); + f << "in"; + f.fillBreak(1); + ASSERT(expr2 && !expr3); + f << expr2; + } else { + f << ';'; + if (expr2) { + f.linearBreak(1); + f << expr2; + } + f << ';'; + if (expr3) { + f.linearBreak(1); + f << expr3; + } + } + f << ')'; + } + stmt->printSubstatement(f, noSemi); } void JS::SwitchStmtNode::print(PrettyPrinter &f, bool) const { - PrettyPrinter::Block b(f); - f << "switch ("; - f << expr << ") "; - printBlockStatements(f, statements, true); + PrettyPrinter::Block b(f); + f << "switch ("; + f << expr << ") "; + printBlockStatements(f, statements, true); } void JS::GoStmtNode::print(PrettyPrinter &f, bool noSemi) const { - const char *kindName = 0; + const char *kindName = 0; - switch (getKind()) { - case Break: - kindName = "break"; - break; + switch (getKind()) { + case Break: + kindName = "break"; + break; - case Continue: - kindName = "continue"; - break; + case Continue: + kindName = "continue"; + break; - default: - NOT_REACHED("Bad kind"); - } + default: + NOT_REACHED("Bad kind"); + } - f << kindName; - if (name) - f << " " << *name; - printSemi(f, noSemi); + f << kindName; + if (name) + f << " " << *name; + printSemi(f, noSemi); } void JS::TryStmtNode::print(PrettyPrinter &f, bool noSemi) const { - PrettyPrinter::Block b(f, 0); - f << "try"; - const StmtNode *s = stmt; - for (const CatchClause *c = catches; c; c = c->next) { - s->printSubstatement(f, true, "catch ("); - PrettyPrinter::Block b2(f); - f << c->name; - ExprNode *t = c->type; - if (t) { - f << ':'; - f.linearBreak(1); - f << t; - } - f << ')'; - s = c->stmt; - } - if (finally) { - s->printSubstatement(f, true, "finally"); - s = finally; - } - s->printSubstatement(f, noSemi); + PrettyPrinter::Block b(f, 0); + f << "try"; + const StmtNode *s = stmt; + for (const CatchClause *c = catches; c; c = c->next) { + s->printSubstatement(f, true, "catch ("); + PrettyPrinter::Block b2(f); + f << c->name; + ExprNode *t = c->type; + if (t) { + f << ':'; + f.linearBreak(1); + f << t; + } + f << ')'; + s = c->stmt; + } + if (finally) { + s->printSubstatement(f, true, "finally"); + s = finally; + } + s->printSubstatement(f, noSemi); } void JS::VariableStmtNode::print(PrettyPrinter &f, bool noSemi) const { - printAttributes(f); - ASSERT(hasKind(Const) || hasKind(Var)); - f << (hasKind(Const) ? "const" : "var"); - { - PrettyPrinter::Block b(f, basicIndent); - const VariableBinding *binding = bindings; - if (binding) - while (true) { - f.linearBreak(1); - binding->print(f, false); - binding = binding->next; - if (!binding) - break; - f << ','; - } - } - printSemi(f, noSemi); + printAttributes(f); + ASSERT(hasKind(Const) || hasKind(Var)); + f << (hasKind(Const) ? "const" : "var"); + { + PrettyPrinter::Block b(f, basicIndent); + const VariableBinding *binding = bindings; + if (binding) + while (true) { + f.linearBreak(1); + binding->print(f, false); + binding = binding->next; + if (!binding) + break; + f << ','; + } + } + printSemi(f, noSemi); } void JS::FunctionStmtNode::print(PrettyPrinter &f, bool noSemi) const { - function.print(f, this, noSemi); + function.print(f, this, noSemi); } void JS::NamespaceStmtNode::print(PrettyPrinter &f, bool noSemi) const { - printAttributes(f); - ASSERT(hasKind(Namespace)); + printAttributes(f); + ASSERT(hasKind(Namespace)); - PrettyPrinter::Block b(f, namespaceHeaderIndent); - f << "namespace "; - f << name; - ExprList::printOptionalCommaList(f, "extends", supers); - printSemi(f, noSemi); + PrettyPrinter::Block b(f, namespaceHeaderIndent); + f << "namespace "; + f << name; + ExprList::printOptionalCommaList(f, "extends", supers); + printSemi(f, noSemi); } void JS::ClassStmtNode::print(PrettyPrinter &f, bool noSemi) const { - printAttributes(f); - ASSERT(hasKind(Class) || hasKind(Interface)); + printAttributes(f); + ASSERT(hasKind(Class) || hasKind(Interface)); - { - PrettyPrinter::Block b(f, namespaceHeaderIndent); - const char *keyword; - const char *superlistKeyword; - if (hasKind(Class)) { - keyword = "class "; - superlistKeyword = "implements"; - } else { - keyword = "interface "; - superlistKeyword = "extends"; - } - f << keyword; - f << name; - if (superclass) { - f.linearBreak(1); - f << "extends "; - f << superclass; - } - ExprList::printOptionalCommaList(f, superlistKeyword, supers); - } - if (body) { - f.requiredBreak(); - body->printBlock(f, true); - } else - printSemi(f, noSemi); + { + PrettyPrinter::Block b(f, namespaceHeaderIndent); + const char *keyword; + const char *superlistKeyword; + if (hasKind(Class)) { + keyword = "class "; + superlistKeyword = "implements"; + } else { + keyword = "interface "; + superlistKeyword = "extends"; + } + f << keyword; + f << name; + if (superclass) { + f.linearBreak(1); + f << "extends "; + f << superclass; + } + ExprList::printOptionalCommaList(f, superlistKeyword, supers); + } + if (body) { + f.requiredBreak(); + body->printBlock(f, true); + } else + printSemi(f, noSemi); } diff --git a/mozilla/js2/src/parser.h b/mozilla/js2/src/parser.h index 084ed00f91d..dd72e80b66b 100644 --- a/mozilla/js2/src/parser.h +++ b/mozilla/js2/src/parser.h @@ -6,14 +6,14 @@ * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the JavaScript 2 Prototype. * * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are + * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * @@ -54,18 +54,18 @@ namespace JavaScript { // Language Selectors // - class Language { - enum { - minorVersion = 0, // Single BCD digit representing the minor JavaScript version - minorVersionBits = 4, - majorVersion = 4, // Single BCD digit representing the major JavaScript version - majorVersionBits = 4, - strictSemantics = 8, // True when strict semantics are in use - strictSyntax = 9, // True when strict syntax is in use - unknown = 31 // True when language is unknown - }; - uint32 flags; // Bitmap of flags at locations as above - }; + class Language { + enum { + minorVersion = 0, // Single BCD digit representing the minor JavaScript version + minorVersionBits = 4, + majorVersion = 4, // Single BCD digit representing the major JavaScript version + majorVersionBits = 4, + strictSemantics = 8, // True when strict semantics are in use + strictSyntax = 9, // True when strict syntax is in use + unknown = 31 // True when language is unknown + }; + uint32 flags; // Bitmap of flags at locations as above + }; // // Parser @@ -76,757 +76,756 @@ namespace JavaScript { // hold onto any data that needs to be destroyed explicitly. Strings are // allocated via newArenaString. - struct ParseNode: ArenaObject { - uint32 pos; // Position of this statement or expression + struct ParseNode: ArenaObject { + size_t pos; // Position of this statement or expression - explicit ParseNode(uint32 pos): pos(pos) {} - }; + explicit ParseNode(size_t pos): pos(pos) {} + }; // A helper template for creating linked lists of ParseNode subtypes. N should // be derived from a ParseNode and should have an instance variable called // of type N* and that is initialized to nil when an N instance is // created. - template - class NodeQueue { - public: - N *first; // Head of queue - private: - N **last; // Next link of last element of queue + template + class NodeQueue { + public: + N *first; // Head of queue + private: + N **last; // Next link of last element of queue - public: - NodeQueue(): first(0), last(&first) {} - private: - NodeQueue(const NodeQueue&); // No copy constructor - void operator=(const NodeQueue&); // No assignment operator - public: - void operator+=(N *elt) { - ASSERT(elt && !elt->next); *last = elt; last = &elt->next; - } - }; + public: + NodeQueue(): first(0), last(&first) {} + private: + NodeQueue(const NodeQueue&); // No copy constructor + void operator=(const NodeQueue&); // No assignment operator + public: + void operator+=(N *elt) { + ASSERT(elt && !elt->next); *last = elt; last = &elt->next; + } + }; - struct ExprNode; - struct AttributeStmtNode; - struct BlockStmtNode; + struct ExprNode; + struct AttributeStmtNode; + struct BlockStmtNode; - struct VariableBinding: ParseNode { - VariableBinding *next; // Next binding in a linked list of variable or parameter bindings - ExprNode *name; // The variable's name; - // nil if omitted, which currently can only happen for ... parameters - ExprNode *type; // Type expression or nil if not provided - ExprNode *initializer; // Initial value expression or nil if not provided - bool constant; // true for const variables and parameters - VariableBinding(uint32 pos, ExprNode *name, ExprNode *type, ExprNode *initializer, bool constant): - ParseNode(pos), next(0), name(name), type(type), initializer(initializer), constant(constant) {} + struct VariableBinding: ParseNode { + VariableBinding *next; // Next binding in a linked list of variable or parameter bindings + ExprNode *name; // The variable's name; + // nil if omitted, which currently can only happen for ... parameters + ExprNode *type; // Type expression or nil if not provided + ExprNode *initializer; // Initial value expression or nil if not provided + bool constant; // true for const variables and parameters + VariableBinding(size_t pos, ExprNode *name, ExprNode *type, ExprNode *initializer, bool constant): + ParseNode(pos), next(0), name(name), type(type), initializer(initializer), constant(constant) {} // the sematics/codegen passes stuff their // data in here. JS2Runtime::Property *prop; void print(PrettyPrinter &f, bool printConst) const; - }; - - - struct ExprNode: ParseNode { - // Keep synchronized with kindNames - enum Kind { // Actual class Operands - none, - identifier, // IdentifierExprNode - - // Begin of isPostfix() - number, // NumberExprNode - string, // StringExprNode - regExp, // RegExpExprNode // - Null, // ExprNode null - True, // ExprNode true - False, // ExprNode false - This, // ExprNode this - - parentheses, // UnaryExprNode () - numUnit, // NumUnitExprNode "" or - exprUnit, // ExprUnitExprNode () "" or - qualify, // BinaryExprNode :: ( must be identifier) - - objectLiteral, // PairListExprNode {:, :, ..., :} - arrayLiteral, // PairListExprNode [, , ..., ] - functionLiteral, // FunctionExprNode function - - call, // InvokeExprNode (:, :, ..., :) - New, // InvokeExprNode new (:, :, ..., :) - index, // InvokeExprNode [:, :, ..., :] - - dot, // BinaryExprNode . ( must be identifier or qualify) - dotClass, // UnaryExprNode .class - dotParen, // BinaryExprNode .( ) - // End of isPostfix() - - superExpr, // SuperExprNode super or super() - superStmt, // InvokeExprNode super(:, :, ..., :) - // A superStmt will only appear at the top level of an expression StmtNode. - - Const, // UnaryExprNode const - Delete, // UnaryExprNode delete - Void, // UnaryExprNode void - Typeof, // UnaryExprNode typeof - preIncrement, // UnaryExprNode ++ - preDecrement, // UnaryExprNode -- - postIncrement, // UnaryExprNode ++ - postDecrement, // UnaryExprNode -- - plus, // UnaryExprNode + - minus, // UnaryExprNode - - complement, // UnaryExprNode ~ - logicalNot, // UnaryExprNode ! - - add, // BinaryExprNode + - subtract, // BinaryExprNode - - multiply, // BinaryExprNode * - divide, // BinaryExprNode / - modulo, // BinaryExprNode % - leftShift, // BinaryExprNode << - rightShift, // BinaryExprNode >> - logicalRightShift, // BinaryExprNode >>> - bitwiseAnd, // BinaryExprNode & - bitwiseXor, // BinaryExprNode ^ - bitwiseOr, // BinaryExprNode | - logicalAnd, // BinaryExprNode && - logicalXor, // BinaryExprNode ^^ - logicalOr, // BinaryExprNode || - - equal, // BinaryExprNode == - notEqual, // BinaryExprNode != - lessThan, // BinaryExprNode < - lessThanOrEqual, // BinaryExprNode <= - greaterThan, // BinaryExprNode > - greaterThanOrEqual, // BinaryExprNode >= - identical, // BinaryExprNode === - notIdentical, // BinaryExprNode !== - As, // BinaryExprNode as - In, // BinaryExprNode in - Instanceof, // BinaryExprNode instanceof - Is, // BinaryExprNode is - - assignment, // BinaryExprNode = - - // Begin of isAssigningKind() - addEquals, // BinaryExprNode += - subtractEquals, // BinaryExprNode -= - multiplyEquals, // BinaryExprNode *= - divideEquals, // BinaryExprNode /= - moduloEquals, // BinaryExprNode %= - leftShiftEquals, // BinaryExprNode <<= - rightShiftEquals, // BinaryExprNode >>= - logicalRightShiftEquals, // BinaryExprNode >>>= - bitwiseAndEquals, // BinaryExprNode &= - bitwiseXorEquals, // BinaryExprNode ^= - bitwiseOrEquals, // BinaryExprNode |= - logicalAndEquals, // BinaryExprNode &&= - logicalXorEquals, // BinaryExprNode ^^= - logicalOrEquals, // BinaryExprNode ||= - // End of isAssigningKind() - - conditional, // TernaryExprNode ? : - comma, // BinaryExprNode , (Comma expressions only) - - kindsEnd - }; - - private: - Kind kind; // The node's kind - static const char *const kindNames[kindsEnd]; - public: - - ExprNode(uint32 pos, Kind kind): ParseNode(pos), kind(kind) {} - - Kind getKind() const {return kind;} - bool hasKind(Kind k) const {return kind == k;} - - static bool isAssigningKind(Kind kind) {return kind >= assignment && kind <= logicalOrEquals;} - static const char *kindName(Kind kind) {ASSERT(uint(kind) < kindsEnd); return kindNames[kind];} - bool isPostfix() const {return kind >= identifier && kind <= dotParen;} - - virtual void print(PrettyPrinter &f) const; - friend Formatter &operator<<(Formatter &f, Kind k) {f << kindName(k); return f;} - }; - - // Print e onto f. - inline PrettyPrinter &operator<<(PrettyPrinter &f, const ExprNode *e) { - ASSERT(e); e->print(f); return f; - } - - - struct FunctionName { - enum Prefix { - normal, // No prefix - Get, // get - Set // set - }; - - Prefix prefix; // The name's prefix, if any - ExprNode *name; // The name; nil if omitted + }; + + + struct ExprNode: ParseNode { + // Keep synchronized with kindNames + enum Kind { // Actual class Operands + none, + identifier, // IdentifierExprNode + + // Begin of isPostfix() + number, // NumberExprNode + string, // StringExprNode + regExp, // RegExpExprNode // + Null, // ExprNode null + True, // ExprNode true + False, // ExprNode false + This, // ExprNode this + + parentheses, // UnaryExprNode () + numUnit, // NumUnitExprNode "" or + exprUnit, // ExprUnitExprNode () "" or + qualify, // BinaryExprNode :: ( must be identifier) + + objectLiteral, // PairListExprNode {:, :, ..., :} + arrayLiteral, // PairListExprNode [, , ..., ] + functionLiteral, // FunctionExprNode function + + call, // InvokeExprNode (:, :, ..., :) + New, // InvokeExprNode new (:, :, ..., :) + index, // InvokeExprNode [:, :, ..., :] + + dot, // BinaryExprNode . ( must be identifier or qualify) + dotClass, // UnaryExprNode .class + dotParen, // BinaryExprNode .( ) + // End of isPostfix() + + superExpr, // SuperExprNode super or super() + superStmt, // InvokeExprNode super(:, :, ..., :) + // A superStmt will only appear at the top level of an expression StmtNode. + + Const, // UnaryExprNode const + Delete, // UnaryExprNode delete + Void, // UnaryExprNode void + Typeof, // UnaryExprNode typeof + preIncrement, // UnaryExprNode ++ + preDecrement, // UnaryExprNode -- + postIncrement, // UnaryExprNode ++ + postDecrement, // UnaryExprNode -- + plus, // UnaryExprNode + + minus, // UnaryExprNode - + complement, // UnaryExprNode ~ + logicalNot, // UnaryExprNode ! + + add, // BinaryExprNode + + subtract, // BinaryExprNode - + multiply, // BinaryExprNode * + divide, // BinaryExprNode / + modulo, // BinaryExprNode % + leftShift, // BinaryExprNode << + rightShift, // BinaryExprNode >> + logicalRightShift, // BinaryExprNode >>> + bitwiseAnd, // BinaryExprNode & + bitwiseXor, // BinaryExprNode ^ + bitwiseOr, // BinaryExprNode | + logicalAnd, // BinaryExprNode && + logicalXor, // BinaryExprNode ^^ + logicalOr, // BinaryExprNode || + + equal, // BinaryExprNode == + notEqual, // BinaryExprNode != + lessThan, // BinaryExprNode < + lessThanOrEqual, // BinaryExprNode <= + greaterThan, // BinaryExprNode > + greaterThanOrEqual, // BinaryExprNode >= + identical, // BinaryExprNode === + notIdentical, // BinaryExprNode !== + As, // BinaryExprNode as + In, // BinaryExprNode in + Instanceof, // BinaryExprNode instanceof + Is, // BinaryExprNode is + + assignment, // BinaryExprNode = + + // Begin of isAssigningKind() + addEquals, // BinaryExprNode += + subtractEquals, // BinaryExprNode -= + multiplyEquals, // BinaryExprNode *= + divideEquals, // BinaryExprNode /= + moduloEquals, // BinaryExprNode %= + leftShiftEquals, // BinaryExprNode <<= + rightShiftEquals, // BinaryExprNode >>= + logicalRightShiftEquals, // BinaryExprNode >>>= + bitwiseAndEquals, // BinaryExprNode &= + bitwiseXorEquals, // BinaryExprNode ^= + bitwiseOrEquals, // BinaryExprNode |= + logicalAndEquals, // BinaryExprNode &&= + logicalXorEquals, // BinaryExprNode ^^= + logicalOrEquals, // BinaryExprNode ||= + // End of isAssigningKind() + + conditional, // TernaryExprNode ? : + comma, // BinaryExprNode , (Comma expressions only) + + kindsEnd + }; + + private: + Kind kind; // The node's kind + static const char *const kindNames[kindsEnd]; + public: + + ExprNode(size_t pos, Kind kind): ParseNode(pos), kind(kind) {} + + Kind getKind() const {return kind;} + bool hasKind(Kind k) const {return kind == k;} + + static bool isAssigningKind(Kind kind) {return kind >= assignment && kind <= logicalOrEquals;} + static const char *kindName(Kind kind) {ASSERT(uint(kind) < kindsEnd); return kindNames[kind];} + bool isPostfix() const {return kind >= identifier && kind <= dotParen;} + + virtual void print(PrettyPrinter &f) const; + friend Formatter &operator<<(Formatter &f, Kind k) {f << kindName(k); return f;} + }; + + // Print e onto f. + inline PrettyPrinter &operator<<(PrettyPrinter &f, const ExprNode *e) { + ASSERT(e); e->print(f); return f; + } + + + struct FunctionName { + enum Prefix { + normal, // No prefix + Get, // get + Set // set + }; + + Prefix prefix; // The name's prefix, if any + ExprNode *name; // The name; nil if omitted - FunctionName(): prefix(normal), name(0) {} - - void print(PrettyPrinter &f) const; - }; + FunctionName(): prefix(normal), name(0) {} + + void print(PrettyPrinter &f) const; + }; - struct FunctionDefinition: FunctionName { - VariableBinding *parameters; // Linked list of all parameters, including optional and rest parameters, if any - VariableBinding *optParameters; // Pointer to first non-required parameter inside parameters list; nil if none - VariableBinding *namedParameters; // The first parameter after the named parameter marker. May or may not have aliases. - VariableBinding *restParameter; // Pointer to rest parameter inside parameters list; nil if none - ExprNode *resultType; // Result type expression or nil if not provided - BlockStmtNode *body; // Body; nil if none + struct FunctionDefinition: FunctionName { + VariableBinding *parameters; // Linked list of all parameters, including optional and rest parameters, if any + VariableBinding *optParameters; // Pointer to first non-required parameter inside parameters list; nil if none + VariableBinding *namedParameters; // The first parameter after the named parameter marker. May or may not have aliases. + VariableBinding *restParameter; // Pointer to rest parameter inside parameters list; nil if none + ExprNode *resultType; // Result type expression or nil if not provided + BlockStmtNode *body; // Body; nil if none - void print(PrettyPrinter &f, const AttributeStmtNode *attributes, bool noSemi) const; - }; + void print(PrettyPrinter &f, const AttributeStmtNode *attributes, bool noSemi) const; + }; - struct IdentifierExprNode: ExprNode { - const StringAtom &name; // The identifier + struct IdentifierExprNode: ExprNode { + const StringAtom &name; // The identifier - IdentifierExprNode(uint32 pos, Kind kind, const StringAtom &name): ExprNode(pos, kind), name(name) {} - explicit IdentifierExprNode(const Token &t): ExprNode(t.getPos(), identifier), name(t.getIdentifier()) {} + IdentifierExprNode(size_t pos, Kind kind, const StringAtom &name): ExprNode(pos, kind), name(name) {} + explicit IdentifierExprNode(const Token &t): ExprNode(t.getPos(), identifier), name(t.getIdentifier()) {} - void print(PrettyPrinter &f) const; - }; + void print(PrettyPrinter &f) const; + }; - struct NumberExprNode: ExprNode { - float64 value; // The number's value + struct NumberExprNode: ExprNode { + float64 value; // The number's value - NumberExprNode(uint32 pos, float64 value): ExprNode(pos, number), value(value) {} - explicit NumberExprNode(const Token &t): ExprNode(t.getPos(), number), value(t.getValue()) {} + NumberExprNode(size_t pos, float64 value): ExprNode(pos, number), value(value) {} + explicit NumberExprNode(const Token &t): ExprNode(t.getPos(), number), value(t.getValue()) {} - void print(PrettyPrinter &f) const; - }; + void print(PrettyPrinter &f) const; + }; - struct StringExprNode: ExprNode { - String &str; // The string + struct StringExprNode: ExprNode { + String &str; // The string - StringExprNode(uint32 pos, Kind kind, String &str): ExprNode(pos, kind), str(str) {} + StringExprNode(size_t pos, Kind kind, String &str): ExprNode(pos, kind), str(str) {} - void print(PrettyPrinter &f) const; - }; + void print(PrettyPrinter &f) const; + }; - struct RegExpExprNode: ExprNode { - const StringAtom &re; // The regular expression's contents - String &flags; // The regular expression's flags + struct RegExpExprNode: ExprNode { + const StringAtom &re; // The regular expression's contents + String &flags; // The regular expression's flags - RegExpExprNode(uint32 pos, Kind kind, const StringAtom &re, String &flags): - ExprNode(pos, kind), re(re), flags(flags) {} + RegExpExprNode(size_t pos, Kind kind, const StringAtom &re, String &flags): + ExprNode(pos, kind), re(re), flags(flags) {} - void print(PrettyPrinter &f) const; - }; + void print(PrettyPrinter &f) const; + }; - struct NumUnitExprNode: StringExprNode { // str is the unit string - String &numStr; // The number's source string - float64 num; // The number's value + struct NumUnitExprNode: StringExprNode { // str is the unit string + String &numStr; // The number's source string + float64 num; // The number's value - NumUnitExprNode(uint32 pos, Kind kind, String &numStr, float64 num, String &unitStr): - StringExprNode(pos, kind, unitStr), numStr(numStr), num(num) {} + NumUnitExprNode(size_t pos, Kind kind, String &numStr, float64 num, String &unitStr): + StringExprNode(pos, kind, unitStr), numStr(numStr), num(num) {} - void print(PrettyPrinter &f) const; - }; + void print(PrettyPrinter &f) const; + }; - struct ExprUnitExprNode: StringExprNode { // str is the unit string - ExprNode *op; // The expression to which the unit is applied; non-nil only + struct ExprUnitExprNode: StringExprNode { // str is the unit string + ExprNode *op; // The expression to which the unit is applied; non-nil only - ExprUnitExprNode(uint32 pos, Kind kind, ExprNode *op, String &unitStr): - StringExprNode(pos, kind, unitStr), op(op) {ASSERT(op);} + ExprUnitExprNode(size_t pos, Kind kind, ExprNode *op, String &unitStr): + StringExprNode(pos, kind, unitStr), op(op) {ASSERT(op);} - void print(PrettyPrinter &f) const; - }; + void print(PrettyPrinter &f) const; + }; - struct FunctionExprNode: ExprNode { - FunctionDefinition function; // Function definition + struct FunctionExprNode: ExprNode { + FunctionDefinition function; // Function definition - explicit FunctionExprNode(uint32 pos): ExprNode(pos, functionLiteral) {} + explicit FunctionExprNode(size_t pos): ExprNode(pos, functionLiteral) {} - void print(PrettyPrinter &f) const; - }; + void print(PrettyPrinter &f) const; + }; - struct ExprPairList: ArenaObject { - ExprPairList *next; // Next pair in linked list - ExprNode *field; // Field expression or nil if not provided - ExprNode *value; // Value expression or nil if not provided + struct ExprPairList: ArenaObject { + ExprPairList *next; // Next pair in linked list + ExprNode *field; // Field expression or nil if not provided + ExprNode *value; // Value expression or nil if not provided - explicit ExprPairList(ExprNode *field = 0, ExprNode *value = 0): next(0), field(field), value(value) {} - }; + explicit ExprPairList(ExprNode *field = 0, ExprNode *value = 0): next(0), field(field), value(value) {} + }; - struct PairListExprNode: ExprNode { - ExprPairList *pairs; // Linked list of pairs + struct PairListExprNode: ExprNode { + ExprPairList *pairs; // Linked list of pairs - PairListExprNode(uint32 pos, Kind kind, ExprPairList *pairs): ExprNode(pos, kind), pairs(pairs) {} + PairListExprNode(size_t pos, Kind kind, ExprPairList *pairs): ExprNode(pos, kind), pairs(pairs) {} - void print(PrettyPrinter &f) const; - }; + void print(PrettyPrinter &f) const; + }; - struct InvokeExprNode: PairListExprNode { - ExprNode *op; // The called function, called constructor, or indexed object; nil only for superStmt + struct InvokeExprNode: PairListExprNode { + ExprNode *op; // The called function, called constructor, or indexed object; nil only for superStmt - InvokeExprNode(uint32 pos, Kind kind, ExprNode *op, ExprPairList *pairs): - PairListExprNode(pos, kind, pairs), op(op) {ASSERT(op || kind == superStmt);} + InvokeExprNode(size_t pos, Kind kind, ExprNode *op, ExprPairList *pairs): + PairListExprNode(pos, kind, pairs), op(op) {ASSERT(op || kind == superStmt);} - void print(PrettyPrinter &f) const; - }; + void print(PrettyPrinter &f) const; + }; - struct SuperExprNode: ExprNode { - ExprNode *op; // The operand or nil if none + struct SuperExprNode: ExprNode { + ExprNode *op; // The operand or nil if none - SuperExprNode(uint32 pos, ExprNode *op): ExprNode(pos, superExpr), op(op) {} + SuperExprNode(size_t pos, ExprNode *op): ExprNode(pos, superExpr), op(op) {} - void print(PrettyPrinter &f) const; - }; + void print(PrettyPrinter &f) const; + }; - struct UnaryExprNode: ExprNode { - ExprNode *op; // The unary operator's operand; non-nil only + struct UnaryExprNode: ExprNode { + 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(size_t pos, Kind kind, ExprNode *op): ExprNode(pos, kind), op(op) {ASSERT(op);} - void print(PrettyPrinter &f) const; - }; + void print(PrettyPrinter &f) const; + }; - struct BinaryExprNode: ExprNode { - ExprNode *op1; // The binary operator's first operand; non-nil only - ExprNode *op2; // The binary operator's second operand; non-nil only + struct BinaryExprNode: ExprNode { + ExprNode *op1; // The binary operator's first operand; non-nil only + ExprNode *op2; // The binary operator's second operand; non-nil only - BinaryExprNode(uint32 pos, Kind kind, ExprNode *op1, ExprNode *op2): - ExprNode(pos, kind), op1(op1), op2(op2) {ASSERT(op1 && op2);} + BinaryExprNode(size_t pos, Kind kind, ExprNode *op1, ExprNode *op2): + ExprNode(pos, kind), op1(op1), op2(op2) {ASSERT(op1 && op2);} - void print(PrettyPrinter &f) const; - }; + void print(PrettyPrinter &f) const; + }; - struct TernaryExprNode: ExprNode { - ExprNode *op1; // The ternary operator's first operand; non-nil only - ExprNode *op2; // The ternary operator's second operand; non-nil only - ExprNode *op3; // The ternary operator's third operand; non-nil only + struct TernaryExprNode: ExprNode { + ExprNode *op1; // The ternary operator's first operand; non-nil only + ExprNode *op2; // The ternary operator's second operand; non-nil only + ExprNode *op3; // The ternary operator's third operand; non-nil only - TernaryExprNode(uint32 pos, Kind kind, ExprNode *op1, ExprNode *op2, ExprNode *op3): - ExprNode(pos, kind), op1(op1), op2(op2), op3(op3) {ASSERT(op1 && op2 && op3);} + TernaryExprNode(size_t pos, Kind kind, ExprNode *op1, ExprNode *op2, ExprNode *op3): + ExprNode(pos, kind), op1(op1), op2(op2), op3(op3) {ASSERT(op1 && op2 && op3);} - void print(PrettyPrinter &f) const; - }; + void print(PrettyPrinter &f) const; + }; - struct StmtNode: ParseNode { - enum Kind { // Actual class Operands - empty, // StmtNode ; - expression, // ExprStmtNode ; - block, // BlockStmtNode { } - label, // LabelStmtNode : - If, // UnaryStmtNode if ( ) - IfElse, // BinaryStmtNode if ( ) else - Switch, // SwitchStmtNode switch ( ) - While, // UnaryStmtNode while ( ) - DoWhile, // UnaryStmtNode do while ( ) - With, // UnaryStmtNode with ( ) - For, // ForStmtNode for ( ; ; ) - ForIn, // ForStmtNode for ( in ) - Case, // ExprStmtNode case : or default : - // Only occurs directly inside a Switch - Break, // GoStmtNode break ; or break ; - Continue, // GoStmtNode continue ; or continue ; - Return, // ExprStmtNode return ; or return ; - Throw, // ExprStmtNode throw ; - Try, // TryStmtNode try - Import, // ImportStmtNode import ; - UseImport, // ImportStmtNode use import ; - Use, // UseStmtNode use namespace ; - Export, // ExportStmtNode export ; - Const, // VariableStmtNode const ; - Var, // VariableStmtNode var ; - Function, // FunctionStmtNode function - Class, // ClassStmtNode class extends implements - Interface, // ClassStmtNode interface extends - Namespace, // NamespaceStmtNode namespace extends - Language, // LanguageStmtNode language ; - Package, // PackageStmtNode package - Debugger // ExprStmtNode debugger ; - }; + struct StmtNode: ParseNode { + enum Kind { // Actual class Operands + empty, // StmtNode ; + expression, // ExprStmtNode ; + block, // BlockStmtNode { } + label, // LabelStmtNode : + If, // UnaryStmtNode if ( ) + IfElse, // BinaryStmtNode if ( ) else + Switch, // SwitchStmtNode switch ( ) + While, // UnaryStmtNode while ( ) + DoWhile, // UnaryStmtNode do while ( ) + With, // UnaryStmtNode with ( ) + For, // ForStmtNode for ( ; ; ) + ForIn, // ForStmtNode for ( in ) + Case, // ExprStmtNode case : or default : + // Only occurs directly inside a Switch + Break, // GoStmtNode break ; or break ; + Continue, // GoStmtNode continue ; or continue ; + Return, // ExprStmtNode return ; or return ; + Throw, // ExprStmtNode throw ; + Try, // TryStmtNode try + Import, // ImportStmtNode import ; + UseImport, // ImportStmtNode use import ; + Use, // UseStmtNode use namespace ; + Export, // ExportStmtNode export ; + Const, // VariableStmtNode const ; + Var, // VariableStmtNode var ; + Function, // FunctionStmtNode function + Class, // ClassStmtNode class extends implements + Interface, // ClassStmtNode interface extends + Namespace, // NamespaceStmtNode namespace extends + Language, // LanguageStmtNode language ; + Package, // PackageStmtNode package + Debugger // ExprStmtNode debugger ; + }; - private: - Kind kind; // The node's kind - public: - StmtNode *next; // Next statement in a linked list of statements in this block + private: + Kind kind; // The node's kind + public: + StmtNode *next; // Next statement in a linked list of statements in this block - StmtNode(uint32 pos, Kind kind): ParseNode(pos), kind(kind), next(0) {} + StmtNode(size_t pos, Kind kind): ParseNode(pos), kind(kind), next(0) {} - Kind getKind() const {return kind;} - bool hasKind(Kind k) const {return kind == k;} + Kind getKind() const {return kind;} + bool hasKind(Kind k) const {return kind == k;} - static void printStatements(PrettyPrinter &f, const StmtNode *statements); - static void printBlockStatements(PrettyPrinter &f, const StmtNode *statements, bool loose); - static void printSemi(PrettyPrinter &f, bool noSemi); - void printSubstatement(PrettyPrinter &f, bool noSemi, const char *continuation = 0) const; - virtual void print(PrettyPrinter &f, bool noSemi) const; - }; + static void printStatements(PrettyPrinter &f, const StmtNode *statements); + static void printBlockStatements(PrettyPrinter &f, const StmtNode *statements, bool loose); + static void printSemi(PrettyPrinter &f, bool noSemi); + void printSubstatement(PrettyPrinter &f, bool noSemi, const char *continuation = 0) const; + virtual void print(PrettyPrinter &f, bool noSemi) const; + }; - struct ExprList: ArenaObject { - ExprList *next; // Next expression in linked list - ExprNode *expr; // Attribute expression; non-nil only + struct ExprList: ArenaObject { + ExprList *next; // Next expression in linked list + ExprNode *expr; // Attribute expression; non-nil only - explicit ExprList(ExprNode *expr): next(0), expr(expr) {ASSERT(expr);} + explicit ExprList(ExprNode *expr): next(0), expr(expr) {ASSERT(expr);} - void printCommaList(PrettyPrinter &f) const; - static void printOptionalCommaList(PrettyPrinter &f, const char *name, const ExprList *list); - }; + void printCommaList(PrettyPrinter &f) const; + static void printOptionalCommaList(PrettyPrinter &f, const char *name, const ExprList *list); + }; - struct ExprStmtNode: StmtNode { - ExprNode *expr; // The expression statement's expression. May be nil for default: or return-with-no-expression statements. - uint32 label; // (only used for case statements) + struct ExprStmtNode: StmtNode { + ExprNode *expr; // The expression statement's expression. May be nil for default: or return-with-no-expression statements. + uint32 label; // (only used for case statements) - ExprStmtNode(uint32 pos, Kind kind, ExprNode *expr): StmtNode(pos, kind), expr(expr) {} + ExprStmtNode(size_t pos, Kind kind, ExprNode *expr): StmtNode(pos, kind), expr(expr) {} - void print(PrettyPrinter &f, bool noSemi) const; - }; + void print(PrettyPrinter &f, bool noSemi) const; + }; - struct DebuggerStmtNode: StmtNode { - DebuggerStmtNode(uint32 pos, Kind kind): StmtNode(pos, kind) {} + struct DebuggerStmtNode: StmtNode { + DebuggerStmtNode(size_t pos, Kind kind): StmtNode(pos, kind) {} - void print(PrettyPrinter &f, bool noSemi) const; - }; + void print(PrettyPrinter &f, bool noSemi) const; + }; - struct AttributeStmtNode: StmtNode { - ExprList *attributes; // Linked list of block or definition's attributes + struct AttributeStmtNode: StmtNode { + ExprList *attributes; // Linked list of block or definition's attributes - AttributeStmtNode(uint32 pos, Kind kind, ExprList *attributes): StmtNode(pos, kind), attributes(attributes) {} + AttributeStmtNode(size_t pos, Kind kind, ExprList *attributes): StmtNode(pos, kind), attributes(attributes) {} - void printAttributes(PrettyPrinter &f) const; - }; + void printAttributes(PrettyPrinter &f) const; + }; - struct BlockStmtNode: AttributeStmtNode { - StmtNode *statements; // Linked list of block's statements + struct BlockStmtNode: AttributeStmtNode { + StmtNode *statements; // Linked list of block's statements - BlockStmtNode(uint32 pos, Kind kind, ExprList *attributes, StmtNode *statements): - AttributeStmtNode(pos, kind, attributes), statements(statements) {} + BlockStmtNode(size_t pos, Kind kind, ExprList *attributes, StmtNode *statements): + AttributeStmtNode(pos, kind, attributes), statements(statements) {} - void print(PrettyPrinter &f, bool noSemi) const; - void printBlock(PrettyPrinter &f, bool loose) const; - }; + void print(PrettyPrinter &f, bool noSemi) const; + void printBlock(PrettyPrinter &f, bool loose) const; + }; - struct LabelStmtNode: StmtNode { - const StringAtom &name; // The label - StmtNode *stmt; // Labeled statement; non-nil only - - LabelStmtNode(uint32 pos, const StringAtom &name, StmtNode *stmt): - StmtNode(pos, label), name(name), stmt(stmt) {ASSERT(stmt);} + struct LabelStmtNode: StmtNode { + const StringAtom &name; // The label + StmtNode *stmt; // Labeled statement; non-nil only + + LabelStmtNode(size_t pos, const StringAtom &name, StmtNode *stmt): + StmtNode(pos, label), name(name), stmt(stmt) {ASSERT(stmt);} - void print(PrettyPrinter &f, bool noSemi) const; - }; + void print(PrettyPrinter &f, bool noSemi) const; + }; - struct UnaryStmtNode: ExprStmtNode { - StmtNode *stmt; // First substatement; non-nil only + struct UnaryStmtNode: ExprStmtNode { + StmtNode *stmt; // First substatement; non-nil only - UnaryStmtNode(uint32 pos, Kind kind, ExprNode *expr, StmtNode *stmt): - ExprStmtNode(pos, kind, expr), stmt(stmt) {ASSERT(stmt);} + UnaryStmtNode(size_t pos, Kind kind, ExprNode *expr, StmtNode *stmt): + ExprStmtNode(pos, kind, expr), stmt(stmt) {ASSERT(stmt);} - void print(PrettyPrinter &f, bool noSemi) const; - virtual void printContents(PrettyPrinter &f, bool noSemi) const; - }; + void print(PrettyPrinter &f, bool noSemi) const; + virtual void printContents(PrettyPrinter &f, bool noSemi) const; + }; - struct BinaryStmtNode: UnaryStmtNode { - StmtNode *stmt2; // Second substatement; non-nil only + struct BinaryStmtNode: UnaryStmtNode { + StmtNode *stmt2; // Second substatement; non-nil only - BinaryStmtNode(uint32 pos, Kind kind, ExprNode *expr, StmtNode *stmt1, StmtNode *stmt2): - UnaryStmtNode(pos, kind, expr, stmt1), stmt2(stmt2) {ASSERT(stmt2);} + BinaryStmtNode(size_t pos, Kind kind, ExprNode *expr, StmtNode *stmt1, StmtNode *stmt2): + UnaryStmtNode(pos, kind, expr, stmt1), stmt2(stmt2) {ASSERT(stmt2);} - void printContents(PrettyPrinter &f, bool noSemi) const; - }; + void printContents(PrettyPrinter &f, bool noSemi) const; + }; - struct ForStmtNode: StmtNode { - StmtNode *initializer; // For: First item in parentheses; either nil (if not provided), an expression, or a Var, or a Const. - // ForIn: Expression or declaration before 'in'; either an expression, - // or a Var or a Const with exactly one binding. - ExprNode *expr2; // For: Second item in parentheses; nil if not provided - // ForIn: Subexpression after 'in'; non-nil only - ExprNode *expr3; // For: Third item in parentheses; nil if not provided - // ForIn: nil - StmtNode *stmt; // Substatement; non-nil only + struct ForStmtNode: StmtNode { + StmtNode *initializer; // For: First item in parentheses; either nil (if not provided), an expression, or a Var, or a Const. + // ForIn: Expression or declaration before 'in'; either an expression, + // or a Var or a Const with exactly one binding. + ExprNode *expr2; // For: Second item in parentheses; nil if not provided + // ForIn: Subexpression after 'in'; non-nil only + ExprNode *expr3; // For: Third item in parentheses; nil if not provided + // ForIn: nil + StmtNode *stmt; // Substatement; non-nil only - ForStmtNode(uint32 pos, Kind kind, StmtNode *initializer, ExprNode *expr2, ExprNode *expr3, StmtNode *stmt): - StmtNode(pos, kind), initializer(initializer), expr2(expr2), expr3(expr3), stmt(stmt) {ASSERT(stmt);} + ForStmtNode(size_t pos, Kind kind, StmtNode *initializer, ExprNode *expr2, ExprNode *expr3, StmtNode *stmt): + StmtNode(pos, kind), initializer(initializer), expr2(expr2), expr3(expr3), stmt(stmt) {ASSERT(stmt);} - void print(PrettyPrinter &f, bool noSemi) const; - }; + void print(PrettyPrinter &f, bool noSemi) const; + }; - struct SwitchStmtNode: ExprStmtNode { - StmtNode *statements; // Linked list of switch block's statements, which may include Case and Default statements + struct SwitchStmtNode: ExprStmtNode { + StmtNode *statements; // Linked list of switch block's statements, which may include Case and Default statements - SwitchStmtNode(uint32 pos, ExprNode *expr, StmtNode *statements): - ExprStmtNode(pos, Switch, expr), statements(statements) {} + SwitchStmtNode(size_t pos, ExprNode *expr, StmtNode *statements): + ExprStmtNode(pos, Switch, expr), statements(statements) {} - void print(PrettyPrinter &f, bool noSemi) const; - }; + void print(PrettyPrinter &f, bool noSemi) const; + }; - struct GoStmtNode: StmtNode { - const StringAtom *name; // The label; nil if none + struct GoStmtNode: StmtNode { + const StringAtom *name; // The label; nil if none - GoStmtNode(uint32 pos, Kind kind, const StringAtom *name): StmtNode(pos, kind), name(name) {} + GoStmtNode(size_t pos, Kind kind, const StringAtom *name): StmtNode(pos, kind), name(name) {} - void print(PrettyPrinter &f, bool noSemi) const; - }; + void print(PrettyPrinter &f, bool noSemi) const; + }; - struct CatchClause: ParseNode { - CatchClause *next; // Next catch clause in a linked list of catch clauses - const StringAtom &name; // The name of the variable that will hold the exception - ExprNode *type; // Type expression or nil if not provided - StmtNode *stmt; // The catch clause's body; non-nil only + struct CatchClause: ParseNode { + CatchClause *next; // Next catch clause in a linked list of catch clauses + const StringAtom &name; // The name of the variable that will hold the exception + ExprNode *type; // Type expression or nil if not provided + StmtNode *stmt; // The catch clause's body; non-nil only - CatchClause(uint32 pos, const StringAtom &name, ExprNode *type, StmtNode *stmt): - ParseNode(pos), next(0), name(name), type(type), stmt(stmt) {ASSERT(stmt);} + CatchClause(size_t pos, const StringAtom &name, ExprNode *type, StmtNode *stmt): + ParseNode(pos), next(0), name(name), type(type), stmt(stmt) {ASSERT(stmt);} - // the sematics/codegen passes stuff their - // data in here. - JS2Runtime::Property *prop; - }; + // the sematics/codegen passes stuff their data in here. + JS2Runtime::Property *prop; + }; - struct TryStmtNode: StmtNode { - StmtNode *stmt; // Substatement being tried; usually a block; non-nil only - CatchClause *catches; // Linked list of catch blocks; may be nil - StmtNode *finally; // Finally block or nil if none + struct TryStmtNode: StmtNode { + StmtNode *stmt; // Substatement being tried; usually a block; non-nil only + CatchClause *catches; // Linked list of catch blocks; may be nil + StmtNode *finally; // Finally block or nil if none - TryStmtNode(uint32 pos, StmtNode *stmt, CatchClause *catches, StmtNode *finally): - StmtNode(pos, Try), stmt(stmt), catches(catches), finally(finally) {ASSERT(stmt);} + TryStmtNode(size_t pos, StmtNode *stmt, CatchClause *catches, StmtNode *finally): + StmtNode(pos, Try), stmt(stmt), catches(catches), finally(finally) {ASSERT(stmt);} - void print(PrettyPrinter &f, bool noSemi) const; - }; + void print(PrettyPrinter &f, bool noSemi) const; + }; - struct IdentifierList: ArenaObject { - IdentifierList *next; // Next identifier in linked list - const StringAtom &name; // The identifier + struct IdentifierList: ArenaObject { + IdentifierList *next; // Next identifier in linked list + const StringAtom &name; // The identifier - explicit IdentifierList(const StringAtom &name): next(0), name(name) {} - }; + explicit IdentifierList(const StringAtom &name): next(0), name(name) {} + }; - struct PackageName: ArenaObject { // Either idList or str may be null, but not both - IdentifierList *idList; // The package name as an identifier list - String *str; // The package name as a string + struct PackageName: ArenaObject { // Either idList or str may be null, but not both + IdentifierList *idList; // The package name as an identifier list + String *str; // The package name as a string - explicit PackageName(IdentifierList *idList): idList(idList), str(0) {ASSERT(idList);} - explicit PackageName(String &str): idList(0), str(&str) {} - }; + explicit PackageName(IdentifierList *idList): idList(idList), str(0) {ASSERT(idList);} + explicit PackageName(String &str): idList(0), str(&str) {} + }; - struct ImportBinding: ParseNode { - ImportBinding *next; // Next binding in a linked list of import bindings - const StringAtom *name; // The package variable's name; nil if omitted - PackageName &packageName; // The package's name + struct ImportBinding: ParseNode { + ImportBinding *next; // Next binding in a linked list of import bindings + const StringAtom *name; // The package variable's name; nil if omitted + PackageName &packageName; // The package's name - ImportBinding(uint32 pos, const StringAtom *name, PackageName &packageName): - ParseNode(pos), next(0), name(name), packageName(packageName) {} - }; + ImportBinding(size_t pos, const StringAtom *name, PackageName &packageName): + ParseNode(pos), next(0), name(name), packageName(packageName) {} + }; - struct ImportStmtNode: StmtNode { - ImportBinding *bindings; // Linked list of import bindings + struct ImportStmtNode: StmtNode { + ImportBinding *bindings; // Linked list of import bindings - ImportStmtNode(uint32 pos, Kind kind, ImportBinding *bindings): - StmtNode(pos, kind), bindings(bindings) {} - }; + ImportStmtNode(size_t pos, Kind kind, ImportBinding *bindings): + StmtNode(pos, kind), bindings(bindings) {} + }; - struct UseStmtNode: StmtNode { - ExprList *exprs; // Linked list of namespace expressions + struct UseStmtNode: StmtNode { + ExprList *exprs; // Linked list of namespace expressions - UseStmtNode(uint32 pos, Kind kind, ExprList *exprs): StmtNode(pos, kind), exprs(exprs) {} - }; + UseStmtNode(size_t pos, Kind kind, ExprList *exprs): StmtNode(pos, kind), exprs(exprs) {} + }; - struct ExportBinding: ParseNode { - ExportBinding *next; // Next binding in a linked list of export bindings - FunctionName name; // The exported variable's name - FunctionName *initializer; // The original variable's name or nil if not provided + struct ExportBinding: ParseNode { + ExportBinding *next; // Next binding in a linked list of export bindings + FunctionName name; // The exported variable's name + FunctionName *initializer; // The original variable's name or nil if not provided - ExportBinding(uint32 pos, FunctionName *initializer): - ParseNode(pos), next(0), initializer(initializer) {} - }; + ExportBinding(size_t pos, FunctionName *initializer): + ParseNode(pos), next(0), initializer(initializer) {} + }; - struct ExportStmtNode: AttributeStmtNode { - ExportBinding *bindings; // Linked list of export bindings + struct ExportStmtNode: AttributeStmtNode { + ExportBinding *bindings; // Linked list of export bindings - ExportStmtNode(uint32 pos, Kind kind, ExprList *attributes, ExportBinding *bindings): - AttributeStmtNode(pos, kind, attributes), bindings(bindings) {} - }; + ExportStmtNode(size_t pos, Kind kind, ExprList *attributes, ExportBinding *bindings): + AttributeStmtNode(pos, kind, attributes), bindings(bindings) {} + }; - struct VariableStmtNode: AttributeStmtNode { - VariableBinding *bindings; // Linked list of variable bindings + struct VariableStmtNode: AttributeStmtNode { + VariableBinding *bindings; // Linked list of variable bindings - VariableStmtNode(uint32 pos, Kind kind, ExprList *attributes, VariableBinding *bindings): - AttributeStmtNode(pos, kind, attributes), bindings(bindings) {} + VariableStmtNode(size_t pos, Kind kind, ExprList *attributes, VariableBinding *bindings): + AttributeStmtNode(pos, kind, attributes), bindings(bindings) {} - void print(PrettyPrinter &f, bool noSemi) const; - }; + void print(PrettyPrinter &f, bool noSemi) const; + }; - struct FunctionStmtNode: AttributeStmtNode { - FunctionDefinition function; // Function definition + struct FunctionStmtNode: AttributeStmtNode { + FunctionDefinition function; // Function definition JS2Runtime::JSFunction *mFunction; // used by backend - FunctionStmtNode(uint32 pos, Kind kind, ExprList *attributes): AttributeStmtNode(pos, kind, attributes) {} + FunctionStmtNode(size_t pos, Kind kind, ExprList *attributes): AttributeStmtNode(pos, kind, attributes) {} - void print(PrettyPrinter &f, bool noSemi) const; - }; + void print(PrettyPrinter &f, bool noSemi) const; + }; - struct NamespaceStmtNode: AttributeStmtNode { - ExprNode *name; // The namespace's, interfaces, or class's name; non-nil only - ExprList *supers; // Linked list of supernamespace or superinterface expressions + struct NamespaceStmtNode: AttributeStmtNode { + ExprNode *name; // The namespace's, interfaces, or class's name; non-nil only + ExprList *supers; // Linked list of supernamespace or superinterface expressions - NamespaceStmtNode(uint32 pos, Kind kind, ExprList *attributes, ExprNode *name, ExprList *supers): - AttributeStmtNode(pos, kind, attributes), name(name), supers(supers) {ASSERT(name);} + NamespaceStmtNode(size_t pos, Kind kind, ExprList *attributes, ExprNode *name, ExprList *supers): + AttributeStmtNode(pos, kind, attributes), name(name), supers(supers) {ASSERT(name);} - void print(PrettyPrinter &f, bool noSemi) const; - }; + void print(PrettyPrinter &f, bool noSemi) const; + }; - struct ClassStmtNode: NamespaceStmtNode { - ExprNode *superclass; // Superclass expression (classes only); nil if omitted - BlockStmtNode *body; // The class's body; nil if omitted + struct ClassStmtNode: NamespaceStmtNode { + ExprNode *superclass; // Superclass expression (classes only); nil if omitted + BlockStmtNode *body; // The class's body; nil if omitted JS2Runtime::JSType *mType; // used by backend - ClassStmtNode(uint32 pos, Kind kind, ExprList *attributes, ExprNode *name, ExprNode *superclass, - ExprList *superinterfaces, BlockStmtNode *body): - NamespaceStmtNode(pos, kind, attributes, name, superinterfaces), superclass(superclass), body(body) {} + ClassStmtNode(size_t pos, Kind kind, ExprList *attributes, ExprNode *name, ExprNode *superclass, + ExprList *superinterfaces, BlockStmtNode *body): + NamespaceStmtNode(pos, kind, attributes, name, superinterfaces), superclass(superclass), body(body) {} - void print(PrettyPrinter &f, bool noSemi) const; - }; + void print(PrettyPrinter &f, bool noSemi) const; + }; - struct LanguageStmtNode: StmtNode { - JavaScript::Language language; // The selected language + struct LanguageStmtNode: StmtNode { + JavaScript::Language language; // The selected language - LanguageStmtNode(uint32 pos, Kind kind, JavaScript::Language language): - StmtNode(pos, kind), language(language) {} - }; + LanguageStmtNode(size_t pos, Kind kind, JavaScript::Language language): + StmtNode(pos, kind), language(language) {} + }; - struct PackageStmtNode: StmtNode { - PackageName &packageName; // The package's name - BlockStmtNode *body; // The package's body; non-nil only + struct PackageStmtNode: StmtNode { + PackageName &packageName; // The package's name + BlockStmtNode *body; // The package's body; non-nil only - PackageStmtNode(uint32 pos, Kind kind, PackageName &packageName, BlockStmtNode *body): - StmtNode(pos, kind), packageName(packageName), body(body) {ASSERT(body);} - }; + PackageStmtNode(size_t pos, Kind kind, PackageName &packageName, BlockStmtNode *body): + StmtNode(pos, kind), packageName(packageName), body(body) {ASSERT(body);} + }; - class Parser { - public: - Lexer lexer; - Arena &arena; - bool lineBreaksSignificant; // If false, line breaks between tokens are treated as though they were spaces instead + class Parser { + public: + Lexer lexer; + Arena &arena; + bool lineBreaksSignificant; // If false, line breaks between tokens are treated as though they were spaces instead - Parser(World &world, Arena &arena, const String &source, const String &sourceLocation, uint32 initialLineNum = 1); + Parser(World &world, Arena &arena, const String &source, const String &sourceLocation, uint32 initialLineNum = 1); - private: - Reader &getReader() {return lexer.reader;} - World &getWorld() {return lexer.world;} + private: + Reader &getReader() {return lexer.reader;} + World &getWorld() {return lexer.world;} - public: - void syntaxError(const char *message, uint backUp = 1); - void syntaxError(const String &message, uint backUp = 1); - const Token &require(bool preferRegExp, Token::Kind kind); - private: - String ©TokenChars(const Token &t); - bool lineBreakBefore(const Token &t) const {return lineBreaksSignificant && t.getLineBreak();} - bool lineBreakBefore() {return lineBreaksSignificant && lexer.peek(true).getLineBreak();} + public: + void syntaxError(const char *message, uint backUp = 1); + void syntaxError(const String &message, uint backUp = 1); + const Token &require(bool preferRegExp, Token::Kind kind); + private: + String ©TokenChars(const Token &t); + bool lineBreakBefore(const Token &t) const {return lineBreaksSignificant && t.getLineBreak();} + bool lineBreakBefore() {return lineBreaksSignificant && lexer.peek(true).getLineBreak();} - enum SuperState { - ssNone, // No super operator - ssExpr, // super or super(expr) - ssStmt // super or super(expr) or super(arguments) - }; + enum SuperState { + ssNone, // No super operator + ssExpr, // super or super(expr) + ssStmt // super or super(expr) or super(arguments) + }; - enum Precedence { - pNone, // End tag - pExpression, // ListExpression - 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 - }; + enum Precedence { + pNone, // End tag + pExpression, // ListExpression + 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 - bool superLeft; // True if the left operand can be a SuperExpression - }; + 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 + bool superLeft; // True if the left operand can be a SuperExpression + }; - static const BinaryOperatorInfo tokenBinaryOperatorInfos[Token::kindsEnd]; - struct StackedSubexpression; + static const BinaryOperatorInfo tokenBinaryOperatorInfos[Token::kindsEnd]; + struct StackedSubexpression; - ExprNode *makeIdentifierExpression(const Token &t) const; - ExprNode *parseIdentifier(); - ExprNode *parseIdentifierQualifiers(ExprNode *e, bool &foundQualifiers, bool preferRegExp); - ExprNode *parseParenthesesAndIdentifierQualifiers(const Token &tParen, bool noComma, bool &foundQualifiers, bool preferRegExp); - ExprNode *parseQualifiedIdentifier(const Token &t, bool preferRegExp); - PairListExprNode *parseArrayLiteral(const Token &initialToken); - PairListExprNode *parseObjectLiteral(const Token &initialToken); - ExprNode *parseUnitSuffixes(ExprNode *e); - ExprNode *parseSuper(uint32 pos, SuperState superState); - ExprNode *parsePrimaryExpression(SuperState superState); - ExprNode *parseMember(ExprNode *target, const Token &tOperator, bool preferRegExp); - InvokeExprNode *parseInvoke(ExprNode *target, uint32 pos, Token::Kind closingTokenKind, ExprNode::Kind invokeKind); - ExprNode *parsePostfixOperator(ExprNode *e, bool newExpression, bool attribute); - ExprNode *parsePostfixExpression(SuperState superState, bool newExpression); - void ensurePostfix(const ExprNode *e); - ExprNode *parseAttribute(const Token &t); - static bool expressionIsAttribute(const ExprNode *e); - ExprNode *parseUnaryExpression(SuperState superState); - ExprNode *parseGeneralExpression(bool allowSuperStmt, bool noIn, bool noAssignment, bool noComma); - public: - ExprNode *parseListExpression(bool noIn) {return parseGeneralExpression(false, noIn, false, false);} - ExprNode *parseAssignmentExpression(bool noIn) {return parseGeneralExpression(false, noIn, false, true);} - ExprNode *parseNonAssignmentExpression(bool noIn) {return parseGeneralExpression(false, noIn, true, true);} + ExprNode *makeIdentifierExpression(const Token &t) const; + ExprNode *parseIdentifier(); + ExprNode *parseIdentifierQualifiers(ExprNode *e, bool &foundQualifiers, bool preferRegExp); + ExprNode *parseParenthesesAndIdentifierQualifiers(const Token &tParen, bool noComma, bool &foundQualifiers, bool preferRegExp); + ExprNode *parseQualifiedIdentifier(const Token &t, bool preferRegExp); + PairListExprNode *parseArrayLiteral(const Token &initialToken); + PairListExprNode *parseObjectLiteral(const Token &initialToken); + ExprNode *parseUnitSuffixes(ExprNode *e); + ExprNode *parseSuper(size_t pos, SuperState superState); + ExprNode *parsePrimaryExpression(SuperState superState); + ExprNode *parseMember(ExprNode *target, const Token &tOperator, bool preferRegExp); + InvokeExprNode *parseInvoke(ExprNode *target, size_t pos, Token::Kind closingTokenKind, ExprNode::Kind invokeKind); + ExprNode *parsePostfixOperator(ExprNode *e, bool newExpression, bool attribute); + ExprNode *parsePostfixExpression(SuperState superState, bool newExpression); + void ensurePostfix(const ExprNode *e); + ExprNode *parseAttribute(const Token &t); + static bool expressionIsAttribute(const ExprNode *e); + ExprNode *parseUnaryExpression(SuperState superState); + ExprNode *parseGeneralExpression(bool allowSuperStmt, bool noIn, bool noAssignment, bool noComma); + public: + ExprNode *parseListExpression(bool noIn) {return parseGeneralExpression(false, noIn, false, false);} + ExprNode *parseAssignmentExpression(bool noIn) {return parseGeneralExpression(false, noIn, false, true);} + ExprNode *parseNonAssignmentExpression(bool noIn) {return parseGeneralExpression(false, noIn, true, true);} - private: - ExprNode *parseParenthesizedListExpression(); - ExprNode *parseTypeExpression(bool noIn=false); - const StringAtom &parseTypedIdentifier(ExprNode *&type); - ExprNode *parseTypeBinding(Token::Kind kind, bool noIn); - ExprList *parseTypeListBinding(Token::Kind kind); - VariableBinding *parseVariableBinding(bool noQualifiers, bool noIn, bool constant); - void parseFunctionName(FunctionName &fn); - void parseFunctionSignature(FunctionDefinition &fd); + private: + ExprNode *parseParenthesizedListExpression(); + ExprNode *parseTypeExpression(bool noIn=false); + const StringAtom &parseTypedIdentifier(ExprNode *&type); + ExprNode *parseTypeBinding(Token::Kind kind, bool noIn); + ExprList *parseTypeListBinding(Token::Kind kind); + VariableBinding *parseVariableBinding(bool noQualifiers, bool noIn, bool constant); + void parseFunctionName(FunctionName &fn); + void parseFunctionSignature(FunctionDefinition &fd); - enum SemicolonState {semiNone, semiNoninsertable, semiInsertable}; - enum AttributeStatement {asAny, asBlock, asConstVar}; - StmtNode *parseBlockContents(bool inSwitch, bool noCloseBrace); - BlockStmtNode *parseBody(SemicolonState *semicolonState); - ExprNode::Kind validateOperatorName(const Token &name); - StmtNode *parseAttributeStatement(uint32 pos, ExprList *attributes, const Token &t, bool noIn, SemicolonState &semicolonState); - StmtNode *parseAttributesAndStatement(uint32 pos, ExprNode *e, AttributeStatement as, SemicolonState &semicolonState); - StmtNode *parseFor(uint32 pos, SemicolonState &semicolonState); - StmtNode *parseTry(uint32 pos); + enum SemicolonState {semiNone, semiNoninsertable, semiInsertable}; + enum AttributeStatement {asAny, asBlock, asConstVar}; + StmtNode *parseBlockContents(bool inSwitch, bool noCloseBrace); + BlockStmtNode *parseBody(SemicolonState *semicolonState); + ExprNode::Kind validateOperatorName(const Token &name); + StmtNode *parseAttributeStatement(size_t pos, ExprList *attributes, const Token &t, bool noIn, SemicolonState &semicolonState); + StmtNode *parseAttributesAndStatement(size_t pos, ExprNode *e, AttributeStatement as, SemicolonState &semicolonState); + StmtNode *parseFor(size_t pos, SemicolonState &semicolonState); + StmtNode *parseTry(size_t pos); - public: - StmtNode *parseStatement(bool directive, bool inSwitch, SemicolonState &semicolonState); - StmtNode *parseStatementAndSemicolon(SemicolonState &semicolonState); - StmtNode *parseProgram() {return parseBlockContents(false, true);} + public: + StmtNode *parseStatement(bool directive, bool inSwitch, SemicolonState &semicolonState); + StmtNode *parseStatementAndSemicolon(SemicolonState &semicolonState); + StmtNode *parseProgram() {return parseBlockContents(false, true);} - private: - bool lookahead(Token::Kind kind, bool preferRegExp=true); - const Token *match(Token::Kind kind, bool preferRegExp=true); - ExprPairList *parseLiteralField(); - ExprNode *parseFieldName(); - VariableBinding *parseAllParameters(FunctionDefinition &fd, NodeQueue ¶ms); - VariableBinding *parseNamedParameters(FunctionDefinition &fd, NodeQueue ¶ms); - VariableBinding *parseRestParameter(); - VariableBinding *parseParameter(); - VariableBinding *parseOptionalNamedRestParameters(FunctionDefinition &fd, NodeQueue ¶ms); - VariableBinding *parseNamedRestParameters(FunctionDefinition &fd, NodeQueue ¶ms); - VariableBinding *parseOptionalParameter(); - VariableBinding *parseOptionalParameterPrime(VariableBinding *binding); - VariableBinding *parseNamedParameter(NodeQueue &aliases); - ExprNode *parseResultSignature(); - }; + private: + bool lookahead(Token::Kind kind, bool preferRegExp=true); + const Token *match(Token::Kind kind, bool preferRegExp=true); + ExprPairList *parseLiteralField(); + ExprNode *parseFieldName(); + VariableBinding *parseAllParameters(FunctionDefinition &fd, NodeQueue ¶ms); + VariableBinding *parseNamedParameters(FunctionDefinition &fd, NodeQueue ¶ms); + VariableBinding *parseRestParameter(); + VariableBinding *parseParameter(); + VariableBinding *parseOptionalNamedRestParameters(FunctionDefinition &fd, NodeQueue ¶ms); + VariableBinding *parseNamedRestParameters(FunctionDefinition &fd, NodeQueue ¶ms); + VariableBinding *parseOptionalParameter(); + VariableBinding *parseOptionalParameterPrime(VariableBinding *binding); + VariableBinding *parseNamedParameter(NodeQueue &aliases); + ExprNode *parseResultSignature(); + }; } #endif /* parser_h___ */ diff --git a/mozilla/js2/src/reader.cpp b/mozilla/js2/src/reader.cpp index 2adf1dd4b66..968f20e6f85 100644 --- a/mozilla/js2/src/reader.cpp +++ b/mozilla/js2/src/reader.cpp @@ -65,15 +65,14 @@ void JS::Reader::beginLine() // Return the number of the line containing the given character position. // The line starts should have been recorded by calling beginLine. -uint32 JS::Reader::posToLineNum(uint32 pos) const +uint32 JS::Reader::posToLineNum(size_t pos) const { ASSERT(pos <= getPos()); std::vector::const_iterator i = std::upper_bound(linePositions.begin(), linePositions.end(), begin + pos); ASSERT(i != linePositions.begin()); - return static_cast(i-1 - linePositions.begin()) + - initialLineNum; + return static_cast(i-1 - linePositions.begin()) + initialLineNum; } @@ -84,7 +83,7 @@ uint32 JS::Reader::posToLineNum(uint32 pos) const // manually finds the line ending by searching for a line break; otherwise, // getLine assumes that the line ends one character before the beginning // of the next line. -uint32 JS::Reader::getLine(uint32 lineNum, const char16 *&lineBegin, const char16 *&lineEnd) const +size_t JS::Reader::getLine(uint32 lineNum, const char16 *&lineBegin, const char16 *&lineEnd) const { lineBegin = 0; lineEnd = 0; @@ -106,7 +105,7 @@ uint32 JS::Reader::getLine(uint32 lineNum, const char16 *&lineBegin, const char1 ++e; } lineEnd = e; - return static_cast(lineBegin - begin); + return toSize_t(lineBegin - begin); } @@ -156,12 +155,12 @@ JS::String &JS::Reader::endRecording() // Report an error at the given character position in the source code. -void JS::Reader::error(Exception::Kind kind, const String &message, uint32 pos) +void JS::Reader::error(Exception::Kind kind, const String &message, size_t pos) { uint32 lineNum = posToLineNum(pos); const char16 *lineBegin; const char16 *lineEnd; - uint32 linePos = getLine(lineNum, lineBegin, lineEnd); + size_t linePos = getLine(lineNum, lineBegin, lineEnd); ASSERT(lineBegin && lineEnd && linePos <= pos); throw Exception(kind, message, sourceLocation, lineNum, pos - linePos, pos, lineBegin, lineEnd); diff --git a/mozilla/js2/src/reader.h b/mozilla/js2/src/reader.h index cae4e860e55..a33b60d6580 100644 --- a/mozilla/js2/src/reader.h +++ b/mozilla/js2/src/reader.h @@ -69,9 +69,9 @@ namespace JavaScript { char16 get() {ASSERT(p <= end);return *p++;} char16 peek() {ASSERT(p <= end); return *p;} - void unget(uint32 n = 1) {ASSERT(p >= begin + n); p -= n;} - uint32 getPos() const {return static_cast(p - begin);} - void setPos(uint32 pos) {ASSERT(pos <= getPos()); p = begin + pos;} + void unget(size_t n = 1) {ASSERT(p >= begin + n); p -= n;} + size_t getPos() const {return toSize_t(p - begin);} + void setPos(size_t pos) {ASSERT(pos <= getPos()); p = begin + pos;} bool eof() const {ASSERT(p <= end); return p == end;} bool peekEof(char16 ch) const { @@ -85,13 +85,13 @@ namespace JavaScript { ASSERT(p[-1] == ch); return !ch && p == end+1; } void beginLine(); - uint32 posToLineNum(uint32 pos) const; - uint32 getLine(uint32 lineNum, const char16 *&lineBegin, const char16 *&lineEnd) const; + uint32 posToLineNum(size_t pos) const; + size_t getLine(uint32 lineNum, const char16 *&lineBegin, const char16 *&lineEnd) const; void beginRecording(String &recordString); void recordChar(char16 ch); String &endRecording(); - void error(Exception::Kind kind, const String &message, uint32 pos); + void error(Exception::Kind kind, const String &message, size_t pos); }; diff --git a/mozilla/js2/src/token.h b/mozilla/js2/src/token.h index 5f9459b7e4a..68084b7573b 100644 --- a/mozilla/js2/src/token.h +++ b/mozilla/js2/src/token.h @@ -229,7 +229,7 @@ namespace JavaScript #endif Kind kind; // The token's kind bool lineBreak; // True if line break precedes this token - uint32 pos; // Source position of this token + size_t pos; // Source position of this token const StringAtom *id; // The token's characters; non-nil for identifiers, keywords, and regular expressions only String chars; // The token's characters; valid for strings, units, numbers, and regular expression flags only float64 value; // The token's value (numbers only) @@ -247,7 +247,7 @@ namespace JavaScript bool hasIdentifierKind() const {ASSERT(nonreservedEnd == identifier && kindsEnd == identifier+1); return kind >= nonreservedBegin;} bool getFlag(Flag f) const {ASSERT(valid); return (kindFlags[kind] & 1<= kindsWithCharsBegin && kind < kindsWithCharsEnd); return chars;} float64 getValue() const {ASSERT(valid && kind == number); return value;}