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