WIP: Implemented update_expression, unary_expression
MozReview-Commit-ID: ANe7hFHKHGy
--- a/js/src/frontend/BinSource.cpp
+++ b/js/src/frontend/BinSource.cpp
@@ -124,16 +124,17 @@ private:
bool parseExpressionAux(SimpleTokenReader* reader, const BinKind kind, const SimpleTokenReader::BinFields& fields, UniquePtr<ParseNode>& out);
bool parseVariableDeclarationAux(SimpleTokenReader* reader, const BinKind kind, const SimpleTokenReader::BinFields& fields, UniquePtr<ParseNode>& out);
// --- Utilities.
bool readString(SimpleTokenReader* reader, std::string&);
bool readString(SimpleTokenReader* reader, MutableHandleString);
bool readString(SimpleTokenReader* reader, MutableHandleAtom);
+ bool readBool(SimpleTokenReader* reader, Maybe<bool>&);
const Directives& currentDirectives() const;
const ReadOnlyCompileOptions& options() const;
// --- GC.
/* List of objects allocated during parsing, for GC tracing. */
ObjectBox* traceListHead;
@@ -1223,21 +1224,117 @@ ASTReader::parseExpression(SimpleTokenRe
break;
case BinKind::object_expression:
// FIXME: Implement
break;
case BinKind::function_expression:
// FIXME: Implement
break;
case BinKind::unary_expression:
- // FIXME: Implement
+ case BinKind::update_expression: {
+
+ UniquePtr<ParseNode> expr;
+ std::string operation;
+ Maybe<bool> prefix; // FIXME: Ignored for unary_expression?
+
+ for (auto field: fields) {
+ switch (field) {
+ case BinField::operator_:
+ if (!this->readString(&sub, operation)) {
+ return false;
+ }
+ break;
+ case BinField::prefix:
+ if (!this->readBool(&sub, prefix)) {
+ return false;
+ }
+ break;
+ case BinField::argument:
+ if (!this->parseExpression(&sub, expr)) {
+ return false;
+ }
+ break;
+ default:
+ return this->raiseError();
+ }
+ }
+
+ if (!expr || operation.length() == 0 || !prefix.isSome()) {
+ return this->raiseError();
+ }
+
+ ParseNodeKind pnk = PNK_LIMIT;
+ JSOp op = JSOP_NOP;
+ if (kind == BinKind::unary_expression) {
+ if (operation == "-") {
+ pnk = PNK_NEG;
+ op = JSOP_NEG;
+ } else if (operation == "+") {
+ pnk = PNK_POS;
+ op = JSOP_POS;
+ } else if (operation == "!") {
+ pnk = PNK_NOT;
+ op = JSOP_NOT;
+ } else if (operation == "~") {
+ pnk = PNK_BITNOT;
+ op = JSOP_BITNOT;
+ } else if (operation == "typeof") {
+ if (expr->isKind(PNK_NAME)) {
+ pnk = PNK_TYPEOFNAME;
+ } else {
+ pnk = PNK_TYPEOFEXPR;
+ }
+ } else if (operation == "void") {
+ pnk = PNK_VOID;
+ op = JSOP_VOID;
+ } else if (operation == "delete") {
+ switch (expr->getKind()) {
+ case PNK_NAME:
+ expr->setOp(JSOP_DELNAME);
+ pnk = PNK_DELETENAME;
+ break;
+ case PNK_DOT:
+ pnk = PNK_DELETEPROP;
+ break;
+ case PNK_ELEM:
+ pnk = PNK_DELETEELEM;
+ break;
+ default:
+ pnk = PNK_DELETEEXPR;
+ }
+ } else {
+ return this->raiseError();
+ }
+ } else if (kind == BinKind::update_expression) {
+ if (operation == "++") {
+ if (*prefix) {
+ pnk = PNK_PREINCREMENT;
+ } else {
+ pnk = PNK_PREDECREMENT;
+ }
+ } else if (operation == "--") {
+ if (*prefix) {
+ pnk = PNK_PREDECREMENT;
+ } else {
+ pnk = PNK_POSTDECREMENT;
+ }
+ } else {
+ return this->raiseError();
+ }
+ }
+
+ UniquePtr<ParseNode> result(new_<UnaryNode>(pnk, op, TokenPos(), expr.get()));
+ if (!result) {
+ return false;
+ }
+
+ Unused << expr.release();
+ out = Move(result);
break;
- case BinKind::update_expression:
- // FIXME: Implement
- break;
+ }
case BinKind::binary_expression: MOZ_FALLTHROUGH;
case BinKind::logical_expression: {
UniquePtr<ParseNode> left;
UniquePtr<ParseNode> right;
std::string operation;
for (auto field: fields) {
switch (field) {