--- a/js/src/frontend/BinSource.cpp
+++ b/js/src/frontend/BinSource.cpp
@@ -86,16 +86,17 @@ private:
bool parseStatementList(SimpleTokenReader* reader, UniquePtr<ParseNode>& out);
bool parseStringList(SimpleTokenReader* reader, MutableHandle<Maybe<Names>> out);
bool parseStringList(SimpleTokenReader* reader, MutableHandle<Names> out);
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);
// --- Parse the contents of a node whose kind has already been determined.
bool parseBlockStatementAux(SimpleTokenReader* reader, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
bool parseExpressionStatementAux(SimpleTokenReader* reader, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
// --- Utilities.
bool readString(SimpleTokenReader* reader, MutableHandleString);
@@ -501,19 +502,80 @@ ASTReader::parseStatement(SimpleTokenRea
UniquePtr<ParseNode> result(new_<ContinueStatement>(label.release(), TokenPos()));
if (!result) {
return false;
}
out = Move(result);
}
} else if (name == "IfStatement") {
- // FIXME: Implement
+
+ UniquePtr<ParseNode> test;
+ UniquePtr<ParseNode> consequent;
+ UniquePtr<ParseNode> alternate; // Optional
+
+ for (auto field: fields) {
+ if (field == "test") {
+ if (!this->parseExpression(&sub, test)) {
+ return false;
+ }
+ } else if (field == "consequent") {
+ if (!this->parseStatement(&sub, consequent)) {
+ return false;
+ }
+ } else if (field == "alternate") {
+ if (!this->parseStatement(&sub, alternate)) {
+ return false;
+ }
+ } else {
+ return this->raiseError();
+ }
+ }
+
+ if (!test || !consequent) {
+ // Do not test `alternate`, since that value is optional.
+ return this->raiseError();
+ }
+
+ UniquePtr<ParseNode> result(new_<TernaryNode>(PNK_IF, JSOP_NOP, test.release(), consequent.release(), alternate.release()));
+ if (!result) {
+ return false;
+ }
+ out = Move(result);
+
} else if (name == "SwitchStatement") {
- // FIXME: Implement
+
+ UniquePtr<ParseNode> discriminant;
+ UniquePtr<ParseNode> cases;
+
+ for (auto field: fields) {
+ if (field == "discriminant") {
+ if (!this->parseExpression(&sub, discriminant)) {
+ return false;
+ }
+ } else if (field == "cases") {
+ if (!this->parseSwitchCaseList(&sub, cases)) {
+ return false;
+ }
+ } else {
+ return this->raiseError();
+ }
+ }
+
+ if (!discriminant || !cases) {
+ return this->raiseError();
+ }
+
+ UniquePtr<ParseNode> result(new_<BinaryNode>(PNK_SWITCH, JSOP_NOP, TokenPos(), discriminant.release(), cases.release()));
+ if (!result) {
+ return false;
+ }
+
+ out = Move(result);
+
} else if (name == "SwitchCase") {
// FIXME: Implement
} else if (name == "ThrowStatement") {
// FIXME: Implement
} else if (name == "TryStatement") {
// FIXME: Implement
} else if (name == "WhileStatement") {
// FIXME: Implement