LCOV - code coverage report
Current view: top level - src/torque - torque-parser.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 767 817 93.9 %
Date: 2019-04-17 Functions: 93 97 95.9 %

          Line data    Source code
       1             : // Copyright 2018 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include <cctype>
       6             : 
       7             : #include "src/torque/earley-parser.h"
       8             : #include "src/torque/torque-parser.h"
       9             : #include "src/torque/utils.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : namespace torque {
      14             : 
      15       19056 : DEFINE_CONTEXTUAL_VARIABLE(CurrentAst)
      16             : 
      17             : using TypeList = std::vector<TypeExpression*>;
      18             : using GenericParameters = std::vector<Identifier*>;
      19             : 
      20        1617 : struct ExpressionWithSource {
      21             :   Expression* expression;
      22             :   std::string source;
      23             : };
      24             : 
      25         888 : struct TypeswitchCase {
      26             :   SourcePosition pos;
      27             :   base::Optional<std::string> name;
      28             :   TypeExpression* type;
      29             :   Statement* block;
      30             : };
      31             : 
      32             : template <>
      33             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<std::string>::id =
      34             :     ParseResultTypeId::kStdString;
      35             : template <>
      36             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<bool>::id =
      37             :     ParseResultTypeId::kBool;
      38             : template <>
      39             : V8_EXPORT_PRIVATE const ParseResultTypeId
      40             :     ParseResultHolder<std::vector<std::string>>::id =
      41             :         ParseResultTypeId::kStdVectorOfString;
      42             : template <>
      43             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Declaration*>::id =
      44             :     ParseResultTypeId::kDeclarationPtr;
      45             : template <>
      46             : V8_EXPORT_PRIVATE const ParseResultTypeId
      47             :     ParseResultHolder<TypeExpression*>::id =
      48             :         ParseResultTypeId::kTypeExpressionPtr;
      49             : template <>
      50             : V8_EXPORT_PRIVATE const ParseResultTypeId
      51             :     ParseResultHolder<base::Optional<TypeExpression*>>::id =
      52             :         ParseResultTypeId::kOptionalTypeExpressionPtr;
      53             : template <>
      54             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<LabelBlock*>::id =
      55             :     ParseResultTypeId::kLabelBlockPtr;
      56             : template <>
      57             : V8_EXPORT_PRIVATE const ParseResultTypeId
      58             :     ParseResultHolder<base::Optional<LabelBlock*>>::id =
      59             :         ParseResultTypeId::kOptionalLabelBlockPtr;
      60             : template <>
      61             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Expression*>::id =
      62             :     ParseResultTypeId::kExpressionPtr;
      63             : template <>
      64             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Identifier*>::id =
      65             :     ParseResultTypeId::kIdentifierPtr;
      66             : template <>
      67             : V8_EXPORT_PRIVATE const ParseResultTypeId
      68             :     ParseResultHolder<base::Optional<Identifier*>>::id =
      69             :         ParseResultTypeId::kOptionalIdentifierPtr;
      70             : template <>
      71             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Statement*>::id =
      72             :     ParseResultTypeId::kStatementPtr;
      73             : template <>
      74             : V8_EXPORT_PRIVATE const ParseResultTypeId
      75             :     ParseResultHolder<NameAndTypeExpression>::id =
      76             :         ParseResultTypeId::kNameAndTypeExpression;
      77             : template <>
      78             : V8_EXPORT_PRIVATE const ParseResultTypeId
      79             :     ParseResultHolder<NameAndExpression>::id =
      80             :         ParseResultTypeId::kNameAndExpression;
      81             : template <>
      82             : V8_EXPORT_PRIVATE const ParseResultTypeId
      83             :     ParseResultHolder<ClassFieldExpression>::id =
      84             :         ParseResultTypeId::kClassFieldExpression;
      85             : template <>
      86             : V8_EXPORT_PRIVATE const ParseResultTypeId
      87             :     ParseResultHolder<StructFieldExpression>::id =
      88             :         ParseResultTypeId::kStructFieldExpression;
      89             : template <>
      90             : V8_EXPORT_PRIVATE const ParseResultTypeId
      91             :     ParseResultHolder<std::vector<NameAndTypeExpression>>::id =
      92             :         ParseResultTypeId::kStdVectorOfNameAndTypeExpression;
      93             : template <>
      94             : V8_EXPORT_PRIVATE const ParseResultTypeId
      95             :     ParseResultHolder<std::vector<NameAndExpression>>::id =
      96             :         ParseResultTypeId::kStdVectorOfNameAndExpression;
      97             : template <>
      98             : V8_EXPORT_PRIVATE const ParseResultTypeId
      99             :     ParseResultHolder<std::vector<ClassFieldExpression>>::id =
     100             :         ParseResultTypeId::kStdVectorOfClassFieldExpression;
     101             : template <>
     102             : V8_EXPORT_PRIVATE const ParseResultTypeId
     103             :     ParseResultHolder<std::vector<StructFieldExpression>>::id =
     104             :         ParseResultTypeId::kStdVectorOfStructFieldExpression;
     105             : template <>
     106             : V8_EXPORT_PRIVATE const ParseResultTypeId
     107             :     ParseResultHolder<IncrementDecrementOperator>::id =
     108             :         ParseResultTypeId::kIncrementDecrementOperator;
     109             : template <>
     110             : V8_EXPORT_PRIVATE const ParseResultTypeId
     111             :     ParseResultHolder<base::Optional<std::string>>::id =
     112             :         ParseResultTypeId::kOptionalStdString;
     113             : template <>
     114             : V8_EXPORT_PRIVATE const ParseResultTypeId
     115             :     ParseResultHolder<std::vector<Statement*>>::id =
     116             :         ParseResultTypeId::kStdVectorOfStatementPtr;
     117             : template <>
     118             : V8_EXPORT_PRIVATE const ParseResultTypeId
     119             :     ParseResultHolder<std::vector<Declaration*>>::id =
     120             :         ParseResultTypeId::kStdVectorOfDeclarationPtr;
     121             : template <>
     122             : V8_EXPORT_PRIVATE const ParseResultTypeId
     123             :     ParseResultHolder<std::vector<Expression*>>::id =
     124             :         ParseResultTypeId::kStdVectorOfExpressionPtr;
     125             : template <>
     126             : V8_EXPORT_PRIVATE const ParseResultTypeId
     127             :     ParseResultHolder<ExpressionWithSource>::id =
     128             :         ParseResultTypeId::kExpressionWithSource;
     129             : template <>
     130             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<ParameterList>::id =
     131             :     ParseResultTypeId::kParameterList;
     132             : template <>
     133             : V8_EXPORT_PRIVATE const ParseResultTypeId
     134             :     ParseResultHolder<RangeExpression>::id =
     135             :         ParseResultTypeId::kRangeExpression;
     136             : template <>
     137             : V8_EXPORT_PRIVATE const ParseResultTypeId
     138             :     ParseResultHolder<base::Optional<RangeExpression>>::id =
     139             :         ParseResultTypeId::kOptionalRangeExpression;
     140             : template <>
     141             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<TypeList>::id =
     142             :     ParseResultTypeId::kTypeList;
     143             : template <>
     144             : V8_EXPORT_PRIVATE const ParseResultTypeId
     145             :     ParseResultHolder<base::Optional<TypeList>>::id =
     146             :         ParseResultTypeId::kOptionalTypeList;
     147             : template <>
     148             : V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<LabelAndTypes>::id =
     149             :     ParseResultTypeId::kLabelAndTypes;
     150             : template <>
     151             : V8_EXPORT_PRIVATE const ParseResultTypeId
     152             :     ParseResultHolder<std::vector<LabelAndTypes>>::id =
     153             :         ParseResultTypeId::kStdVectorOfLabelAndTypes;
     154             : template <>
     155             : V8_EXPORT_PRIVATE const ParseResultTypeId
     156             :     ParseResultHolder<std::vector<LabelBlock*>>::id =
     157             :         ParseResultTypeId::kStdVectorOfLabelBlockPtr;
     158             : template <>
     159             : V8_EXPORT_PRIVATE const ParseResultTypeId
     160             :     ParseResultHolder<base::Optional<Statement*>>::id =
     161             :         ParseResultTypeId::kOptionalStatementPtr;
     162             : template <>
     163             : V8_EXPORT_PRIVATE const ParseResultTypeId
     164             :     ParseResultHolder<base::Optional<Expression*>>::id =
     165             :         ParseResultTypeId::kOptionalExpressionPtr;
     166             : template <>
     167             : V8_EXPORT_PRIVATE const ParseResultTypeId
     168             :     ParseResultHolder<TypeswitchCase>::id = ParseResultTypeId::kTypeswitchCase;
     169             : template <>
     170             : V8_EXPORT_PRIVATE const ParseResultTypeId
     171             :     ParseResultHolder<std::vector<TypeswitchCase>>::id =
     172             :         ParseResultTypeId::kStdVectorOfTypeswitchCase;
     173             : template <>
     174             : V8_EXPORT_PRIVATE const ParseResultTypeId
     175             :     ParseResultHolder<std::vector<Identifier*>>::id =
     176             :         ParseResultTypeId::kStdVectorOfIdentifierPtr;
     177             : 
     178             : namespace {
     179             : 
     180         966 : base::Optional<ParseResult> AddGlobalDeclaration(
     181             :     ParseResultIterator* child_results) {
     182         966 :   auto declaration = child_results->NextAs<Declaration*>();
     183         966 :   CurrentAst::Get().declarations().push_back(declaration);
     184         966 :   return base::nullopt;
     185             : }
     186             : 
     187         869 : void LintGenericParameters(const GenericParameters& parameters) {
     188         927 :   for (const Identifier* parameter : parameters) {
     189          58 :     if (!IsUpperCamelCase(parameter->value)) {
     190           0 :       NamingConventionError("Generic parameter", parameter->value,
     191           0 :                             "UpperCamelCase");
     192             :     }
     193             :   }
     194         869 : }
     195             : 
     196        3897 : void CheckNotDeferredStatement(Statement* statement) {
     197        3897 :   CurrentSourcePosition::Scope source_position(statement->pos);
     198        3897 :   if (BlockStatement* block = BlockStatement::DynamicCast(statement)) {
     199         382 :     if (block->deferred) {
     200           0 :       LintError(
     201             :           "cannot use deferred with a statement block here, it will have no "
     202           0 :           "effect");
     203             :     }
     204             :   }
     205        3897 : }
     206             : 
     207        3147 : Expression* MakeCall(IdentifierExpression* callee,
     208             :                      base::Optional<Expression*> target,
     209             :                      std::vector<Expression*> arguments,
     210             :                      const std::vector<Statement*>& otherwise) {
     211        3147 :   std::vector<std::string> labels;
     212             : 
     213             :   // All IdentifierExpressions are treated as label names and can be directly
     214             :   // used as labels identifiers. All other statements in a call's otherwise
     215             :   // must create intermediate Labels for the otherwise's statement code.
     216             :   size_t label_id = 0;
     217             :   std::vector<LabelBlock*> temp_labels;
     218        3547 :   for (auto* statement : otherwise) {
     219         400 :     if (auto* e = ExpressionStatement::DynamicCast(statement)) {
     220         490 :       if (auto* id = IdentifierExpression::DynamicCast(e->expression)) {
     221         235 :         if (id->generic_arguments.size() != 0) {
     222           0 :           ReportError("An otherwise label cannot have generic parameters");
     223             :         }
     224         235 :         labels.push_back(id->name->value);
     225         235 :         continue;
     226             :       }
     227             :     }
     228         660 :     auto label_name = std::string("_label") + std::to_string(label_id++);
     229         165 :     labels.push_back(label_name);
     230             :     auto* label_block =
     231         330 :         MakeNode<LabelBlock>(label_name, ParameterList::Empty(), statement);
     232         165 :     temp_labels.push_back(label_block);
     233             :   }
     234             : 
     235             :   // Create nested try-label expression for all of the temporary Labels that
     236             :   // were created.
     237             :   Expression* result = nullptr;
     238        3147 :   if (target) {
     239         240 :     result = MakeNode<CallMethodExpression>(*target, callee, arguments, labels);
     240             :   } else {
     241        6054 :     result = MakeNode<CallExpression>(callee, arguments, labels);
     242             :   }
     243             : 
     244        3312 :   for (auto* label : temp_labels) {
     245         165 :     result = MakeNode<TryLabelExpression>(false, result, label);
     246             :   }
     247        3147 :   return result;
     248             : }
     249             : 
     250        1254 : Expression* MakeCall(const std::string& callee,
     251             :                      const std::vector<TypeExpression*>& generic_arguments,
     252             :                      const std::vector<Expression*>& arguments,
     253             :                      const std::vector<Statement*>& otherwise) {
     254        7524 :   return MakeCall(MakeNode<IdentifierExpression>(MakeNode<Identifier>(callee),
     255             :                                                  generic_arguments),
     256        2508 :                   base::nullopt, arguments, otherwise);
     257             : }
     258             : 
     259        1773 : base::Optional<ParseResult> MakeCall(ParseResultIterator* child_results) {
     260        1773 :   auto callee = child_results->NextAs<Expression*>();
     261        1773 :   auto args = child_results->NextAs<std::vector<Expression*>>();
     262        1773 :   auto otherwise = child_results->NextAs<std::vector<Statement*>>();
     263             :   IdentifierExpression* target = IdentifierExpression::cast(callee);
     264        8865 :   return ParseResult{MakeCall(target, base::nullopt, args, otherwise)};
     265             : }
     266             : 
     267         120 : base::Optional<ParseResult> MakeMethodCall(ParseResultIterator* child_results) {
     268         120 :   auto this_arg = child_results->NextAs<Expression*>();
     269         120 :   auto callee = child_results->NextAs<std::string>();
     270         120 :   auto args = child_results->NextAs<std::vector<Expression*>>();
     271         120 :   auto otherwise = child_results->NextAs<std::vector<Statement*>>();
     272             :   return ParseResult{
     273             :       MakeCall(MakeNode<IdentifierExpression>(MakeNode<Identifier>(callee)),
     274         600 :                this_arg, args, otherwise)};
     275             : }
     276             : 
     277          12 : base::Optional<ParseResult> MakeNewExpression(
     278             :     ParseResultIterator* child_results) {
     279          12 :   auto type = child_results->NextAs<TypeExpression*>();
     280          12 :   auto initializers = child_results->NextAs<std::vector<NameAndExpression>>();
     281          24 :   Expression* result = MakeNode<NewExpression>(type, std::move(initializers));
     282          12 :   return ParseResult{result};
     283             : }
     284             : 
     285        1163 : base::Optional<ParseResult> MakeBinaryOperator(
     286             :     ParseResultIterator* child_results) {
     287        1163 :   auto left = child_results->NextAs<Expression*>();
     288        1163 :   auto op = child_results->NextAs<std::string>();
     289        1163 :   auto right = child_results->NextAs<Expression*>();
     290             :   return ParseResult{MakeCall(op, TypeList{},
     291             :                               std::vector<Expression*>{left, right},
     292        6978 :                               std::vector<Statement*>{})};
     293             : }
     294             : 
     295          49 : base::Optional<ParseResult> MakeIntrinsicCallExpression(
     296             :     ParseResultIterator* child_results) {
     297          49 :   auto callee = child_results->NextAs<std::string>();
     298             :   auto generic_arguments =
     299          49 :       child_results->NextAs<std::vector<TypeExpression*>>();
     300          49 :   auto args = child_results->NextAs<std::vector<Expression*>>();
     301             :   Expression* result =
     302         245 :       MakeNode<IntrinsicCallExpression>(callee, generic_arguments, args);
     303          49 :   return ParseResult{result};
     304             : }
     305             : 
     306          55 : base::Optional<ParseResult> MakeUnaryOperator(
     307             :     ParseResultIterator* child_results) {
     308          55 :   auto op = child_results->NextAs<std::string>();
     309          55 :   auto e = child_results->NextAs<Expression*>();
     310             :   return ParseResult{MakeCall(op, TypeList{}, std::vector<Expression*>{e},
     311         330 :                               std::vector<Statement*>{})};
     312             : }
     313             : 
     314           2 : base::Optional<ParseResult> MakeSpreadExpression(
     315             :     ParseResultIterator* child_results) {
     316           2 :   auto spreadee = child_results->NextAs<Expression*>();
     317           2 :   Expression* result = MakeNode<SpreadExpression>(spreadee);
     318           2 :   return ParseResult{result};
     319             : }
     320             : 
     321             : template <bool has_varargs>
     322         465 : base::Optional<ParseResult> MakeParameterListFromTypes(
     323             :     ParseResultIterator* child_results) {
     324             :   auto implicit_params =
     325         465 :       child_results->NextAs<std::vector<NameAndTypeExpression>>();
     326         465 :   auto explicit_types = child_results->NextAs<TypeList>();
     327         465 :   ParameterList result;
     328         465 :   result.has_varargs = has_varargs;
     329         465 :   result.implicit_count = implicit_params.size();
     330         523 :   for (NameAndTypeExpression& implicit_param : implicit_params) {
     331          58 :     if (!IsLowerCamelCase(implicit_param.name->value)) {
     332           0 :       NamingConventionError("Parameter", implicit_param.name->value,
     333             :                             "lowerCamelCase");
     334             :     }
     335          58 :     result.names.push_back(implicit_param.name);
     336          58 :     result.types.push_back(implicit_param.type);
     337             :   }
     338        1296 :   for (auto* explicit_type : explicit_types) {
     339         831 :     result.types.push_back(explicit_type);
     340             :   }
     341        1395 :   return ParseResult{std::move(result)};
     342             : }
     343             : 
     344             : template <bool has_varargs>
     345         623 : base::Optional<ParseResult> MakeParameterListFromNameAndTypeList(
     346             :     ParseResultIterator* child_results) {
     347             :   auto implicit_params =
     348         623 :       child_results->NextAs<std::vector<NameAndTypeExpression>>();
     349             :   auto explicit_params =
     350         623 :       child_results->NextAs<std::vector<NameAndTypeExpression>>();
     351         623 :   std::string arguments_variable = "";
     352         623 :   if (child_results->HasNext()) {
     353         154 :     arguments_variable = child_results->NextAs<std::string>();
     354             :   }
     355         623 :   ParameterList result;
     356         864 :   for (NameAndTypeExpression& pair : implicit_params) {
     357         241 :     if (!IsLowerCamelCase(pair.name->value)) {
     358           0 :       NamingConventionError("Parameter", pair.name->value, "lowerCamelCase");
     359             :     }
     360             : 
     361         241 :     result.names.push_back(std::move(pair.name));
     362         241 :     result.types.push_back(pair.type);
     363             :   }
     364        1872 :   for (NameAndTypeExpression& pair : explicit_params) {
     365        1249 :     if (!IsLowerCamelCase(pair.name->value)) {
     366           0 :       NamingConventionError("Parameter", pair.name->value, "lowerCamelCase");
     367             :     }
     368             : 
     369        1249 :     result.names.push_back(pair.name);
     370        1249 :     result.types.push_back(pair.type);
     371             :   }
     372         623 :   result.implicit_count = implicit_params.size();
     373         623 :   result.has_varargs = has_varargs;
     374             :   result.arguments_variable = arguments_variable;
     375        1869 :   return ParseResult{std::move(result)};
     376             : }
     377             : 
     378         231 : base::Optional<ParseResult> MakeAssertStatement(
     379             :     ParseResultIterator* child_results) {
     380         231 :   auto kind = child_results->NextAs<std::string>();
     381         231 :   auto expr_with_source = child_results->NextAs<ExpressionWithSource>();
     382             :   DCHECK(kind == "assert" || kind == "check");
     383         693 :   Statement* result = MakeNode<AssertStatement>(
     384         231 :       kind == "assert", expr_with_source.expression, expr_with_source.source);
     385         231 :   return ParseResult{result};
     386             : }
     387             : 
     388         123 : base::Optional<ParseResult> MakeDebugStatement(
     389             :     ParseResultIterator* child_results) {
     390         123 :   auto kind = child_results->NextAs<std::string>();
     391             :   DCHECK(kind == "unreachable" || kind == "debug");
     392         369 :   Statement* result = MakeNode<DebugStatement>(kind, kind == "unreachable");
     393         123 :   return ParseResult{result};
     394             : }
     395             : 
     396         104 : base::Optional<ParseResult> MakeVoidType(ParseResultIterator* child_results) {
     397             :   TypeExpression* result =
     398         104 :       MakeNode<BasicTypeExpression>(std::vector<std::string>{}, false, "void");
     399         104 :   return ParseResult{result};
     400             : }
     401             : 
     402         428 : base::Optional<ParseResult> MakeExternalMacro(
     403             :     ParseResultIterator* child_results) {
     404         428 :   auto transitioning = child_results->NextAs<bool>();
     405         428 :   auto operator_name = child_results->NextAs<base::Optional<std::string>>();
     406             :   auto external_assembler_name =
     407         428 :       child_results->NextAs<base::Optional<std::string>>();
     408         428 :   auto name = child_results->NextAs<std::string>();
     409         428 :   auto generic_parameters = child_results->NextAs<GenericParameters>();
     410         428 :   LintGenericParameters(generic_parameters);
     411             : 
     412         856 :   auto args = child_results->NextAs<ParameterList>();
     413         428 :   auto return_type = child_results->NextAs<TypeExpression*>();
     414         856 :   auto labels = child_results->NextAs<LabelAndTypesVector>();
     415        2525 :   MacroDeclaration* macro = MakeNode<ExternalMacroDeclaration>(
     416             :       transitioning,
     417             :       external_assembler_name ? *external_assembler_name : "CodeStubAssembler",
     418         428 :       name, operator_name, args, return_type, labels);
     419             :   Declaration* result;
     420         428 :   if (generic_parameters.empty()) {
     421         428 :     result = MakeNode<StandardDeclaration>(macro, base::nullopt);
     422             :   } else {
     423           0 :     result = MakeNode<GenericDeclaration>(macro, generic_parameters);
     424             :   }
     425         428 :   return ParseResult{result};
     426             : }
     427             : 
     428           6 : base::Optional<ParseResult> MakeIntrinsicDeclaration(
     429             :     ParseResultIterator* child_results) {
     430           6 :   auto name = child_results->NextAs<std::string>();
     431           6 :   auto generic_parameters = child_results->NextAs<GenericParameters>();
     432           6 :   LintGenericParameters(generic_parameters);
     433             : 
     434          12 :   auto args = child_results->NextAs<ParameterList>();
     435           6 :   auto return_type = child_results->NextAs<TypeExpression*>();
     436             :   IntrinsicDeclaration* macro =
     437          18 :       MakeNode<IntrinsicDeclaration>(name, args, return_type);
     438             :   Declaration* result;
     439           6 :   if (generic_parameters.empty()) {
     440           0 :     result = MakeNode<StandardDeclaration>(macro, base::nullopt);
     441             :   } else {
     442          12 :     result = MakeNode<GenericDeclaration>(macro, generic_parameters);
     443             :   }
     444           6 :   return ParseResult{result};
     445             : }
     446             : 
     447         278 : base::Optional<ParseResult> MakeTorqueMacroDeclaration(
     448             :     ParseResultIterator* child_results) {
     449         278 :   auto transitioning = child_results->NextAs<bool>();
     450         278 :   auto operator_name = child_results->NextAs<base::Optional<std::string>>();
     451         278 :   auto name = child_results->NextAs<std::string>();
     452         278 :   if (!IsUpperCamelCase(name)) {
     453           0 :     NamingConventionError("Macro", name, "UpperCamelCase");
     454             :   }
     455             : 
     456         278 :   auto generic_parameters = child_results->NextAs<GenericParameters>();
     457         278 :   LintGenericParameters(generic_parameters);
     458             : 
     459         556 :   auto args = child_results->NextAs<ParameterList>();
     460         278 :   auto return_type = child_results->NextAs<TypeExpression*>();
     461         556 :   auto labels = child_results->NextAs<LabelAndTypesVector>();
     462         278 :   auto body = child_results->NextAs<base::Optional<Statement*>>();
     463        1112 :   MacroDeclaration* macro = MakeNode<TorqueMacroDeclaration>(
     464         278 :       transitioning, name, operator_name, args, return_type, labels);
     465             :   Declaration* result;
     466         278 :   if (generic_parameters.empty()) {
     467         246 :     if (!body) ReportError("A non-generic declaration needs a body.");
     468         246 :     result = MakeNode<StandardDeclaration>(macro, *body);
     469             :   } else {
     470          64 :     result = MakeNode<GenericDeclaration>(macro, generic_parameters, body);
     471             :   }
     472         278 :   return ParseResult{result};
     473             : }
     474             : 
     475         138 : base::Optional<ParseResult> MakeTorqueBuiltinDeclaration(
     476             :     ParseResultIterator* child_results) {
     477         138 :   auto transitioning = child_results->NextAs<bool>();
     478         138 :   auto javascript_linkage = child_results->NextAs<bool>();
     479         138 :   auto name = child_results->NextAs<std::string>();
     480         138 :   if (!IsUpperCamelCase(name)) {
     481           0 :     NamingConventionError("Builtin", name, "UpperCamelCase");
     482             :   }
     483             : 
     484         138 :   auto generic_parameters = child_results->NextAs<GenericParameters>();
     485         138 :   LintGenericParameters(generic_parameters);
     486             : 
     487         276 :   auto args = child_results->NextAs<ParameterList>();
     488         138 :   auto return_type = child_results->NextAs<TypeExpression*>();
     489         138 :   auto body = child_results->NextAs<base::Optional<Statement*>>();
     490         414 :   BuiltinDeclaration* builtin = MakeNode<TorqueBuiltinDeclaration>(
     491         138 :       transitioning, javascript_linkage, name, args, return_type);
     492             :   Declaration* result;
     493         138 :   if (generic_parameters.empty()) {
     494         130 :     if (!body) ReportError("A non-generic declaration needs a body.");
     495         130 :     result = MakeNode<StandardDeclaration>(builtin, *body);
     496             :   } else {
     497          16 :     result = MakeNode<GenericDeclaration>(builtin, generic_parameters, body);
     498             :   }
     499         138 :   return ParseResult{result};
     500             : }
     501             : 
     502          33 : base::Optional<ParseResult> MakeConstDeclaration(
     503             :     ParseResultIterator* child_results) {
     504          33 :   auto name = child_results->NextAs<Identifier*>();
     505          33 :   if (!IsValidNamespaceConstName(name->value)) {
     506           0 :     NamingConventionError("Constant", name->value, "kUpperCamelCase");
     507             :   }
     508             : 
     509          33 :   auto type = child_results->NextAs<TypeExpression*>();
     510          33 :   auto expression = child_results->NextAs<Expression*>();
     511          33 :   Declaration* result = MakeNode<ConstDeclaration>(name, type, expression);
     512          33 :   return ParseResult{result};
     513             : }
     514             : 
     515          97 : base::Optional<ParseResult> MakeExternConstDeclaration(
     516             :     ParseResultIterator* child_results) {
     517          97 :   auto name = child_results->NextAs<Identifier*>();
     518          97 :   auto type = child_results->NextAs<TypeExpression*>();
     519          97 :   auto literal = child_results->NextAs<std::string>();
     520             :   Declaration* result =
     521         194 :       MakeNode<ExternConstDeclaration>(name, type, std::move(literal));
     522          97 :   return ParseResult{result};
     523             : }
     524             : 
     525          19 : base::Optional<ParseResult> MakeTypeAliasDeclaration(
     526             :     ParseResultIterator* child_results) {
     527          19 :   auto name = child_results->NextAs<Identifier*>();
     528          19 :   auto type = child_results->NextAs<TypeExpression*>();
     529          19 :   Declaration* result = MakeNode<TypeAliasDeclaration>(name, type);
     530          19 :   return ParseResult{result};
     531             : }
     532             : 
     533          94 : base::Optional<ParseResult> MakeTypeDeclaration(
     534             :     ParseResultIterator* child_results) {
     535          94 :   auto transient = child_results->NextAs<bool>();
     536          94 :   auto name = child_results->NextAs<Identifier*>();
     537          94 :   if (!IsValidTypeName(name->value)) {
     538           0 :     NamingConventionError("Type", name->value, "UpperCamelCase");
     539             :   }
     540          94 :   auto extends = child_results->NextAs<base::Optional<Identifier*>>();
     541          94 :   auto generates = child_results->NextAs<base::Optional<std::string>>();
     542             :   auto constexpr_generates =
     543          94 :       child_results->NextAs<base::Optional<std::string>>();
     544             :   Declaration* result =
     545         282 :       MakeNode<TypeDeclaration>(name, transient, extends, std::move(generates),
     546          94 :                                 std::move(constexpr_generates));
     547          94 :   return ParseResult{result};
     548             : }
     549             : 
     550          39 : base::Optional<ParseResult> MakeMethodDeclaration(
     551             :     ParseResultIterator* child_results) {
     552          39 :   auto transitioning = child_results->NextAs<bool>();
     553          39 :   auto operator_name = child_results->NextAs<base::Optional<std::string>>();
     554          39 :   auto name = child_results->NextAs<std::string>();
     555          39 :   if (!IsUpperCamelCase(name)) {
     556           0 :     NamingConventionError("Method", name, "UpperCamelCase");
     557             :   }
     558             : 
     559          78 :   auto args = child_results->NextAs<ParameterList>();
     560          39 :   auto return_type = child_results->NextAs<TypeExpression*>();
     561          78 :   auto labels = child_results->NextAs<LabelAndTypesVector>();
     562          39 :   auto body = child_results->NextAs<Statement*>();
     563         156 :   MacroDeclaration* macro = MakeNode<TorqueMacroDeclaration>(
     564          39 :       transitioning, name, operator_name, args, return_type, labels);
     565          39 :   Declaration* result = MakeNode<StandardDeclaration>(macro, body);
     566          39 :   return ParseResult{result};
     567             : }
     568             : 
     569         121 : base::Optional<ParseResult> MakeClassDeclaration(
     570             :     ParseResultIterator* child_results) {
     571         121 :   auto generate_print = child_results->NextAs<bool>();
     572         121 :   auto is_extern = child_results->NextAs<bool>();
     573         121 :   auto transient = child_results->NextAs<bool>();
     574         121 :   auto name = child_results->NextAs<Identifier*>();
     575         121 :   if (!IsValidTypeName(name->value)) {
     576           0 :     NamingConventionError("Type", name->value, "UpperCamelCase");
     577             :   }
     578         121 :   auto extends = child_results->NextAs<base::Optional<std::string>>();
     579         121 :   auto generates = child_results->NextAs<base::Optional<std::string>>();
     580         121 :   auto methods = child_results->NextAs<std::vector<Declaration*>>();
     581         242 :   auto fields = child_results->NextAs<std::vector<ClassFieldExpression>>();
     582         605 :   Declaration* result = MakeNode<ClassDeclaration>(
     583             :       name, is_extern, generate_print, transient, std::move(extends),
     584         121 :       std::move(generates), std::move(methods), fields);
     585         121 :   return ParseResult{result};
     586             : }
     587             : 
     588          50 : base::Optional<ParseResult> MakeNamespaceDeclaration(
     589             :     ParseResultIterator* child_results) {
     590          50 :   auto name = child_results->NextAs<std::string>();
     591          50 :   if (!IsSnakeCase(name)) {
     592           0 :     NamingConventionError("Namespace", name, "snake_case");
     593             :   }
     594          50 :   auto declarations = child_results->NextAs<std::vector<Declaration*>>();
     595             :   Declaration* result =
     596         150 :       MakeNode<NamespaceDeclaration>(std::move(name), std::move(declarations));
     597          50 :   return ParseResult{result};
     598             : }
     599             : 
     600         141 : base::Optional<ParseResult> MakeSpecializationDeclaration(
     601             :     ParseResultIterator* child_results) {
     602         141 :   auto name = child_results->NextAs<std::string>();
     603             :   auto generic_parameters =
     604         141 :       child_results->NextAs<std::vector<TypeExpression*>>();
     605         282 :   auto parameters = child_results->NextAs<ParameterList>();
     606         141 :   auto return_type = child_results->NextAs<TypeExpression*>();
     607         282 :   auto labels = child_results->NextAs<LabelAndTypesVector>();
     608         141 :   auto body = child_results->NextAs<Statement*>();
     609         141 :   CheckNotDeferredStatement(body);
     610         423 :   Declaration* result = MakeNode<SpecializationDeclaration>(
     611             :       std::move(name), std::move(generic_parameters), std::move(parameters),
     612         141 :       return_type, std::move(labels), body);
     613         141 :   return ParseResult{result};
     614             : }
     615             : 
     616          18 : base::Optional<ParseResult> MakeStructDeclaration(
     617             :     ParseResultIterator* child_results) {
     618          18 :   auto name = child_results->NextAs<Identifier*>();
     619          18 :   auto methods = child_results->NextAs<std::vector<Declaration*>>();
     620          18 :   auto fields = child_results->NextAs<std::vector<StructFieldExpression>>();
     621             :   Declaration* result =
     622          54 :       MakeNode<StructDeclaration>(name, std::move(methods), std::move(fields));
     623          18 :   return ParseResult{result};
     624             : }
     625             : 
     626          36 : base::Optional<ParseResult> MakeCppIncludeDeclaration(
     627             :     ParseResultIterator* child_results) {
     628          36 :   auto include_path = child_results->NextAs<std::string>();
     629             :   Declaration* result =
     630          72 :       MakeNode<CppIncludeDeclaration>(std::move(include_path));
     631          36 :   return ParseResult{result};
     632             : }
     633             : 
     634          19 : base::Optional<ParseResult> MakeExternalBuiltin(
     635             :     ParseResultIterator* child_results) {
     636          19 :   auto transitioning = child_results->NextAs<bool>();
     637          19 :   auto js_linkage = child_results->NextAs<bool>();
     638          19 :   auto name = child_results->NextAs<std::string>();
     639          19 :   auto generic_parameters = child_results->NextAs<GenericParameters>();
     640          19 :   LintGenericParameters(generic_parameters);
     641             : 
     642          38 :   auto args = child_results->NextAs<ParameterList>();
     643          19 :   auto return_type = child_results->NextAs<TypeExpression*>();
     644          57 :   BuiltinDeclaration* builtin = MakeNode<ExternalBuiltinDeclaration>(
     645          19 :       transitioning, js_linkage, name, args, return_type);
     646             :   Declaration* result;
     647          19 :   if (generic_parameters.empty()) {
     648          19 :     result = MakeNode<StandardDeclaration>(builtin, base::nullopt);
     649             :   } else {
     650           0 :     result = MakeNode<GenericDeclaration>(builtin, generic_parameters);
     651             :   }
     652          19 :   return ParseResult{result};
     653             : }
     654             : 
     655          18 : base::Optional<ParseResult> MakeExternalRuntime(
     656             :     ParseResultIterator* child_results) {
     657          18 :   auto transitioning = child_results->NextAs<bool>();
     658          18 :   auto name = child_results->NextAs<std::string>();
     659          36 :   auto args = child_results->NextAs<ParameterList>();
     660          18 :   auto return_type = child_results->NextAs<TypeExpression*>();
     661          54 :   ExternalRuntimeDeclaration* runtime = MakeNode<ExternalRuntimeDeclaration>(
     662          18 :       transitioning, name, args, return_type);
     663          18 :   Declaration* result = MakeNode<StandardDeclaration>(runtime, base::nullopt);
     664          18 :   return ParseResult{result};
     665             : }
     666             : 
     667         357 : base::Optional<ParseResult> StringLiteralUnquoteAction(
     668             :     ParseResultIterator* child_results) {
     669             :   return ParseResult{
     670        1428 :       StringLiteralUnquote(child_results->NextAs<std::string>())};
     671             : }
     672             : 
     673        5728 : base::Optional<ParseResult> MakeBasicTypeExpression(
     674             :     ParseResultIterator* child_results) {
     675             :   auto namespace_qualification =
     676       11456 :       child_results->NextAs<std::vector<std::string>>();
     677        5728 :   auto is_constexpr = child_results->NextAs<bool>();
     678        5728 :   auto name = child_results->NextAs<std::string>();
     679       17184 :   TypeExpression* result = MakeNode<BasicTypeExpression>(
     680        5728 :       std::move(namespace_qualification), is_constexpr, std::move(name));
     681        5728 :   return ParseResult{result};
     682             : }
     683             : 
     684          11 : base::Optional<ParseResult> MakeFunctionTypeExpression(
     685             :     ParseResultIterator* child_results) {
     686          11 :   auto parameters = child_results->NextAs<std::vector<TypeExpression*>>();
     687          11 :   auto return_type = child_results->NextAs<TypeExpression*>();
     688             :   TypeExpression* result =
     689          22 :       MakeNode<FunctionTypeExpression>(std::move(parameters), return_type);
     690          11 :   return ParseResult{result};
     691             : }
     692             : 
     693           4 : base::Optional<ParseResult> MakeReferenceTypeExpression(
     694             :     ParseResultIterator* child_results) {
     695           4 :   auto referenced_type = child_results->NextAs<TypeExpression*>();
     696           4 :   TypeExpression* result = MakeNode<ReferenceTypeExpression>(referenced_type);
     697           4 :   return ParseResult{result};
     698             : }
     699             : 
     700          79 : base::Optional<ParseResult> MakeUnionTypeExpression(
     701             :     ParseResultIterator* child_results) {
     702          79 :   auto a = child_results->NextAs<TypeExpression*>();
     703          79 :   auto b = child_results->NextAs<TypeExpression*>();
     704          79 :   TypeExpression* result = MakeNode<UnionTypeExpression>(a, b);
     705          79 :   return ParseResult{result};
     706             : }
     707             : 
     708        1018 : base::Optional<ParseResult> MakeExpressionStatement(
     709             :     ParseResultIterator* child_results) {
     710        1018 :   auto expression = child_results->NextAs<Expression*>();
     711        1018 :   Statement* result = MakeNode<ExpressionStatement>(expression);
     712        1018 :   return ParseResult{result};
     713             : }
     714             : 
     715         505 : base::Optional<ParseResult> MakeIfStatement(
     716             :     ParseResultIterator* child_results) {
     717         505 :   auto is_constexpr = child_results->NextAs<bool>();
     718         505 :   auto condition = child_results->NextAs<Expression*>();
     719         505 :   auto if_true = child_results->NextAs<Statement*>();
     720         505 :   auto if_false = child_results->NextAs<base::Optional<Statement*>>();
     721             : 
     722        1180 :   if (if_false && !(BlockStatement::DynamicCast(if_true) &&
     723          85 :                     (BlockStatement::DynamicCast(*if_false) ||
     724         170 :                      IfStatement::DynamicCast(*if_false)))) {
     725           0 :     ReportError("if-else statements require curly braces");
     726             :   }
     727             : 
     728         505 :   if (is_constexpr) {
     729          52 :     CheckNotDeferredStatement(if_true);
     730          52 :     if (if_false) CheckNotDeferredStatement(*if_false);
     731             :   }
     732             : 
     733             :   Statement* result =
     734         505 :       MakeNode<IfStatement>(is_constexpr, condition, if_true, if_false);
     735         505 :   return ParseResult{result};
     736             : }
     737             : 
     738          21 : base::Optional<ParseResult> MakeTypeswitchStatement(
     739             :     ParseResultIterator* child_results) {
     740          21 :   auto expression = child_results->NextAs<Expression*>();
     741          42 :   auto cases = child_results->NextAs<std::vector<TypeswitchCase>>();
     742             :   CurrentSourcePosition::Scope current_source_position(
     743          21 :       child_results->matched_input().pos);
     744             : 
     745             :   // typeswitch (expression) case (x1 : T1) {
     746             :   //   ...b1
     747             :   // } case (x2 : T2) {
     748             :   //   ...b2
     749             :   // } case (x3 : T3) {
     750             :   //   ...b3
     751             :   // }
     752             :   //
     753             :   // desugars to
     754             :   //
     755             :   // {
     756             :   //   const _value = expression;
     757             :   //   try {
     758             :   //     const x1 : T1 = cast<T1>(_value) otherwise _NextCase;
     759             :   //     ...b1
     760             :   //   } label _NextCase {
     761             :   //     try {
     762             :   //       const x2 : T2 = cast<T2>(%assume_impossible<T1>(_value));
     763             :   //       ...b2
     764             :   //     } label _NextCase {
     765             :   //       const x3 : T3 = %assume_impossible<T1|T2>(_value);
     766             :   //       ...b3
     767             :   //     }
     768             :   //   }
     769             :   // }
     770             : 
     771          21 :   BlockStatement* current_block = MakeNode<BlockStatement>();
     772             :   Statement* result = current_block;
     773             :   {
     774          21 :     CurrentSourcePosition::Scope current_source_position(expression->pos);
     775          42 :     current_block->statements.push_back(MakeNode<VarDeclarationStatement>(
     776             :         true, MakeNode<Identifier>("_value"), base::nullopt, expression));
     777             :   }
     778             : 
     779             :   TypeExpression* accumulated_types;
     780         135 :   for (size_t i = 0; i < cases.size(); ++i) {
     781          57 :     CurrentSourcePosition::Scope current_source_position(cases[i].pos);
     782             :     Expression* value =
     783          57 :         MakeNode<IdentifierExpression>(MakeNode<Identifier>("_value"));
     784          57 :     if (i >= 1) {
     785             :       value =
     786          36 :           MakeNode<AssumeTypeImpossibleExpression>(accumulated_types, value);
     787             :     }
     788             :     BlockStatement* case_block;
     789          57 :     if (i < cases.size() - 1) {
     790         216 :       value = MakeCall("Cast", std::vector<TypeExpression*>{cases[i].type},
     791             :                        std::vector<Expression*>{value},
     792          36 :                        std::vector<Statement*>{MakeNode<ExpressionStatement>(
     793             :                            MakeNode<IdentifierExpression>(
     794          36 :                                MakeNode<Identifier>("_NextCase")))});
     795          36 :       case_block = MakeNode<BlockStatement>();
     796             :     } else {
     797             :       case_block = current_block;
     798             :     }
     799          57 :     std::string name = "_case_value";
     800          57 :     if (cases[i].name) name = *cases[i].name;
     801         228 :     case_block->statements.push_back(MakeNode<VarDeclarationStatement>(
     802             :         true, MakeNode<Identifier>(name), cases[i].type, value));
     803          57 :     case_block->statements.push_back(cases[i].block);
     804          57 :     if (i < cases.size() - 1) {
     805          36 :       BlockStatement* next_block = MakeNode<BlockStatement>();
     806          72 :       current_block->statements.push_back(
     807          36 :           MakeNode<ExpressionStatement>(MakeNode<TryLabelExpression>(
     808             :               false, MakeNode<StatementExpression>(case_block),
     809          36 :               MakeNode<LabelBlock>("_NextCase", ParameterList::Empty(),
     810             :                                    next_block))));
     811             :       current_block = next_block;
     812             :     }
     813             :     accumulated_types =
     814          36 :         i > 0 ? MakeNode<UnionTypeExpression>(accumulated_types, cases[i].type)
     815         114 :               : cases[i].type;
     816             :   }
     817          21 :   return ParseResult{result};
     818             : }
     819             : 
     820          57 : base::Optional<ParseResult> MakeTypeswitchCase(
     821             :     ParseResultIterator* child_results) {
     822          57 :   auto name = child_results->NextAs<base::Optional<std::string>>();
     823          57 :   auto type = child_results->NextAs<TypeExpression*>();
     824          57 :   auto block = child_results->NextAs<Statement*>();
     825             :   return ParseResult{TypeswitchCase{child_results->matched_input().pos,
     826         285 :                                     std::move(name), type, block}};
     827             : }
     828             : 
     829          39 : base::Optional<ParseResult> MakeWhileStatement(
     830             :     ParseResultIterator* child_results) {
     831          39 :   auto condition = child_results->NextAs<Expression*>();
     832          39 :   auto body = child_results->NextAs<Statement*>();
     833          39 :   Statement* result = MakeNode<WhileStatement>(condition, body);
     834          39 :   CheckNotDeferredStatement(result);
     835          39 :   return ParseResult{result};
     836             : }
     837             : 
     838         626 : base::Optional<ParseResult> MakeReturnStatement(
     839             :     ParseResultIterator* child_results) {
     840         626 :   auto value = child_results->NextAs<base::Optional<Expression*>>();
     841         626 :   Statement* result = MakeNode<ReturnStatement>(value);
     842         626 :   return ParseResult{result};
     843             : }
     844             : 
     845           2 : base::Optional<ParseResult> MakeTailCallStatement(
     846             :     ParseResultIterator* child_results) {
     847           2 :   auto value = child_results->NextAs<Expression*>();
     848           2 :   Statement* result = MakeNode<TailCallStatement>(CallExpression::cast(value));
     849           2 :   return ParseResult{result};
     850             : }
     851             : 
     852        1159 : base::Optional<ParseResult> MakeVarDeclarationStatement(
     853             :     ParseResultIterator* child_results) {
     854        1159 :   auto kind = child_results->NextAs<std::string>();
     855             :   bool const_qualified = kind == "const";
     856             :   if (!const_qualified) DCHECK_EQ("let", kind);
     857        1159 :   auto name = child_results->NextAs<Identifier*>();
     858        1159 :   if (!IsLowerCamelCase(name->value)) {
     859           0 :     NamingConventionError("Variable", name->value, "lowerCamelCase");
     860             :   }
     861             : 
     862        1159 :   auto type = child_results->NextAs<base::Optional<TypeExpression*>>();
     863        1159 :   base::Optional<Expression*> initializer;
     864        1159 :   if (child_results->HasNext())
     865        1133 :     initializer = child_results->NextAs<Expression*>();
     866        1159 :   if (!initializer && !type) {
     867           0 :     ReportError("Declaration is missing a type.");
     868             :   }
     869        1159 :   Statement* result = MakeNode<VarDeclarationStatement>(const_qualified, name,
     870        1159 :                                                         type, initializer);
     871        1159 :   return ParseResult{result};
     872             : }
     873             : 
     874          27 : base::Optional<ParseResult> MakeBreakStatement(
     875             :     ParseResultIterator* child_results) {
     876          27 :   Statement* result = MakeNode<BreakStatement>();
     877          27 :   return ParseResult{result};
     878             : }
     879             : 
     880          14 : base::Optional<ParseResult> MakeContinueStatement(
     881             :     ParseResultIterator* child_results) {
     882          14 :   Statement* result = MakeNode<ContinueStatement>();
     883          14 :   return ParseResult{result};
     884             : }
     885             : 
     886         199 : base::Optional<ParseResult> MakeGotoStatement(
     887             :     ParseResultIterator* child_results) {
     888         199 :   auto label = child_results->NextAs<std::string>();
     889         199 :   auto arguments = child_results->NextAs<std::vector<Expression*>>();
     890             :   Statement* result =
     891         597 :       MakeNode<GotoStatement>(std::move(label), std::move(arguments));
     892         199 :   return ParseResult{result};
     893             : }
     894             : 
     895        1401 : base::Optional<ParseResult> MakeBlockStatement(
     896             :     ParseResultIterator* child_results) {
     897        1401 :   auto deferred = child_results->NextAs<bool>();
     898        1401 :   auto statements = child_results->NextAs<std::vector<Statement*>>();
     899        4862 :   for (Statement* statement : statements) {
     900        3461 :     CheckNotDeferredStatement(statement);
     901             :   }
     902        2802 :   Statement* result = MakeNode<BlockStatement>(deferred, std::move(statements));
     903        1401 :   return ParseResult{result};
     904             : }
     905             : 
     906          99 : base::Optional<ParseResult> MakeTryLabelExpression(
     907             :     ParseResultIterator* child_results) {
     908          99 :   auto try_block = child_results->NextAs<Statement*>();
     909          99 :   CheckNotDeferredStatement(try_block);
     910             :   Statement* result = try_block;
     911          99 :   auto label_blocks = child_results->NextAs<std::vector<LabelBlock*>>();
     912          99 :   auto catch_block = child_results->NextAs<base::Optional<LabelBlock*>>();
     913         236 :   for (auto block : label_blocks) {
     914         137 :     result = MakeNode<ExpressionStatement>(MakeNode<TryLabelExpression>(
     915         137 :         false, MakeNode<StatementExpression>(result), block));
     916             :   }
     917          99 :   if (catch_block) {
     918           5 :     result = MakeNode<ExpressionStatement>(MakeNode<TryLabelExpression>(
     919           5 :         true, MakeNode<StatementExpression>(result), *catch_block));
     920             :   }
     921          99 :   return ParseResult{result};
     922             : }
     923             : 
     924           0 : base::Optional<ParseResult> MakeForOfLoopStatement(
     925             :     ParseResultIterator* child_results) {
     926           0 :   auto var_decl = child_results->NextAs<Statement*>();
     927           0 :   CheckNotDeferredStatement(var_decl);
     928           0 :   auto iterable = child_results->NextAs<Expression*>();
     929           0 :   auto range = child_results->NextAs<base::Optional<RangeExpression>>();
     930           0 :   auto body = child_results->NextAs<Statement*>();
     931           0 :   CheckNotDeferredStatement(body);
     932             :   Statement* result =
     933           0 :       MakeNode<ForOfLoopStatement>(var_decl, iterable, range, body);
     934           0 :   return ParseResult{result};
     935             : }
     936             : 
     937          57 : base::Optional<ParseResult> MakeForLoopStatement(
     938             :     ParseResultIterator* child_results) {
     939          57 :   auto var_decl = child_results->NextAs<base::Optional<Statement*>>();
     940          57 :   auto test = child_results->NextAs<base::Optional<Expression*>>();
     941          57 :   auto action = child_results->NextAs<base::Optional<Expression*>>();
     942          57 :   base::Optional<Statement*> action_stmt;
     943          57 :   if (action) action_stmt = MakeNode<ExpressionStatement>(*action);
     944          57 :   auto body = child_results->NextAs<Statement*>();
     945          57 :   CheckNotDeferredStatement(body);
     946             :   Statement* result =
     947          57 :       MakeNode<ForLoopStatement>(var_decl, test, action_stmt, body);
     948          57 :   return ParseResult{result};
     949             : }
     950             : 
     951         137 : base::Optional<ParseResult> MakeLabelBlock(ParseResultIterator* child_results) {
     952         137 :   auto label = child_results->NextAs<std::string>();
     953         137 :   if (!IsUpperCamelCase(label)) {
     954           0 :     NamingConventionError("Label", label, "UpperCamelCase");
     955             :   }
     956         274 :   auto parameters = child_results->NextAs<ParameterList>();
     957         137 :   auto body = child_results->NextAs<Statement*>();
     958             :   LabelBlock* result =
     959         411 :       MakeNode<LabelBlock>(std::move(label), std::move(parameters), body);
     960         137 :   return ParseResult{result};
     961             : }
     962             : 
     963           5 : base::Optional<ParseResult> MakeCatchBlock(ParseResultIterator* child_results) {
     964           5 :   auto variable = child_results->NextAs<std::string>();
     965           5 :   auto body = child_results->NextAs<Statement*>();
     966           5 :   if (!IsLowerCamelCase(variable)) {
     967           0 :     NamingConventionError("Exception", variable, "lowerCamelCase");
     968             :   }
     969           5 :   ParameterList parameters;
     970          15 :   parameters.names.push_back(MakeNode<Identifier>(variable));
     971          10 :   parameters.types.push_back(MakeNode<BasicTypeExpression>(
     972             :       std::vector<std::string>{}, false, "Object"));
     973           5 :   parameters.has_varargs = false;
     974             :   LabelBlock* result =
     975           5 :       MakeNode<LabelBlock>("_catch", std::move(parameters), body);
     976           5 :   return ParseResult{result};
     977             : }
     978             : 
     979           0 : base::Optional<ParseResult> MakeRangeExpression(
     980             :     ParseResultIterator* child_results) {
     981           0 :   auto begin = child_results->NextAs<base::Optional<Expression*>>();
     982           0 :   auto end = child_results->NextAs<base::Optional<Expression*>>();
     983           0 :   RangeExpression result = {begin, end};
     984           0 :   return ParseResult{result};
     985             : }
     986             : 
     987         231 : base::Optional<ParseResult> MakeExpressionWithSource(
     988             :     ParseResultIterator* child_results) {
     989         231 :   auto e = child_results->NextAs<Expression*>();
     990             :   return ParseResult{
     991         924 :       ExpressionWithSource{e, child_results->matched_input().ToString()}};
     992             : }
     993             : 
     994       12755 : base::Optional<ParseResult> MakeIdentifier(ParseResultIterator* child_results) {
     995       12755 :   auto name = child_results->NextAs<std::string>();
     996       25510 :   Identifier* result = MakeNode<Identifier>(std::move(name));
     997       12755 :   return ParseResult{result};
     998             : }
     999             : 
    1000        8454 : base::Optional<ParseResult> MakeIdentifierExpression(
    1001             :     ParseResultIterator* child_results) {
    1002             :   auto namespace_qualification =
    1003       16908 :       child_results->NextAs<std::vector<std::string>>();
    1004        8454 :   auto name = child_results->NextAs<Identifier*>();
    1005             :   auto generic_arguments =
    1006        8454 :       child_results->NextAs<std::vector<TypeExpression*>>();
    1007       16908 :   Expression* result = MakeNode<IdentifierExpression>(
    1008        8454 :       std::move(namespace_qualification), name, std::move(generic_arguments));
    1009        8454 :   return ParseResult{result};
    1010             : }
    1011             : 
    1012         647 : base::Optional<ParseResult> MakeFieldAccessExpression(
    1013             :     ParseResultIterator* child_results) {
    1014         647 :   auto object = child_results->NextAs<Expression*>();
    1015         647 :   auto field = child_results->NextAs<Identifier*>();
    1016         647 :   Expression* result = MakeNode<FieldAccessExpression>(object, field);
    1017         647 :   return ParseResult{result};
    1018             : }
    1019             : 
    1020         269 : base::Optional<ParseResult> MakeElementAccessExpression(
    1021             :     ParseResultIterator* child_results) {
    1022         269 :   auto object = child_results->NextAs<Expression*>();
    1023         269 :   auto field = child_results->NextAs<Expression*>();
    1024         269 :   Expression* result = MakeNode<ElementAccessExpression>(object, field);
    1025         269 :   return ParseResult{result};
    1026             : }
    1027             : 
    1028           7 : base::Optional<ParseResult> MakeDereferenceExpression(
    1029             :     ParseResultIterator* child_results) {
    1030           7 :   auto reference = child_results->NextAs<Expression*>();
    1031           7 :   Expression* result = MakeNode<DereferenceExpression>(reference);
    1032           7 :   return ParseResult{result};
    1033             : }
    1034             : 
    1035          21 : base::Optional<ParseResult> MakeStructExpression(
    1036             :     ParseResultIterator* child_results) {
    1037          21 :   auto type = child_results->NextAs<TypeExpression*>();
    1038          21 :   auto initializers = child_results->NextAs<std::vector<NameAndExpression>>();
    1039             :   Expression* result =
    1040          42 :       MakeNode<StructExpression>(type, std::move(initializers));
    1041          21 :   return ParseResult{result};
    1042             : }
    1043             : 
    1044         409 : base::Optional<ParseResult> MakeAssignmentExpression(
    1045             :     ParseResultIterator* child_results) {
    1046         409 :   auto location = child_results->NextAs<Expression*>();
    1047         409 :   auto op = child_results->NextAs<base::Optional<std::string>>();
    1048         409 :   auto value = child_results->NextAs<Expression*>();
    1049             :   Expression* result =
    1050         818 :       MakeNode<AssignmentExpression>(location, std::move(op), value);
    1051         409 :   return ParseResult{result};
    1052             : }
    1053             : 
    1054         965 : base::Optional<ParseResult> MakeNumberLiteralExpression(
    1055             :     ParseResultIterator* child_results) {
    1056         965 :   auto number = child_results->NextAs<std::string>();
    1057        1930 :   Expression* result = MakeNode<NumberLiteralExpression>(std::move(number));
    1058         965 :   return ParseResult{result};
    1059             : }
    1060             : 
    1061         106 : base::Optional<ParseResult> MakeStringLiteralExpression(
    1062             :     ParseResultIterator* child_results) {
    1063         106 :   auto literal = child_results->NextAs<std::string>();
    1064         212 :   Expression* result = MakeNode<StringLiteralExpression>(std::move(literal));
    1065         106 :   return ParseResult{result};
    1066             : }
    1067             : 
    1068          84 : base::Optional<ParseResult> MakeIncrementDecrementExpressionPostfix(
    1069             :     ParseResultIterator* child_results) {
    1070          84 :   auto location = child_results->NextAs<Expression*>();
    1071          84 :   auto op = child_results->NextAs<IncrementDecrementOperator>();
    1072             :   Expression* result =
    1073          84 :       MakeNode<IncrementDecrementExpression>(location, op, true);
    1074          84 :   return ParseResult{result};
    1075             : }
    1076             : 
    1077          56 : base::Optional<ParseResult> MakeIncrementDecrementExpressionPrefix(
    1078             :     ParseResultIterator* child_results) {
    1079          56 :   auto op = child_results->NextAs<IncrementDecrementOperator>();
    1080          56 :   auto location = child_results->NextAs<Expression*>();
    1081             :   Expression* result =
    1082          56 :       MakeNode<IncrementDecrementExpression>(location, op, false);
    1083          56 :   return ParseResult{result};
    1084             : }
    1085             : 
    1086          30 : base::Optional<ParseResult> MakeLogicalOrExpression(
    1087             :     ParseResultIterator* child_results) {
    1088          30 :   auto left = child_results->NextAs<Expression*>();
    1089          30 :   auto right = child_results->NextAs<Expression*>();
    1090          30 :   Expression* result = MakeNode<LogicalOrExpression>(left, right);
    1091          30 :   return ParseResult{result};
    1092             : }
    1093             : 
    1094          46 : base::Optional<ParseResult> MakeLogicalAndExpression(
    1095             :     ParseResultIterator* child_results) {
    1096          46 :   auto left = child_results->NextAs<Expression*>();
    1097          46 :   auto right = child_results->NextAs<Expression*>();
    1098          46 :   Expression* result = MakeNode<LogicalAndExpression>(left, right);
    1099          46 :   return ParseResult{result};
    1100             : }
    1101             : 
    1102          99 : base::Optional<ParseResult> MakeConditionalExpression(
    1103             :     ParseResultIterator* child_results) {
    1104          99 :   auto condition = child_results->NextAs<Expression*>();
    1105          99 :   auto if_true = child_results->NextAs<Expression*>();
    1106          99 :   auto if_false = child_results->NextAs<Expression*>();
    1107             :   Expression* result =
    1108          99 :       MakeNode<ConditionalExpression>(condition, if_true, if_false);
    1109          99 :   return ParseResult{result};
    1110             : }
    1111             : 
    1112         171 : base::Optional<ParseResult> MakeLabelAndTypes(
    1113             :     ParseResultIterator* child_results) {
    1114         171 :   auto name = child_results->NextAs<std::string>();
    1115         171 :   if (!IsUpperCamelCase(name)) {
    1116           0 :     NamingConventionError("Label", name, "UpperCamelCase");
    1117             :   }
    1118         171 :   auto types = child_results->NextAs<std::vector<TypeExpression*>>();
    1119         513 :   return ParseResult{LabelAndTypes{std::move(name), std::move(types)}};
    1120             : }
    1121             : 
    1122        1548 : base::Optional<ParseResult> MakeNameAndType(
    1123             :     ParseResultIterator* child_results) {
    1124        1548 :   auto name = child_results->NextAs<Identifier*>();
    1125        1548 :   auto type = child_results->NextAs<TypeExpression*>();
    1126        1548 :   return ParseResult{NameAndTypeExpression{name, type}};
    1127             : }
    1128             : 
    1129          85 : base::Optional<ParseResult> MakeNameAndExpression(
    1130             :     ParseResultIterator* child_results) {
    1131          85 :   auto name = child_results->NextAs<Identifier*>();
    1132          85 :   auto expression = child_results->NextAs<Expression*>();
    1133          85 :   return ParseResult{NameAndExpression{name, expression}};
    1134             : }
    1135             : 
    1136          21 : base::Optional<ParseResult> MakeNameAndExpressionFromExpression(
    1137             :     ParseResultIterator* child_results) {
    1138          21 :   auto expression = child_results->NextAs<Expression*>();
    1139          21 :   if (auto* id = IdentifierExpression::DynamicCast(expression)) {
    1140          21 :     if (!id->generic_arguments.empty() ||
    1141             :         !id->namespace_qualification.empty()) {
    1142           0 :       ReportError("expected a plain identifier without qualification");
    1143             :     }
    1144          42 :     return ParseResult{NameAndExpression{id->name, id}};
    1145             :   }
    1146           0 :   ReportError("Constructor parameters need to be named.");
    1147             : }
    1148             : 
    1149         319 : base::Optional<ParseResult> MakeClassField(ParseResultIterator* child_results) {
    1150         319 :   auto weak = child_results->NextAs<bool>();
    1151         319 :   auto const_qualified = child_results->NextAs<bool>();
    1152         319 :   auto name = child_results->NextAs<Identifier*>();
    1153         319 :   auto index = child_results->NextAs<base::Optional<std::string>>();
    1154         319 :   auto type = child_results->NextAs<TypeExpression*>();
    1155             :   return ParseResult{
    1156        1595 :       ClassFieldExpression{{name, type}, index, weak, const_qualified}};
    1157             : }
    1158             : 
    1159          48 : base::Optional<ParseResult> MakeStructField(
    1160             :     ParseResultIterator* child_results) {
    1161          48 :   auto const_qualified = child_results->NextAs<bool>();
    1162          48 :   auto name = child_results->NextAs<Identifier*>();
    1163          48 :   auto type = child_results->NextAs<TypeExpression*>();
    1164          96 :   return ParseResult{StructFieldExpression{{name, type}, const_qualified}};
    1165             : }
    1166             : 
    1167          11 : base::Optional<ParseResult> ExtractAssignmentOperator(
    1168             :     ParseResultIterator* child_results) {
    1169          11 :   auto op = child_results->NextAs<std::string>();
    1170          11 :   base::Optional<std::string> result = std::string(op.begin(), op.end() - 1);
    1171          44 :   return ParseResult(std::move(result));
    1172             : }
    1173             : 
    1174         108 : struct TorqueGrammar : Grammar {
    1175       59727 :   static bool MatchWhitespace(InputPosition* pos) {
    1176             :     while (true) {
    1177      138927 :       if (MatchChar(std::isspace, pos)) continue;
    1178       61415 :       if (MatchString("//", pos)) {
    1179      162218 :         while (MatchChar([](char c) { return c != '\n'; }, pos)) {
    1180             :         }
    1181             :         continue;
    1182             :       }
    1183       59727 :       return true;
    1184             :     }
    1185             :   }
    1186             : 
    1187       59673 :   static bool MatchIdentifier(InputPosition* pos) {
    1188       59673 :     if (!MatchChar(std::isalpha, pos)) return false;
    1189      218459 :     while (MatchChar(std::isalnum, pos) || MatchString("_", pos)) {
    1190             :     }
    1191             :     return true;
    1192             :   }
    1193             : 
    1194       59673 :   static bool MatchIntrinsicName(InputPosition* pos) {
    1195       59673 :     InputPosition current = *pos;
    1196       59673 :     if (!MatchString("%", &current)) return false;
    1197          55 :     if (!MatchChar(std::isalpha, &current)) return false;
    1198         664 :     while (MatchChar(std::isalnum, &current) || MatchString("_", pos)) {
    1199             :     }
    1200          55 :     *pos = current;
    1201          55 :     return true;
    1202             :   }
    1203             : 
    1204       59673 :   static bool MatchStringLiteral(InputPosition* pos) {
    1205       59673 :     InputPosition current = *pos;
    1206       59673 :     if (MatchString("\"", &current)) {
    1207           0 :       while (
    1208           0 :           (MatchString("\\", &current) && MatchAnyChar(&current)) ||
    1209           0 :           MatchChar([](char c) { return c != '"' && c != '\n'; }, &current)) {
    1210             :       }
    1211           0 :       if (MatchString("\"", &current)) {
    1212           0 :         *pos = current;
    1213           0 :         return true;
    1214             :       }
    1215             :     }
    1216       59673 :     current = *pos;
    1217       59673 :     if (MatchString("'", &current)) {
    1218        7853 :       while (
    1219       15703 :           (MatchString("\\", &current) && MatchAnyChar(&current)) ||
    1220       15700 :           MatchChar([](char c) { return c != '\'' && c != '\n'; }, &current)) {
    1221             :       }
    1222         463 :       if (MatchString("'", &current)) {
    1223         463 :         *pos = current;
    1224         463 :         return true;
    1225             :       }
    1226             :     }
    1227             :     return false;
    1228             :   }
    1229             : 
    1230       59673 :   static bool MatchHexLiteral(InputPosition* pos) {
    1231       59673 :     InputPosition current = *pos;
    1232       59673 :     MatchString("-", &current);
    1233       59673 :     if (MatchString("0x", &current) && MatchChar(std::isxdigit, &current)) {
    1234          57 :       while (MatchChar(std::isxdigit, &current)) {
    1235             :       }
    1236          18 :       *pos = current;
    1237          18 :       return true;
    1238             :     }
    1239             :     return false;
    1240             :   }
    1241             : 
    1242       59673 :   static bool MatchDecimalLiteral(InputPosition* pos) {
    1243       59673 :     InputPosition current = *pos;
    1244             :     bool found_digit = false;
    1245       59673 :     MatchString("-", &current);
    1246       60711 :     while (MatchChar(std::isdigit, &current)) found_digit = true;
    1247       59673 :     MatchString(".", &current);
    1248       59679 :     while (MatchChar(std::isdigit, &current)) found_digit = true;
    1249       59673 :     if (!found_digit) return false;
    1250         965 :     *pos = current;
    1251        2895 :     if ((MatchString("e", &current) || MatchString("E", &current)) &&
    1252         965 :         (MatchString("+", &current) || MatchString("-", &current) || true) &&
    1253           0 :         MatchChar(std::isdigit, &current)) {
    1254           0 :       while (MatchChar(std::isdigit, &current)) {
    1255             :       }
    1256           0 :       *pos = current;
    1257           0 :       return true;
    1258             :     }
    1259             :     return true;
    1260             :   }
    1261             : 
    1262       26676 :   TorqueGrammar() : Grammar(&file) { SetWhitespace(MatchWhitespace); }
    1263             : 
    1264             :   // Result: std::string
    1265             :   Symbol identifier = {Rule({Pattern(MatchIdentifier)}, YieldMatchedInput)};
    1266             : 
    1267             :   // Result: Identifier*
    1268             :   Symbol name = {Rule({&identifier}, MakeIdentifier)};
    1269             : 
    1270             :   // Result: std::string
    1271             :   Symbol intrinsicName = {
    1272             :       Rule({Pattern(MatchIntrinsicName)}, YieldMatchedInput)};
    1273             : 
    1274             :   // Result: std::string
    1275             :   Symbol stringLiteral = {
    1276             :       Rule({Pattern(MatchStringLiteral)}, YieldMatchedInput)};
    1277             : 
    1278             :   // Result: std::string
    1279             :   Symbol externalString = {Rule({&stringLiteral}, StringLiteralUnquoteAction)};
    1280             : 
    1281             :   // Result: std::string
    1282             :   Symbol decimalLiteral = {
    1283             :       Rule({Pattern(MatchDecimalLiteral)}, YieldMatchedInput),
    1284             :       Rule({Pattern(MatchHexLiteral)}, YieldMatchedInput)};
    1285             : 
    1286             :   // Result: TypeList
    1287         162 :   Symbol* typeList = List<TypeExpression*>(&type, Token(","));
    1288             : 
    1289             :   // Result: TypeExpression*
    1290             :   Symbol simpleType = {
    1291         216 :       Rule({Token("("), &type, Token(")")}),
    1292         216 :       Rule({List<std::string>(Sequence({&identifier, Token("::")})),
    1293         162 :             CheckIf(Token("constexpr")), &identifier},
    1294             :            MakeBasicTypeExpression),
    1295         486 :       Rule({Token("builtin"), Token("("), typeList, Token(")"), Token("=>"),
    1296             :             &simpleType},
    1297             :            MakeFunctionTypeExpression),
    1298         108 :       Rule({Token("&"), &simpleType}, MakeReferenceTypeExpression)};
    1299             : 
    1300             :   // Result: TypeExpression*
    1301         108 :   Symbol type = {Rule({&simpleType}), Rule({&type, Token("|"), &simpleType},
    1302             :                                            MakeUnionTypeExpression)};
    1303             : 
    1304             :   // Result: GenericParameters
    1305             :   Symbol genericParameters = {
    1306         108 :       Rule({Token("<"),
    1307         324 :             List<Identifier*>(Sequence({&name, Token(":"), Token("type")}),
    1308         108 :                               Token(",")),
    1309         108 :             Token(">")})};
    1310             : 
    1311             :   // Result: TypeList
    1312             :   Symbol genericSpecializationTypeList = {
    1313         270 :       Rule({Token("<"), typeList, Token(">")})};
    1314             : 
    1315             :   // Result: base::Optional<TypeList>
    1316             :   Symbol* optionalGenericParameters = Optional<TypeList>(&genericParameters);
    1317             : 
    1318             :   Symbol* optionalImplicitParameterList{
    1319         270 :       TryOrDefault<std::vector<NameAndTypeExpression>>(
    1320         216 :           Sequence({Token("("), Token("implicit"),
    1321         162 :                     List<NameAndTypeExpression>(&nameAndType, Token(",")),
    1322         108 :                     Token(")")}))};
    1323             : 
    1324             :   // Result: ParameterList
    1325             :   Symbol typeListMaybeVarArgs = {
    1326         162 :       Rule({optionalImplicitParameterList, Token("("),
    1327         324 :             List<TypeExpression*>(Sequence({&type, Token(",")})), Token("..."),
    1328         108 :             Token(")")},
    1329             :            MakeParameterListFromTypes<true>),
    1330         324 :       Rule({optionalImplicitParameterList, Token("("), typeList, Token(")")},
    1331             :            MakeParameterListFromTypes<false>)};
    1332             : 
    1333             :   // Result: LabelAndTypes
    1334             :   Symbol labelParameter = {Rule(
    1335             :       {&identifier,
    1336         324 :        TryOrDefault<TypeList>(Sequence({Token("("), typeList, Token(")")}))},
    1337             :       MakeLabelAndTypes)};
    1338             : 
    1339             :   // Result: TypeExpression*
    1340         108 :   Symbol optionalReturnType = {Rule({Token(":"), &type}),
    1341             :                                Rule({}, MakeVoidType)};
    1342             : 
    1343             :   // Result: LabelAndTypesVector
    1344         162 :   Symbol* optionalLabelList{TryOrDefault<LabelAndTypesVector>(
    1345         108 :       Sequence({Token("labels"),
    1346         216 :                 NonemptyList<LabelAndTypes>(&labelParameter, Token(","))}))};
    1347             : 
    1348             :   // Result: std::vector<Statement*>
    1349         162 :   Symbol* optionalOtherwise{TryOrDefault<std::vector<Statement*>>(
    1350         108 :       Sequence({Token("otherwise"),
    1351         216 :                 NonemptyList<Statement*>(&atomarStatement, Token(","))}))};
    1352             : 
    1353             :   // Result: NameAndTypeExpression
    1354         108 :   Symbol nameAndType = {Rule({&name, Token(":"), &type}, MakeNameAndType)};
    1355             : 
    1356             :   Symbol* optionalArraySpecifier =
    1357         324 :       Optional<std::string>(Sequence({Token("["), &identifier, Token("]")}));
    1358             : 
    1359             :   Symbol classField = {
    1360         324 :       Rule({CheckIf(Token("weak")), CheckIf(Token("const")), &name,
    1361         270 :             optionalArraySpecifier, Token(":"), &type, Token(";")},
    1362             :            MakeClassField)};
    1363             : 
    1364             :   Symbol structField = {
    1365         378 :       Rule({CheckIf(Token("const")), &name, Token(":"), &type, Token(";")},
    1366             :            MakeStructField)};
    1367             : 
    1368             :   // Result: ParameterList
    1369             :   Symbol parameterListNoVararg = {
    1370         162 :       Rule({optionalImplicitParameterList, Token("("),
    1371         216 :             List<NameAndTypeExpression>(&nameAndType, Token(",")), Token(")")},
    1372             :            MakeParameterListFromNameAndTypeList<false>)};
    1373             : 
    1374             :   // Result: ParameterList
    1375             :   Symbol parameterListAllowVararg = {
    1376             :       Rule({&parameterListNoVararg}),
    1377         162 :       Rule({optionalImplicitParameterList, Token("("),
    1378         216 :             NonemptyList<NameAndTypeExpression>(&nameAndType, Token(",")),
    1379         324 :             Token(","), Token("..."), &identifier, Token(")")},
    1380             :            MakeParameterListFromNameAndTypeList<true>)};
    1381             : 
    1382             :   // Result: std::string
    1383         648 :   Symbol* OneOf(const std::vector<std::string>& alternatives) {
    1384         648 :     Symbol* result = NewSymbol();
    1385        2808 :     for (const std::string& s : alternatives) {
    1386        8640 :       result->AddRule(Rule({Token(s)}, YieldMatchedInput));
    1387             :     }
    1388         648 :     return result;
    1389             :   }
    1390             : 
    1391             :   // Result: Expression*
    1392         270 :   Symbol* BinaryOperator(Symbol* nextLevel, Symbol* op) {
    1393         270 :     Symbol* result = NewSymbol();
    1394             :     *result = {Rule({nextLevel}),
    1395        1620 :                Rule({result, op, nextLevel}, MakeBinaryOperator)};
    1396         270 :     return result;
    1397             :   }
    1398             : 
    1399             :   // Result: Expression*
    1400             :   Symbol* expression = &assignmentExpression;
    1401             : 
    1402             :   // Result: IncrementDecrementOperator
    1403             :   Symbol incrementDecrementOperator = {
    1404         108 :       Rule({Token("++")},
    1405             :            YieldIntegralConstant<IncrementDecrementOperator,
    1406             :                                  IncrementDecrementOperator::kIncrement>),
    1407         108 :       Rule({Token("--")},
    1408             :            YieldIntegralConstant<IncrementDecrementOperator,
    1409             :                                  IncrementDecrementOperator::kDecrement>)};
    1410             : 
    1411             :   // Result: Expression*
    1412             :   Symbol identifierExpression = {
    1413         216 :       Rule({List<std::string>(Sequence({&identifier, Token("::")})), &name,
    1414          54 :             TryOrDefault<TypeList>(&genericSpecializationTypeList)},
    1415             :            MakeIdentifierExpression),
    1416             :   };
    1417             : 
    1418             :   // Result: std::vector<Expression*>
    1419             :   Symbol argumentList = {Rule(
    1420         378 :       {Token("("), List<Expression*>(expression, Token(",")), Token(")")})};
    1421             : 
    1422             :   // Result: Expression*
    1423             :   Symbol callExpression = {Rule(
    1424          54 :       {&identifierExpression, &argumentList, optionalOtherwise}, MakeCall)};
    1425             : 
    1426             :   // Result: Expression*
    1427             :   Symbol callMethodExpression = {
    1428         108 :       Rule({&primaryExpression, Token("."), &identifier, &argumentList,
    1429          54 :             optionalOtherwise},
    1430             :            MakeMethodCall)};
    1431             : 
    1432             :   // Result: NameAndExpression
    1433             :   Symbol namedExpression = {
    1434         162 :       Rule({&name, Token(":"), expression}, MakeNameAndExpression),
    1435          54 :       Rule({expression}, MakeNameAndExpressionFromExpression)};
    1436             : 
    1437             :   // Result: std::vector<NameAndExpression>
    1438             :   Symbol initializerList = {
    1439         216 :       Rule({Token("{"), List<NameAndExpression>(&namedExpression, Token(",")),
    1440         108 :             Token("}")})};
    1441             : 
    1442             :   // Result: Expression*
    1443             :   Symbol intrinsicCallExpression = {Rule(
    1444          54 :       {&intrinsicName, TryOrDefault<TypeList>(&genericSpecializationTypeList),
    1445             :        &argumentList},
    1446             :       MakeIntrinsicCallExpression)};
    1447             : 
    1448             :   // Result: Expression*
    1449             :   Symbol primaryExpression = {
    1450             :       Rule({&callExpression}),
    1451             :       Rule({&callMethodExpression}),
    1452             :       Rule({&intrinsicCallExpression}),
    1453             :       Rule({&identifierExpression}),
    1454         108 :       Rule({&primaryExpression, Token("."), &name}, MakeFieldAccessExpression),
    1455         270 :       Rule({&primaryExpression, Token("["), expression, Token("]")},
    1456             :            MakeElementAccessExpression),
    1457             :       Rule({&decimalLiteral}, MakeNumberLiteralExpression),
    1458             :       Rule({&stringLiteral}, MakeStringLiteralExpression),
    1459             :       Rule({&simpleType, &initializerList}, MakeStructExpression),
    1460         108 :       Rule({Token("new"), &simpleType, &initializerList}, MakeNewExpression),
    1461         270 :       Rule({Token("("), expression, Token(")")})};
    1462             : 
    1463             :   // Result: Expression*
    1464             :   Symbol unaryExpression = {
    1465             :       Rule({&primaryExpression}),
    1466         162 :       Rule({OneOf({"+", "-", "!", "~", "&"}), &unaryExpression},
    1467             :            MakeUnaryOperator),
    1468         108 :       Rule({Token("*"), &unaryExpression}, MakeDereferenceExpression),
    1469         108 :       Rule({Token("..."), &unaryExpression}, MakeSpreadExpression),
    1470             :       Rule({&incrementDecrementOperator, &unaryExpression},
    1471             :            MakeIncrementDecrementExpressionPrefix),
    1472             :       Rule({&unaryExpression, &incrementDecrementOperator},
    1473             :            MakeIncrementDecrementExpressionPostfix)};
    1474             : 
    1475             :   // Result: Expression*
    1476             :   Symbol* multiplicativeExpression =
    1477         162 :       BinaryOperator(&unaryExpression, OneOf({"*", "/", "%"}));
    1478             : 
    1479             :   // Result: Expression*
    1480             :   Symbol* additiveExpression =
    1481         162 :       BinaryOperator(multiplicativeExpression, OneOf({"+", "-"}));
    1482             : 
    1483             :   // Result: Expression*
    1484             :   Symbol* shiftExpression =
    1485         162 :       BinaryOperator(additiveExpression, OneOf({"<<", ">>", ">>>"}));
    1486             : 
    1487             :   // Do not allow expressions like a < b > c because this is never
    1488             :   // useful and ambiguous with template parameters.
    1489             :   // Result: Expression*
    1490             :   Symbol relationalExpression = {
    1491          54 :       Rule({shiftExpression}),
    1492         270 :       Rule({shiftExpression, OneOf({"<", ">", "<=", ">="}), shiftExpression},
    1493             :            MakeBinaryOperator)};
    1494             : 
    1495             :   // Result: Expression*
    1496             :   Symbol* equalityExpression =
    1497         162 :       BinaryOperator(&relationalExpression, OneOf({"==", "!="}));
    1498             : 
    1499             :   // Result: Expression*
    1500             :   Symbol* bitwiseExpression =
    1501         162 :       BinaryOperator(equalityExpression, OneOf({"&", "|"}));
    1502             : 
    1503             :   // Result: Expression*
    1504             :   Symbol logicalAndExpression = {
    1505          54 :       Rule({bitwiseExpression}),
    1506         162 :       Rule({&logicalAndExpression, Token("&&"), bitwiseExpression},
    1507             :            MakeLogicalAndExpression)};
    1508             : 
    1509             :   // Result: Expression*
    1510             :   Symbol logicalOrExpression = {
    1511             :       Rule({&logicalAndExpression}),
    1512         108 :       Rule({&logicalOrExpression, Token("||"), &logicalAndExpression},
    1513             :            MakeLogicalOrExpression)};
    1514             : 
    1515             :   // Result: Expression*
    1516             :   Symbol conditionalExpression = {
    1517             :       Rule({&logicalOrExpression}),
    1518         270 :       Rule({&logicalOrExpression, Token("?"), expression, Token(":"),
    1519             :             &conditionalExpression},
    1520             :            MakeConditionalExpression)};
    1521             : 
    1522             :   // Result: base::Optional<std::string>
    1523             :   Symbol assignmentOperator = {
    1524         108 :       Rule({Token("=")}, YieldDefaultValue<base::Optional<std::string>>),
    1525         162 :       Rule({OneOf({"*=", "/=", "%=", "+=", "-=", "<<=", ">>=", ">>>=", "&=",
    1526             :                    "^=", "|="})},
    1527             :            ExtractAssignmentOperator)};
    1528             : 
    1529             :   // Result: Expression*
    1530             :   Symbol assignmentExpression = {
    1531             :       Rule({&conditionalExpression}),
    1532             :       Rule({&conditionalExpression, &assignmentOperator, &assignmentExpression},
    1533             :            MakeAssignmentExpression)};
    1534             : 
    1535             :   // Result: Statement*
    1536         270 :   Symbol block = {Rule({CheckIf(Token("deferred")), Token("{"),
    1537         162 :                         List<Statement*>(&statement), Token("}")},
    1538             :                        MakeBlockStatement)};
    1539             : 
    1540             :   // Result: LabelBlock*
    1541             :   Symbol labelBlock = {
    1542         108 :       Rule({Token("label"), &identifier,
    1543          54 :             TryOrDefault<ParameterList>(&parameterListNoVararg), &block},
    1544             :            MakeLabelBlock)};
    1545             : 
    1546             :   Symbol catchBlock = {
    1547         324 :       Rule({Token("catch"), Token("("), &identifier, Token(")"), &block},
    1548             :            MakeCatchBlock)};
    1549             : 
    1550             :   // Result: ExpressionWithSource
    1551          54 :   Symbol expressionWithSource = {Rule({expression}, MakeExpressionWithSource)};
    1552             : 
    1553             :   // Result: RangeExpression
    1554             :   Symbol rangeSpecifier = {
    1555         270 :       Rule({Token("["), Optional<Expression*>(expression), Token(":"),
    1556         162 :             Optional<Expression*>(expression), Token("]")},
    1557             :            MakeRangeExpression)};
    1558             : 
    1559             :   Symbol* optionalTypeSpecifier =
    1560         216 :       Optional<TypeExpression*>(Sequence({Token(":"), &type}));
    1561             : 
    1562             :   // Result: Statement*
    1563             :   Symbol varDeclaration = {
    1564         216 :       Rule({OneOf({"let", "const"}), &name, optionalTypeSpecifier},
    1565             :            MakeVarDeclarationStatement)};
    1566             : 
    1567             :   // Result: Statement*
    1568             :   Symbol varDeclarationWithInitialization = {
    1569         270 :       Rule({OneOf({"let", "const"}), &name, optionalTypeSpecifier, Token("="),
    1570          54 :             expression},
    1571             :            MakeVarDeclarationStatement)};
    1572             : 
    1573             :   // Result: Statement*
    1574             :   Symbol atomarStatement = {
    1575          54 :       Rule({expression}, MakeExpressionStatement),
    1576         162 :       Rule({Token("return"), Optional<Expression*>(expression)},
    1577             :            MakeReturnStatement),
    1578         108 :       Rule({Token("tail"), &callExpression}, MakeTailCallStatement),
    1579         108 :       Rule({Token("break")}, MakeBreakStatement),
    1580         108 :       Rule({Token("continue")}, MakeContinueStatement),
    1581         108 :       Rule({Token("goto"), &identifier,
    1582          54 :             TryOrDefault<std::vector<Expression*>>(&argumentList)},
    1583             :            MakeGotoStatement),
    1584         162 :       Rule({OneOf({"debug", "unreachable"})}, MakeDebugStatement)};
    1585             : 
    1586             :   // Result: Statement*
    1587             :   Symbol statement = {
    1588             :       Rule({&block}),
    1589         108 :       Rule({&atomarStatement, Token(";")}),
    1590         108 :       Rule({&varDeclaration, Token(";")}),
    1591         108 :       Rule({&varDeclarationWithInitialization, Token(";")}),
    1592         432 :       Rule({Token("if"), CheckIf(Token("constexpr")), Token("("), expression,
    1593         108 :             Token(")"), &statement,
    1594         216 :             Optional<Statement*>(Sequence({Token("else"), &statement}))},
    1595             :            MakeIfStatement),
    1596             :       Rule(
    1597             :           {
    1598         378 :               Token("typeswitch"), Token("("), expression, Token(")"),
    1599         216 :               Token("{"), NonemptyList<TypeswitchCase>(&typeswitchCase),
    1600         108 :               Token("}"),
    1601             :           },
    1602             :           MakeTypeswitchStatement),
    1603         216 :       Rule({Token("try"), &block, List<LabelBlock*>(&labelBlock),
    1604             :             Optional<LabelBlock*>(&catchBlock)},
    1605             :            MakeTryLabelExpression),
    1606         216 :       Rule({OneOf({"assert", "check"}), Token("("), &expressionWithSource,
    1607         216 :             Token(")"), Token(";")},
    1608             :            MakeAssertStatement),
    1609         378 :       Rule({Token("while"), Token("("), expression, Token(")"), &statement},
    1610             :            MakeWhileStatement),
    1611         378 :       Rule({Token("for"), Token("("), &varDeclaration, Token("of"), expression,
    1612         108 :             Optional<RangeExpression>(&rangeSpecifier), Token(")"), &statement},
    1613             :            MakeForOfLoopStatement),
    1614         216 :       Rule({Token("for"), Token("("),
    1615         108 :             Optional<Statement*>(&varDeclarationWithInitialization), Token(";"),
    1616         162 :             Optional<Expression*>(expression), Token(";"),
    1617         162 :             Optional<Expression*>(expression), Token(")"), &statement},
    1618             :            MakeForLoopStatement)};
    1619             : 
    1620             :   // Result: TypeswitchCase
    1621             :   Symbol typeswitchCase = {
    1622         216 :       Rule({Token("case"), Token("("),
    1623         216 :             Optional<std::string>(Sequence({&identifier, Token(":")})), &type,
    1624         216 :             Token(")"), Token(":"), &block},
    1625             :            MakeTypeswitchCase)};
    1626             : 
    1627             :   // Result: base::Optional<Statement*>
    1628             :   Symbol optionalBody = {
    1629             :       Rule({&block}, CastParseResult<Statement*, base::Optional<Statement*>>),
    1630         108 :       Rule({Token(";")}, YieldDefaultValue<base::Optional<Statement*>>)};
    1631             : 
    1632             :   // Result: Declaration*
    1633             :   Symbol method = {Rule(
    1634         162 :       {CheckIf(Token("transitioning")),
    1635         216 :        Optional<std::string>(Sequence({Token("operator"), &externalString})),
    1636             :        &identifier, &parameterListNoVararg, &optionalReturnType,
    1637          54 :        optionalLabelList, &block},
    1638             :       MakeMethodDeclaration)};
    1639             : 
    1640             :   // Result: Declaration*
    1641             :   Symbol declaration = {
    1642         378 :       Rule({Token("const"), &name, Token(":"), &type, Token("="), expression,
    1643         108 :             Token(";")},
    1644             :            MakeConstDeclaration),
    1645         324 :       Rule({Token("const"), &name, Token(":"), &type, Token("generates"),
    1646         108 :             &externalString, Token(";")},
    1647             :            MakeExternConstDeclaration),
    1648         324 :       Rule({CheckIf(Token("@generatePrint")), CheckIf(Token("extern")),
    1649         270 :             CheckIf(Token("transient")), Token("class"), &name,
    1650         216 :             Optional<std::string>(Sequence({Token("extends"), &identifier})),
    1651         108 :             Optional<std::string>(
    1652         108 :                 Sequence({Token("generates"), &externalString})),
    1653         216 :             Token("{"), List<Declaration*>(&method),
    1654         162 :             List<ClassFieldExpression>(&classField), Token("}")},
    1655             :            MakeClassDeclaration),
    1656         324 :       Rule({Token("struct"), &name, Token("{"), List<Declaration*>(&method),
    1657         162 :             List<StructFieldExpression>(&structField), Token("}")},
    1658             :            MakeStructDeclaration),
    1659         270 :       Rule({CheckIf(Token("transient")), Token("type"), &name,
    1660         216 :             Optional<Identifier*>(Sequence({Token("extends"), &name})),
    1661         108 :             Optional<std::string>(
    1662         108 :                 Sequence({Token("generates"), &externalString})),
    1663         108 :             Optional<std::string>(
    1664         108 :                 Sequence({Token("constexpr"), &externalString})),
    1665         108 :             Token(";")},
    1666             :            MakeTypeDeclaration),
    1667         324 :       Rule({Token("type"), &name, Token("="), &type, Token(";")},
    1668             :            MakeTypeAliasDeclaration),
    1669         108 :       Rule({Token("intrinsic"), &intrinsicName,
    1670          54 :             TryOrDefault<GenericParameters>(&genericParameters),
    1671         108 :             &parameterListNoVararg, &optionalReturnType, Token(";")},
    1672             :            MakeIntrinsicDeclaration),
    1673         270 :       Rule({Token("extern"), CheckIf(Token("transitioning")),
    1674         108 :             Optional<std::string>(
    1675         108 :                 Sequence({Token("operator"), &externalString})),
    1676         108 :             Token("macro"),
    1677         216 :             Optional<std::string>(Sequence({&identifier, Token("::")})),
    1678          54 :             &identifier, TryOrDefault<GenericParameters>(&genericParameters),
    1679          54 :             &typeListMaybeVarArgs, &optionalReturnType, optionalLabelList,
    1680         108 :             Token(";")},
    1681             :            MakeExternalMacro),
    1682         270 :       Rule({Token("extern"), CheckIf(Token("transitioning")),
    1683         270 :             CheckIf(Token("javascript")), Token("builtin"), &identifier,
    1684          54 :             TryOrDefault<GenericParameters>(&genericParameters),
    1685         108 :             &typeListMaybeVarArgs, &optionalReturnType, Token(";")},
    1686             :            MakeExternalBuiltin),
    1687             :       Rule(
    1688         378 :           {Token("extern"), CheckIf(Token("transitioning")), Token("runtime"),
    1689         108 :            &identifier, &typeListMaybeVarArgs, &optionalReturnType, Token(";")},
    1690             :           MakeExternalRuntime),
    1691         162 :       Rule({CheckIf(Token("transitioning")),
    1692         108 :             Optional<std::string>(
    1693         108 :                 Sequence({Token("operator"), &externalString})),
    1694         108 :             Token("macro"), &identifier,
    1695          54 :             TryOrDefault<GenericParameters>(&genericParameters),
    1696          54 :             &parameterListNoVararg, &optionalReturnType, optionalLabelList,
    1697             :             &optionalBody},
    1698             :            MakeTorqueMacroDeclaration),
    1699         324 :       Rule({CheckIf(Token("transitioning")), CheckIf(Token("javascript")),
    1700         108 :             Token("builtin"), &identifier,
    1701          54 :             TryOrDefault<GenericParameters>(&genericParameters),
    1702             :             &parameterListAllowVararg, &optionalReturnType, &optionalBody},
    1703             :            MakeTorqueBuiltinDeclaration),
    1704             :       Rule({&identifier, &genericSpecializationTypeList,
    1705          54 :             &parameterListAllowVararg, &optionalReturnType, optionalLabelList,
    1706             :             &block},
    1707             :            MakeSpecializationDeclaration),
    1708         108 :       Rule({Token("#include"), &externalString}, MakeCppIncludeDeclaration)};
    1709             : 
    1710             :   // Result: Declaration*
    1711             :   Symbol namespaceDeclaration = {
    1712         216 :       Rule({Token("namespace"), &identifier, Token("{"),
    1713         162 :             List<Declaration*>(&declaration), Token("}")},
    1714             :            MakeNamespaceDeclaration)};
    1715             : 
    1716             :   Symbol file = {Rule({&file, &namespaceDeclaration}, AddGlobalDeclaration),
    1717             :                  Rule({&file, &declaration}, AddGlobalDeclaration), Rule({})};
    1718             : };
    1719             : 
    1720             : }  // namespace
    1721             : 
    1722         108 : void ParseTorque(const std::string& input) { TorqueGrammar().Parse(input); }
    1723             : 
    1724             : }  // namespace torque
    1725             : }  // namespace internal
    1726       59456 : }  // namespace v8

Generated by: LCOV version 1.10