LCOV - code coverage report
Current view: top level - src/torque - torque-parser.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 702 734 95.6 %
Date: 2019-01-20 Functions: 88 90 97.8 %

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

Generated by: LCOV version 1.10