WIP: Implemented update_expression, unary_expression draft
authorDavid Teller <dteller@mozilla.com>
Thu, 27 Jul 2017 18:02:57 +0200
changeset 641353 b10ce742139f4d35d90061e4f6196dc1dfed1b95
parent 641352 fc49c4f1318e40ece0f3051df3f05279f029b684
child 641354 6faae396314578fcf132db439b071dfed4b6fc2c
push id72504
push userdteller@mozilla.com
push dateSun, 06 Aug 2017 22:28:40 +0000
milestone57.0a1
WIP: Implemented update_expression, unary_expression MozReview-Commit-ID: ANe7hFHKHGy
js/src/frontend/BinSource.cpp
--- 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) {