WIP: Implemented conditional_expression draft
authorDavid Teller <dteller@mozilla.com>
Thu, 27 Jul 2017 17:35:37 +0200
changeset 641351 cb9e3aff091eed8a3301a5ebccb90fb1276e9c96
parent 641350 e9bd3751d046092ca1fa2a452e77cd36b20da009
child 641352 fc49c4f1318e40ece0f3051df3f05279f029b684
push id72504
push userdteller@mozilla.com
push dateSun, 06 Aug 2017 22:28:40 +0000
milestone57.0a1
WIP: Implemented conditional_expression MozReview-Commit-ID: 3bdfFanil6d
js/src/frontend/BinSource.cpp
--- a/js/src/frontend/BinSource.cpp
+++ b/js/src/frontend/BinSource.cpp
@@ -1224,93 +1224,122 @@ ASTReader::parseExpression(SimpleTokenRe
             // FIXME: Implement
             break;
         case BinKind::unary_expression:
             // FIXME: Implement
             break;
         case BinKind::update_expression:
             // FIXME: Implement
             break;
-        case BinKind::binary_expression: {
+        case BinKind::binary_expression: MOZ_FALLTHROUGH;
+        case BinKind::logical_expression: {
 
             UniquePtr<ParseNode> left;
             UniquePtr<ParseNode> right;
-            std::string op;
+            std::string operation;
             for (auto field: fields) {
                 switch (field) {
                     case BinField::left:
                         if (!this->parseExpression(&sub, left)) {
                             return false;
                         }
                         break;
                     case BinField::right:
                         if (!this->parseExpression(&sub, right)) {
                             return false;
                         }
                         break;
                     case BinField::operator_:
-                        if (!this->readString(&sub, op)) {
+                        if (!this->readString(&sub, operation)) {
                             return false;
                         }
                         break;
                     default:
                         return this->raiseError();
                 }
             }
 
-            if (!left || !right) {
+            if (!left || !right || operation.length() == 0) {
                 return this->raiseError();
             }
 
             // FIXME: Instead of std::string, we should use atoms and comparison
             // between atom ptr.
             // FIXME: We should probably turn associative operations into lists.
             ParseNodeKind pnk = PNK_LIMIT;
-            if (op == "==") {
+            JSOp op;
+            if (operation == "==") {
                 pnk = PNK_EQ;
-            } else if (op == "!=") {
+                op = JSOP_EQ;
+            } else if (operation == "!=") {
                 pnk = PNK_NE;
-            } else if (op == "===") {
+                op = JSOP_NE;
+            } else if (operation == "===") {
                 pnk = PNK_STRICTEQ;
-            } else if (op == "!==") {
+                op = JSOP_STRICTEQ;
+            } else if (operation == "!==") {
                 pnk = PNK_STRICTNE;
-            } else if (op == "<") {
+                op = JSOP_STRICTNE;
+            } else if (operation == "<") {
                 pnk = PNK_LT;
-            } else if (op == "<=") {
+                op = JSOP_LT;
+            } else if (operation == "<=") {
                 pnk = PNK_LE;
-            } else if (op == ">") {
+                op = JSOP_LE;
+            } else if (operation == ">") {
                 pnk = PNK_GT;
-            } else if (op == ">=") {
+                op = JSOP_GT;
+            } else if (operation == ">=") {
                 pnk = PNK_GE;
-            } else if (op == "<<") {
+                op = JSOP_GE;
+            } else if (operation == "<<") {
                 pnk = PNK_LSH;
-            } else if (op == ">>") {
+                op = JSOP_LSH;
+            } else if (operation == ">>") {
                 pnk = PNK_RSH;
-            } else if (op == ">>>") {
+                op = JSOP_RSH;
+            } else if (operation == ">>>") {
                 pnk = PNK_URSH;
-            } else if (op == "+") {
+                op = JSOP_URSH;
+            } else if (operation == "+") {
                 pnk = PNK_ADD;
-            } else if (op == "-") {
+                op = JSOP_ADD;
+            } else if (operation == "-") {
                 pnk = PNK_SUB;
-            } else if (op == "*") {
+                op = JSOP_SUB;
+            } else if (operation == "*") {
                 pnk = PNK_STAR;
-            } else if (op == "/") {
+                op = JSOP_MUL;
+            } else if (operation == "/") {
                 pnk = PNK_DIV;
-            } else if (op == "%") {
+                op = JSOP_DIV;
+            } else if (operation == "%") {
                 pnk = PNK_MOD;
-            } else if (op == "|") {
+                op = JSOP_MOD;
+            } else if (operation == "|") {
                 pnk = PNK_BITOR;
-            } else if (op == "^") {
+                op = JSOP_BITOR;
+            } else if (operation == "^") {
                 pnk = PNK_BITXOR;
-            } else if (op == "&") {
+                op = JSOP_BITXOR;
+            } else if (operation == "&") {
                 pnk = PNK_BITAND;
-            } else if (op == "in") {
+                op = JSOP_BITAND;
+            } else if (operation == "in") {
                 pnk = PNK_IN;
-            } else if (op == "instanceof") {
+                op = JSOP_IN;
+            } else if (operation == "instanceof") {
                 pnk = PNK_INSTANCEOF;
+                op = JSOP_INSTANCEOF;
+            } else if (operation == "||") {
+                pnk = PNK_OR;
+                op = JSOP_OR;
+            } else if (operation == "&&" ) {
+                pnk = PNK_AND;
+                op = JSOP_AND;
             } else {
                 return this->raiseError();
             }
 
             UniquePtr<ParseNode> list(new_<ListNode>(pnk, JSOP_NOP, TokenPos()));
             if (!list) {
                 return false;
             }
@@ -1318,91 +1347,143 @@ ASTReader::parseExpression(SimpleTokenRe
             list->append(left.release());
             list->append(right.release());
             out = Move(list);
             break;
         }
         case BinKind::assignment_expression: {
             UniquePtr<ParseNode> left;
             UniquePtr<ParseNode> right;
-            std::string op;
+            std::string operation;
             for (auto field: fields) {
                 switch (field) {
                     case BinField::left:
                         if (!this->parseExpression(&sub, left)) {
                             return false;
                         }
                         break;
                     case BinField::right:
                         if (!this->parseExpression(&sub, right)) {
                             return false;
                         }
                         break;
                     case BinField::operator_:
-                        if (!this->readString(&sub, op)) {
+                        if (!this->readString(&sub, operation)) {
                             return false;
                         }
                         break;
                     default:
                         return this->raiseError();
                 }
             }
 
-            if (!left || !right) {
+            if (!left || !right || operation.length() == 0) {
                 return this->raiseError();
             }
 
             // FIXME: Instead of std::string, we should use atoms and comparison
             // between atom ptr.
             // FIXME: We should probably turn associative operations into lists.
             ParseNodeKind pnk = PNK_LIMIT;
-            if (op == "=") {
+            JSOp op = JSOP_NOP;
+            if (operation == "=") {
                 pnk = PNK_ASSIGN;
-            } else if (op == "+=") {
+            } else if (operation == "+=") {
                 pnk = PNK_ADDASSIGN;
-            } else if (op == "-=") {
+                op = JSOP_ADD;
+            } else if (operation == "-=") {
                 pnk = PNK_SUBASSIGN;
-            } else if (op == "*=") {
+                op = JSOP_SUB;
+            } else if (operation == "*=") {
                 pnk = PNK_MULASSIGN;
-            } else if (op == "/=") {
+                op = JSOP_MUL;
+            } else if (operation == "/=") {
                 pnk = PNK_DIVASSIGN;
-            } else if (op == "%=") {
+                op = JSOP_DIV;
+            } else if (operation == "%=") {
                 pnk = PNK_MODASSIGN;
-            } else if (op == "<<=") {
+                op = JSOP_MOD;
+            } else if (operation == "<<=") {
                 pnk = PNK_LSHASSIGN;
-            } else if (op == ">>=") {
+                op = JSOP_LSH;
+            } else if (operation == ">>=") {
                 pnk = PNK_RSHASSIGN;
-            } else if (op == ">>>=") {
+                op = JSOP_RSH;
+            } else if (operation == ">>>=") {
                 pnk = PNK_URSHASSIGN;
-            } else if (op == "|=") {
+                op = JSOP_URSH;
+            } else if (operation == "|=") {
                 pnk = PNK_BITORASSIGN;
-            } else if (op == "^=") {
+                op = JSOP_BITOR;
+            } else if (operation == "^=") {
                 pnk = PNK_BITXORASSIGN;
-            } else if (op == "&=") {
+                op = JSOP_BITXOR;
+            } else if (operation == "&=") {
                 pnk = PNK_BITANDASSIGN;
+                op = JSOP_BITAND;
             } else {
                 return this->raiseError();
             }
 
             UniquePtr<ParseNode> list(new_<BinaryNode>(pnk, JSOP_NOP, TokenPos(), left.get(), right.get()));
             if (!list) {
                 return false;
             }
             Unused << left.release();
             Unused << right.release();
+
+            out = Move(list);
+            break;
         }
-        case BinKind::logical_expression:
-            // FIXME: Implement
-            break;
         case BinKind::member_expression:
             // FIXME: Implement
             break;
-        case BinKind::conditional_expression:
-            // FIXME: Implement
+        case BinKind::conditional_expression: {
+            UniquePtr<ParseNode> test;
+            UniquePtr<ParseNode> alternate;
+            UniquePtr<ParseNode> consequent;
+
+            for (auto field: fields) {
+                switch (field) {
+                    case BinField::test:
+                        if (!this->parseExpression(&sub, test)) {
+                            return false;
+                        }
+                        break;
+                    case BinField::alternate:
+                        if (!this->parseExpression(&sub, alternate)) {
+                            return false;
+                        }
+                        break;
+                    case BinField::consequent:
+                        if (!this->parseExpression(&sub, consequent)) {
+                            return false;
+                        }
+                        break;
+                    default:
+                        return this->raiseError();
+                }
+            }
+
+            if (!test || !alternate || !consequent) {
+                return this->raiseError();
+            }
+
+            UniquePtr<ParseNode> result(new_<ConditionalExpression>(test.get(), consequent.get(), alternate.get()));
+            if (!result) {
+                return false;
+            }
+
+            Unused << test.release();
+            Unused << alternate.release();
+            Unused << consequent.release();
+
+            out = Move(result);
             break;
+        }
         case BinKind::call_expression:
             // FIXME: Implement
             break;
         case BinKind::new_expression:
             // FIXME: Implement
             break;
         case BinKind::sequence_expression:
             // FIXME: Implement