WIP: Implemented VarDeclaration draft
authorDavid Teller <dteller@mozilla.com>
Tue, 25 Jul 2017 15:02:41 +0200
changeset 641342 8a0ea18ab5c732d5bd0d6bf4761b5f59496f1419
parent 641341 53c8e2509c88095e3f61c8a5c8d62bfaa7700bfb
child 641343 21e5d2f1eb38fbb83b4a17d7c093c27df904ac5d
push id72504
push userdteller@mozilla.com
push dateSun, 06 Aug 2017 22:28:40 +0000
milestone57.0a1
WIP: Implemented VarDeclaration MozReview-Commit-ID: EhtRSSOZFHk
js/src/frontend/BinSource.cpp
--- a/js/src/frontend/BinSource.cpp
+++ b/js/src/frontend/BinSource.cpp
@@ -93,26 +93,29 @@ private:
     bool parseStringSet(SimpleTokenReader* reader, MutableHandle<Maybe<NameBag>>);
     bool parseStringSet(SimpleTokenReader* reader, MutableHandle<NameBag>);
     bool parseScope(SimpleTokenReader* reader, ScopeData& out);
     bool parseExpression(SimpleTokenReader* reader, UniquePtr<ParseNode>& out);
     bool parsePropertyName(SimpleTokenReader* reader, UniquePtr<PropertyName>& out);
     bool parseSwitchCaseList(SimpleTokenReader* reader, UniquePtr<ParseNode>& out);
     bool parseBlockStatement(SimpleTokenReader* reader, UniquePtr<ParseNode>&);
     bool parseCatchClause(SimpleTokenReader* reader, UniquePtr<ParseNode>&);
+    bool parseVariableDeclarator(SimpleTokenReader* reader, UniquePtr<ParseNode>&);
 
     // --- Parse the contents of a node whose kind has already been determined.
 
+    bool parseFunctionAux(SimpleTokenReader* reader, const std::string& name, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
     bool parsePatternAux(SimpleTokenReader* reader, const std::string& name, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
     bool parseBlockStatementAux(SimpleTokenReader* reader, const std::string& name, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
     bool parseExpressionStatementAux(SimpleTokenReader* reader, const std::string& name, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
     bool parseExpressionAux(SimpleTokenReader* reader, const std::string& name, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
     bool parseVariableDeclarationAux(SimpleTokenReader* reader, const std::string& name, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
 
     // --- Utilities.
+    bool readString(SimpleTokenReader* reader, std::string&);
     bool readString(SimpleTokenReader* reader, MutableHandleString);
 
     const ReadOnlyCompileOptions& options() const;
 
     ParseNodeAllocator allocator;
 
     ParseNode* allocParseNode(size_t size) {
         MOZ_ASSERT(size == sizeof(ParseNode));
@@ -876,29 +879,117 @@ ASTReader::parseStatement(SimpleTokenRea
         }
 
         Unused << forHead.release();
         Unused << body.release();
 
         out = Move(result);
 
     } else if (name == "FunctionDeclaration") {
-        // FIXME: Implement
-    } else if (name == "VariableDeclaration") {
+
         // FIXME: Implement
-    } else if (name == "SwitchStatement") {
-        // FIXME: Implement
+
+    } else if (name == "VariableDeclaration") {
+
+        if (!this->parseVariableDeclarationAux(&sub, name, &fields, out)) {
+            return false;
+        }
+
     } else {
         return this->raiseError();
     }
 
     return true;
 }
 
 bool
+ASTReader::parseVariableDeclarationAux(SimpleTokenReader* reader, const std::string& name, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out) {
+    if (!out) {
+        return this->raiseError();
+    }
+
+    ParseNodeKind kind = PNK_LIMIT;
+    JSOp op = JSOP_NOP;
+    UniquePtr<ParseNode> result;
+
+    for (auto field: *fields) {
+        if (field == "kind") {
+            std::string kindName;
+            if (!this->readString(reader, kindName)) {
+                return false;
+            }
+
+            if (kindName == "let") {
+                kind = PNK_LET;
+                op = JSOP_DEFLET;
+            } else if (kindName == "var") {
+                kind = PNK_VAR;
+                op = JSOP_DEFVAR;
+            } else if (kindName == "const") {
+                kind = PNK_CONST;
+                op = JSOP_DEFCONST;
+            } else {
+                return this->raiseError();
+            }
+        } else if (field == "declarations") {
+            if (result) {
+                // Already parsed.
+                return this->raiseError();
+            }
+
+            uint32_t length;
+            SimpleTokenReader sub(this->cx);
+
+            if (!reader->readList(&length, &sub)) {
+                return false;
+            }
+
+            if (length == 0) {
+                return this->raiseError();
+            }
+
+            UniquePtr<ParseNode> root(new_<ListNode>(PNK_LIMIT /*Placeholder*/, JSOP_NOP/*Placeholder*/, TokenPos()));
+            if (!root) {
+                return false;
+            }
+
+            UniquePtr<ParseNode> first;
+            if (!this->parseVariableDeclarator(&sub, first)) {
+                return false;
+            }
+            root->initList(first.release());
+
+
+            for (uint32_t i = 1; i < length; ++i) {
+                UniquePtr<ParseNode> current;
+                if (!this->parseVariableDeclarator(&sub, current)) {
+                    return false;
+                }
+                if (!current) {
+                    return this->raiseError();
+                }
+                root->append(current.release());
+            }
+
+            result = Move(root);
+        }
+    }
+
+    if (!result || kind == PNK_LIMIT) {
+        return this->raiseError();
+    }
+
+    result->setKind(kind);
+    result->setOp(op);
+    out = Move(result);
+
+    return true;
+}
+
+bool
 ASTReader::parseBool(SimpleTokenReader* reader, Maybe<bool>* result) {
     if (result->isSome()) {
         // Already parsed.
         // FIXME: Can replace with an assert once we have
         // implemented headers and header validation.
         return this->raiseError();
     }
     return reader->readBool(result);