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