// Copyright 2018 the V8 project authors. All rights reserved.
|
// Use of this source code is governed by a BSD-style license that can be
|
// found in the LICENSE file.
|
|
#include <cctype>
|
|
#include "src/torque/earley-parser.h"
|
#include "src/torque/torque-parser.h"
|
#include "src/torque/utils.h"
|
|
namespace v8 {
|
namespace internal {
|
namespace torque {
|
|
DEFINE_CONTEXTUAL_VARIABLE(CurrentAst);
|
|
using TypeList = std::vector<TypeExpression*>;
|
using GenericParameters = std::vector<std::string>;
|
|
struct ExpressionWithSource {
|
Expression* expression;
|
std::string source;
|
};
|
|
struct TypeswitchCase {
|
SourcePosition pos;
|
base::Optional<std::string> name;
|
TypeExpression* type;
|
Statement* block;
|
};
|
|
enum class ParseResultHolderBase::TypeId {
|
kStdString,
|
kBool,
|
kStdVectorOfString,
|
kExpressionPtr,
|
kLocationExpressionPtr,
|
kStatementPtr,
|
kDeclarationPtr,
|
kTypeExpressionPtr,
|
kLabelBlockPtr,
|
kNameAndTypeExpression,
|
kStdVectorOfNameAndTypeExpression,
|
kIncrementDecrementOperator,
|
kOptionalStdString,
|
kStdVectorOfStatementPtr,
|
kStdVectorOfDeclarationPtr,
|
kStdVectorOfExpressionPtr,
|
kExpressionWithSource,
|
kParameterList,
|
kRangeExpression,
|
kOptionalRangeExpression,
|
kTypeList,
|
kOptionalTypeList,
|
kLabelAndTypes,
|
kStdVectorOfLabelAndTypes,
|
kStdVectorOfLabelBlockPtr,
|
kOptionalStatementPtr,
|
kOptionalExpressionPtr,
|
kTypeswitchCase,
|
kStdVectorOfTypeswitchCase
|
};
|
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<std::string>::id =
|
ParseResultTypeId::kStdString;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<bool>::id =
|
ParseResultTypeId::kBool;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<std::vector<std::string>>::id =
|
ParseResultTypeId::kStdVectorOfString;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Declaration*>::id =
|
ParseResultTypeId::kDeclarationPtr;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<TypeExpression*>::id =
|
ParseResultTypeId::kTypeExpressionPtr;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<LabelBlock*>::id =
|
ParseResultTypeId::kLabelBlockPtr;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Expression*>::id =
|
ParseResultTypeId::kExpressionPtr;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<LocationExpression*>::id =
|
ParseResultTypeId::kLocationExpressionPtr;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<Statement*>::id =
|
ParseResultTypeId::kStatementPtr;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<NameAndTypeExpression>::id =
|
ParseResultTypeId::kNameAndTypeExpression;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<std::vector<NameAndTypeExpression>>::id =
|
ParseResultTypeId::kStdVectorOfNameAndTypeExpression;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<IncrementDecrementOperator>::id =
|
ParseResultTypeId::kIncrementDecrementOperator;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<base::Optional<std::string>>::id =
|
ParseResultTypeId::kOptionalStdString;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<std::vector<Statement*>>::id =
|
ParseResultTypeId::kStdVectorOfStatementPtr;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<std::vector<Declaration*>>::id =
|
ParseResultTypeId::kStdVectorOfDeclarationPtr;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<std::vector<Expression*>>::id =
|
ParseResultTypeId::kStdVectorOfExpressionPtr;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<ExpressionWithSource>::id =
|
ParseResultTypeId::kExpressionWithSource;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<ParameterList>::id =
|
ParseResultTypeId::kParameterList;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<RangeExpression>::id =
|
ParseResultTypeId::kRangeExpression;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<base::Optional<RangeExpression>>::id =
|
ParseResultTypeId::kOptionalRangeExpression;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<TypeList>::id =
|
ParseResultTypeId::kTypeList;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<base::Optional<TypeList>>::id =
|
ParseResultTypeId::kOptionalTypeList;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<LabelAndTypes>::id =
|
ParseResultTypeId::kLabelAndTypes;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<std::vector<LabelAndTypes>>::id =
|
ParseResultTypeId::kStdVectorOfLabelAndTypes;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<std::vector<LabelBlock*>>::id =
|
ParseResultTypeId::kStdVectorOfLabelBlockPtr;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<base::Optional<Statement*>>::id =
|
ParseResultTypeId::kOptionalStatementPtr;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<base::Optional<Expression*>>::id =
|
ParseResultTypeId::kOptionalExpressionPtr;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<TypeswitchCase>::id = ParseResultTypeId::kTypeswitchCase;
|
template <>
|
V8_EXPORT_PRIVATE const ParseResultTypeId
|
ParseResultHolder<std::vector<TypeswitchCase>>::id =
|
ParseResultTypeId::kStdVectorOfTypeswitchCase;
|
|
namespace {
|
|
base::Optional<ParseResult> AddGlobalDeclaration(
|
ParseResultIterator* child_results) {
|
auto declaration = child_results->NextAs<Declaration*>();
|
CurrentAst::Get().declarations().push_back(declaration);
|
return base::nullopt;
|
}
|
|
template <class T, class... Args>
|
T* MakeNode(Args... args) {
|
return CurrentAst::Get().AddNode(std::unique_ptr<T>(
|
new T(CurrentSourcePosition::Get(), std::move(args)...)));
|
}
|
|
base::Optional<ParseResult> MakeCall(ParseResultIterator* child_results) {
|
auto callee = child_results->NextAs<std::string>();
|
auto generic_args = child_results->NextAs<TypeList>();
|
auto args = child_results->NextAs<std::vector<Expression*>>();
|
auto labels = child_results->NextAs<std::vector<std::string>>();
|
Expression* result =
|
MakeNode<CallExpression>(callee, false, generic_args, args, labels);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeBinaryOperator(
|
ParseResultIterator* child_results) {
|
auto left = child_results->NextAs<Expression*>();
|
auto op = child_results->NextAs<std::string>();
|
auto right = child_results->NextAs<Expression*>();
|
Expression* result = MakeNode<CallExpression>(
|
op, true, TypeList{}, std::vector<Expression*>{left, right},
|
std::vector<std::string>{});
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeUnaryOperator(
|
ParseResultIterator* child_results) {
|
auto op = child_results->NextAs<std::string>();
|
auto e = child_results->NextAs<Expression*>();
|
Expression* result = MakeNode<CallExpression>(op, true, TypeList{},
|
std::vector<Expression*>{e},
|
std::vector<std::string>{});
|
return ParseResult{result};
|
}
|
|
template <bool has_varargs>
|
base::Optional<ParseResult> MakeParameterListFromTypes(
|
ParseResultIterator* child_results) {
|
auto types = child_results->NextAs<TypeList>();
|
ParameterList result;
|
result.types = std::move(types);
|
result.has_varargs = has_varargs;
|
return ParseResult{std::move(result)};
|
}
|
template <bool has_varargs>
|
base::Optional<ParseResult> MakeParameterListFromNameAndTypeList(
|
ParseResultIterator* child_results) {
|
auto params = child_results->NextAs<std::vector<NameAndTypeExpression>>();
|
std::string arguments_variable = "";
|
if (child_results->HasNext()) {
|
arguments_variable = child_results->NextAs<std::string>();
|
}
|
ParameterList result;
|
for (NameAndTypeExpression& pair : params) {
|
result.names.push_back(std::move(pair.name));
|
result.types.push_back(pair.type);
|
}
|
result.has_varargs = has_varargs;
|
result.arguments_variable = arguments_variable;
|
return ParseResult{std::move(result)};
|
}
|
|
base::Optional<ParseResult> MakeAssertStatement(
|
ParseResultIterator* child_results) {
|
auto kind = child_results->NextAs<std::string>();
|
auto expr_with_source = child_results->NextAs<ExpressionWithSource>();
|
DCHECK(kind == "assert" || kind == "check");
|
Statement* result = MakeNode<AssertStatement>(
|
kind == "assert", expr_with_source.expression, expr_with_source.source);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeDebugStatement(
|
ParseResultIterator* child_results) {
|
auto kind = child_results->NextAs<std::string>();
|
DCHECK(kind == "unreachable" || kind == "debug");
|
Statement* result = MakeNode<DebugStatement>(kind, kind == "unreachable");
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeVoidType(ParseResultIterator* child_results) {
|
TypeExpression* result = MakeNode<BasicTypeExpression>(false, "void");
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeExternalMacro(
|
ParseResultIterator* child_results) {
|
auto operator_name = child_results->NextAs<base::Optional<std::string>>();
|
auto name = child_results->NextAs<std::string>();
|
auto generic_parameters = child_results->NextAs<GenericParameters>();
|
auto args = child_results->NextAs<ParameterList>();
|
auto return_type = child_results->NextAs<TypeExpression*>();
|
auto labels = child_results->NextAs<LabelAndTypesVector>();
|
MacroDeclaration* macro = MakeNode<ExternalMacroDeclaration>(
|
name, operator_name, args, return_type, labels);
|
Declaration* result;
|
if (generic_parameters.empty()) {
|
result = MakeNode<StandardDeclaration>(macro, nullptr);
|
} else {
|
result = MakeNode<GenericDeclaration>(macro, generic_parameters);
|
}
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeTorqueMacroDeclaration(
|
ParseResultIterator* child_results) {
|
auto operator_name = child_results->NextAs<base::Optional<std::string>>();
|
auto name = child_results->NextAs<std::string>();
|
auto generic_parameters = child_results->NextAs<GenericParameters>();
|
auto args = child_results->NextAs<ParameterList>();
|
auto return_type = child_results->NextAs<TypeExpression*>();
|
auto labels = child_results->NextAs<LabelAndTypesVector>();
|
auto body = child_results->NextAs<base::Optional<Statement*>>();
|
MacroDeclaration* macro = MakeNode<TorqueMacroDeclaration>(
|
name, operator_name, args, return_type, labels);
|
Declaration* result;
|
if (generic_parameters.empty()) {
|
if (!body) ReportError("A non-generic declaration needs a body.");
|
result = MakeNode<StandardDeclaration>(macro, *body);
|
} else {
|
result = MakeNode<GenericDeclaration>(macro, generic_parameters, body);
|
}
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeTorqueBuiltinDeclaration(
|
ParseResultIterator* child_results) {
|
auto javascript_linkage = child_results->NextAs<bool>();
|
auto name = child_results->NextAs<std::string>();
|
auto generic_parameters = child_results->NextAs<GenericParameters>();
|
auto args = child_results->NextAs<ParameterList>();
|
auto return_type = child_results->NextAs<TypeExpression*>();
|
auto body = child_results->NextAs<base::Optional<Statement*>>();
|
BuiltinDeclaration* builtin = MakeNode<TorqueBuiltinDeclaration>(
|
javascript_linkage, name, args, return_type);
|
Declaration* result;
|
if (generic_parameters.empty()) {
|
if (!body) ReportError("A non-generic declaration needs a body.");
|
result = MakeNode<StandardDeclaration>(builtin, *body);
|
} else {
|
result = MakeNode<GenericDeclaration>(builtin, generic_parameters, body);
|
}
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeConstDeclaration(
|
ParseResultIterator* child_results) {
|
auto name = child_results->NextAs<std::string>();
|
auto type = child_results->NextAs<TypeExpression*>();
|
auto expression = child_results->NextAs<Expression*>();
|
Declaration* result =
|
MakeNode<ConstDeclaration>(std::move(name), type, expression);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeExternConstDeclaration(
|
ParseResultIterator* child_results) {
|
auto name = child_results->NextAs<std::string>();
|
auto type = child_results->NextAs<TypeExpression*>();
|
auto literal = child_results->NextAs<std::string>();
|
Declaration* result = MakeNode<ExternConstDeclaration>(std::move(name), type,
|
std::move(literal));
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeTypeAliasDeclaration(
|
ParseResultIterator* child_results) {
|
auto name = child_results->NextAs<std::string>();
|
auto type = child_results->NextAs<TypeExpression*>();
|
Declaration* result = MakeNode<TypeAliasDeclaration>(std::move(name), type);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeTypeDeclaration(
|
ParseResultIterator* child_results) {
|
auto name = child_results->NextAs<std::string>();
|
auto extends = child_results->NextAs<base::Optional<std::string>>();
|
auto generates = child_results->NextAs<base::Optional<std::string>>();
|
auto constexpr_generates =
|
child_results->NextAs<base::Optional<std::string>>();
|
Declaration* result = MakeNode<TypeDeclaration>(
|
std::move(name), std::move(extends), std::move(generates),
|
std::move(constexpr_generates));
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeExplicitModuleDeclaration(
|
ParseResultIterator* child_results) {
|
auto name = child_results->NextAs<std::string>();
|
auto declarations = child_results->NextAs<std::vector<Declaration*>>();
|
Declaration* result = MakeNode<ExplicitModuleDeclaration>(
|
std::move(name), std::move(declarations));
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeSpecializationDeclaration(
|
ParseResultIterator* child_results) {
|
auto name = child_results->NextAs<std::string>();
|
auto generic_parameters =
|
child_results->NextAs<std::vector<TypeExpression*>>();
|
auto parameters = child_results->NextAs<ParameterList>();
|
auto return_type = child_results->NextAs<TypeExpression*>();
|
auto labels = child_results->NextAs<LabelAndTypesVector>();
|
auto body = child_results->NextAs<Statement*>();
|
Declaration* result = MakeNode<SpecializationDeclaration>(
|
std::move(name), std::move(generic_parameters), std::move(parameters),
|
return_type, std::move(labels), body);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeStructDeclaration(
|
ParseResultIterator* child_results) {
|
auto name = child_results->NextAs<std::string>();
|
auto fields = child_results->NextAs<std::vector<NameAndTypeExpression>>();
|
Declaration* result =
|
MakeNode<StructDeclaration>(std::move(name), std::move(fields));
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeExternalBuiltin(
|
ParseResultIterator* child_results) {
|
auto js_linkage = child_results->NextAs<bool>();
|
auto name = child_results->NextAs<std::string>();
|
auto generic_parameters = child_results->NextAs<GenericParameters>();
|
auto args = child_results->NextAs<ParameterList>();
|
auto return_type = child_results->NextAs<TypeExpression*>();
|
BuiltinDeclaration* builtin =
|
MakeNode<ExternalBuiltinDeclaration>(js_linkage, name, args, return_type);
|
Declaration* result;
|
if (generic_parameters.empty()) {
|
result = MakeNode<StandardDeclaration>(builtin, nullptr);
|
} else {
|
result = MakeNode<GenericDeclaration>(builtin, generic_parameters);
|
}
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeExternalRuntime(
|
ParseResultIterator* child_results) {
|
auto name = child_results->NextAs<std::string>();
|
auto args = child_results->NextAs<ParameterList>();
|
auto return_type = child_results->NextAs<TypeExpression*>();
|
ExternalRuntimeDeclaration* runtime =
|
MakeNode<ExternalRuntimeDeclaration>(name, args, return_type);
|
Declaration* result = MakeNode<StandardDeclaration>(runtime, nullptr);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> StringLiteralUnquoteAction(
|
ParseResultIterator* child_results) {
|
return ParseResult{
|
StringLiteralUnquote(child_results->NextAs<std::string>())};
|
}
|
|
base::Optional<ParseResult> MakeBasicTypeExpression(
|
ParseResultIterator* child_results) {
|
auto is_constexpr = child_results->NextAs<bool>();
|
auto name = child_results->NextAs<std::string>();
|
TypeExpression* result =
|
MakeNode<BasicTypeExpression>(is_constexpr, std::move(name));
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeFunctionTypeExpression(
|
ParseResultIterator* child_results) {
|
auto parameters = child_results->NextAs<std::vector<TypeExpression*>>();
|
auto return_type = child_results->NextAs<TypeExpression*>();
|
TypeExpression* result =
|
MakeNode<FunctionTypeExpression>(std::move(parameters), return_type);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeUnionTypeExpression(
|
ParseResultIterator* child_results) {
|
auto a = child_results->NextAs<TypeExpression*>();
|
auto b = child_results->NextAs<TypeExpression*>();
|
TypeExpression* result = MakeNode<UnionTypeExpression>(a, b);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeExpressionStatement(
|
ParseResultIterator* child_results) {
|
auto expression = child_results->NextAs<Expression*>();
|
Statement* result = MakeNode<ExpressionStatement>(expression);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeIfStatement(
|
ParseResultIterator* child_results) {
|
auto is_constexpr = child_results->NextAs<bool>();
|
auto condition = child_results->NextAs<Expression*>();
|
auto if_true = child_results->NextAs<Statement*>();
|
auto if_false = child_results->NextAs<base::Optional<Statement*>>();
|
|
if (if_false && !(BlockStatement::DynamicCast(if_true) &&
|
(BlockStatement::DynamicCast(*if_false) ||
|
IfStatement::DynamicCast(*if_false)))) {
|
ReportError("if-else statements require curly braces");
|
}
|
|
Statement* result =
|
MakeNode<IfStatement>(is_constexpr, condition, if_true, if_false);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeTypeswitchStatement(
|
ParseResultIterator* child_results) {
|
auto expression = child_results->NextAs<Expression*>();
|
auto cases = child_results->NextAs<std::vector<TypeswitchCase>>();
|
CurrentSourcePosition::Scope current_source_position(
|
child_results->matched_input().pos);
|
|
// typeswitch (expression) case (x1 : T1) {
|
// ...b1
|
// } case (x2 : T2) {
|
// ...b2
|
// } case (x3 : T3) {
|
// ...b3
|
// }
|
//
|
// desugars to
|
//
|
// {
|
// const _value = expression;
|
// try {
|
// const x1 : T1 = cast<T1>(_value) otherwise _NextCase;
|
// ...b1
|
// } label _NextCase {
|
// try {
|
// const x2 : T2 = cast<T2>(%assume_impossible<T1>(_value));
|
// ...b2
|
// } label _NextCase {
|
// const x3 : T3 = %assume_impossible<T1|T2>(_value);
|
// ...b3
|
// }
|
// }
|
// }
|
|
BlockStatement* current_block = MakeNode<BlockStatement>();
|
Statement* result = current_block;
|
{
|
CurrentSourcePosition::Scope current_source_position(expression->pos);
|
current_block->statements.push_back(MakeNode<VarDeclarationStatement>(
|
true, "_value", base::nullopt, expression));
|
}
|
|
TypeExpression* accumulated_types;
|
for (size_t i = 0; i < cases.size(); ++i) {
|
CurrentSourcePosition::Scope current_source_position(cases[i].pos);
|
Expression* value = MakeNode<IdentifierExpression>("_value");
|
if (i >= 1) {
|
value =
|
MakeNode<AssumeTypeImpossibleExpression>(accumulated_types, value);
|
}
|
BlockStatement* case_block;
|
if (i < cases.size() - 1) {
|
value = MakeNode<CallExpression>(
|
"cast", false, std::vector<TypeExpression*>{cases[i].type},
|
std::vector<Expression*>{value},
|
std::vector<std::string>{"_NextCase"});
|
case_block = MakeNode<BlockStatement>();
|
} else {
|
case_block = current_block;
|
}
|
std::string name = "_case_value";
|
if (cases[i].name) name = *cases[i].name;
|
case_block->statements.push_back(
|
MakeNode<VarDeclarationStatement>(true, name, cases[i].type, value));
|
case_block->statements.push_back(cases[i].block);
|
if (i < cases.size() - 1) {
|
BlockStatement* next_block = MakeNode<BlockStatement>();
|
current_block->statements.push_back(MakeNode<TryLabelStatement>(
|
case_block, std::vector<LabelBlock*>{MakeNode<LabelBlock>(
|
"_NextCase", ParameterList::Empty(), next_block)}));
|
current_block = next_block;
|
}
|
accumulated_types =
|
i > 0 ? MakeNode<UnionTypeExpression>(accumulated_types, cases[i].type)
|
: cases[i].type;
|
}
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeTypeswitchCase(
|
ParseResultIterator* child_results) {
|
auto name = child_results->NextAs<base::Optional<std::string>>();
|
auto type = child_results->NextAs<TypeExpression*>();
|
auto block = child_results->NextAs<Statement*>();
|
return ParseResult{TypeswitchCase{child_results->matched_input().pos,
|
std::move(name), type, block}};
|
}
|
|
base::Optional<ParseResult> MakeWhileStatement(
|
ParseResultIterator* child_results) {
|
auto condition = child_results->NextAs<Expression*>();
|
auto body = child_results->NextAs<Statement*>();
|
Statement* result = MakeNode<WhileStatement>(condition, body);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeReturnStatement(
|
ParseResultIterator* child_results) {
|
auto value = child_results->NextAs<base::Optional<Expression*>>();
|
Statement* result = MakeNode<ReturnStatement>(value);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeTailCallStatement(
|
ParseResultIterator* child_results) {
|
auto value = child_results->NextAs<Expression*>();
|
Statement* result = MakeNode<TailCallStatement>(CallExpression::cast(value));
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeVarDeclarationStatement(
|
ParseResultIterator* child_results) {
|
auto kind = child_results->NextAs<std::string>();
|
bool const_qualified = kind == "const";
|
if (!const_qualified) DCHECK_EQ("let", kind);
|
auto name = child_results->NextAs<std::string>();
|
auto type = child_results->NextAs<TypeExpression*>();
|
base::Optional<Expression*> initializer;
|
if (child_results->HasNext())
|
initializer = child_results->NextAs<Expression*>();
|
Statement* result = MakeNode<VarDeclarationStatement>(
|
const_qualified, std::move(name), type, initializer);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeBreakStatement(
|
ParseResultIterator* child_results) {
|
Statement* result = MakeNode<BreakStatement>();
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeContinueStatement(
|
ParseResultIterator* child_results) {
|
Statement* result = MakeNode<ContinueStatement>();
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeGotoStatement(
|
ParseResultIterator* child_results) {
|
auto label = child_results->NextAs<std::string>();
|
auto arguments = child_results->NextAs<std::vector<Expression*>>();
|
Statement* result =
|
MakeNode<GotoStatement>(std::move(label), std::move(arguments));
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeBlockStatement(
|
ParseResultIterator* child_results) {
|
auto deferred = child_results->NextAs<bool>();
|
auto statements = child_results->NextAs<std::vector<Statement*>>();
|
Statement* result = MakeNode<BlockStatement>(deferred, std::move(statements));
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeTryLabelStatement(
|
ParseResultIterator* child_results) {
|
auto try_block = child_results->NextAs<Statement*>();
|
auto label_blocks = child_results->NextAs<std::vector<LabelBlock*>>();
|
Statement* result =
|
MakeNode<TryLabelStatement>(try_block, std::move(label_blocks));
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeForOfLoopStatement(
|
ParseResultIterator* child_results) {
|
auto var_decl = child_results->NextAs<Statement*>();
|
auto iterable = child_results->NextAs<Expression*>();
|
auto range = child_results->NextAs<base::Optional<RangeExpression>>();
|
auto body = child_results->NextAs<Statement*>();
|
Statement* result =
|
MakeNode<ForOfLoopStatement>(var_decl, iterable, range, body);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeForLoopStatement(
|
ParseResultIterator* child_results) {
|
auto var_decl = child_results->NextAs<base::Optional<Statement*>>();
|
auto test = child_results->NextAs<base::Optional<Expression*>>();
|
auto action = child_results->NextAs<base::Optional<Expression*>>();
|
auto body = child_results->NextAs<Statement*>();
|
Statement* result = MakeNode<ForLoopStatement>(var_decl, test, action, body);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeLabelBlock(ParseResultIterator* child_results) {
|
auto label = child_results->NextAs<std::string>();
|
auto parameters = child_results->NextAs<ParameterList>();
|
auto body = child_results->NextAs<Statement*>();
|
LabelBlock* result =
|
MakeNode<LabelBlock>(std::move(label), std::move(parameters), body);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeRangeExpression(
|
ParseResultIterator* child_results) {
|
auto begin = child_results->NextAs<base::Optional<Expression*>>();
|
auto end = child_results->NextAs<base::Optional<Expression*>>();
|
RangeExpression result = {begin, end};
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeExpressionWithSource(
|
ParseResultIterator* child_results) {
|
auto e = child_results->NextAs<Expression*>();
|
return ParseResult{
|
ExpressionWithSource{e, child_results->matched_input().ToString()}};
|
}
|
|
base::Optional<ParseResult> MakeIdentifierExpression(
|
ParseResultIterator* child_results) {
|
auto name = child_results->NextAs<std::string>();
|
auto generic_arguments =
|
child_results->NextAs<std::vector<TypeExpression*>>();
|
LocationExpression* result = MakeNode<IdentifierExpression>(
|
std::move(name), std::move(generic_arguments));
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeFieldAccessExpression(
|
ParseResultIterator* child_results) {
|
auto object = child_results->NextAs<Expression*>();
|
auto field = child_results->NextAs<std::string>();
|
LocationExpression* result =
|
MakeNode<FieldAccessExpression>(object, std::move(field));
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeElementAccessExpression(
|
ParseResultIterator* child_results) {
|
auto object = child_results->NextAs<Expression*>();
|
auto field = child_results->NextAs<Expression*>();
|
LocationExpression* result = MakeNode<ElementAccessExpression>(object, field);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeStructExpression(
|
ParseResultIterator* child_results) {
|
auto name = child_results->NextAs<std::string>();
|
auto expressions = child_results->NextAs<std::vector<Expression*>>();
|
Expression* result =
|
MakeNode<StructExpression>(std::move(name), std::move(expressions));
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeAssignmentExpression(
|
ParseResultIterator* child_results) {
|
auto location = child_results->NextAs<LocationExpression*>();
|
auto op = child_results->NextAs<base::Optional<std::string>>();
|
auto value = child_results->NextAs<Expression*>();
|
Expression* result =
|
MakeNode<AssignmentExpression>(location, std::move(op), value);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeNumberLiteralExpression(
|
ParseResultIterator* child_results) {
|
auto number = child_results->NextAs<std::string>();
|
Expression* result = MakeNode<NumberLiteralExpression>(std::move(number));
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeStringLiteralExpression(
|
ParseResultIterator* child_results) {
|
auto literal = child_results->NextAs<std::string>();
|
Expression* result = MakeNode<StringLiteralExpression>(std::move(literal));
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeIncrementDecrementExpressionPostfix(
|
ParseResultIterator* child_results) {
|
auto location = child_results->NextAs<LocationExpression*>();
|
auto op = child_results->NextAs<IncrementDecrementOperator>();
|
Expression* result =
|
MakeNode<IncrementDecrementExpression>(location, op, true);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeIncrementDecrementExpressionPrefix(
|
ParseResultIterator* child_results) {
|
auto op = child_results->NextAs<IncrementDecrementOperator>();
|
auto location = child_results->NextAs<LocationExpression*>();
|
Expression* result =
|
MakeNode<IncrementDecrementExpression>(location, op, false);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeLogicalOrExpression(
|
ParseResultIterator* child_results) {
|
auto left = child_results->NextAs<Expression*>();
|
auto right = child_results->NextAs<Expression*>();
|
Expression* result = MakeNode<LogicalOrExpression>(left, right);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeLogicalAndExpression(
|
ParseResultIterator* child_results) {
|
auto left = child_results->NextAs<Expression*>();
|
auto right = child_results->NextAs<Expression*>();
|
Expression* result = MakeNode<LogicalAndExpression>(left, right);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeConditionalExpression(
|
ParseResultIterator* child_results) {
|
auto condition = child_results->NextAs<Expression*>();
|
auto if_true = child_results->NextAs<Expression*>();
|
auto if_false = child_results->NextAs<Expression*>();
|
Expression* result =
|
MakeNode<ConditionalExpression>(condition, if_true, if_false);
|
return ParseResult{result};
|
}
|
|
base::Optional<ParseResult> MakeLabelAndTypes(
|
ParseResultIterator* child_results) {
|
auto name = child_results->NextAs<std::string>();
|
auto types = child_results->NextAs<std::vector<TypeExpression*>>();
|
return ParseResult{LabelAndTypes{std::move(name), std::move(types)}};
|
}
|
|
base::Optional<ParseResult> MakeNameAndType(
|
ParseResultIterator* child_results) {
|
auto name = child_results->NextAs<std::string>();
|
auto type = child_results->NextAs<TypeExpression*>();
|
return ParseResult{NameAndTypeExpression{std::move(name), type}};
|
}
|
|
base::Optional<ParseResult> ExtractAssignmentOperator(
|
ParseResultIterator* child_results) {
|
auto op = child_results->NextAs<std::string>();
|
base::Optional<std::string> result = std::string(op.begin(), op.end() - 1);
|
return ParseResult(std::move(result));
|
}
|
|
struct TorqueGrammar : Grammar {
|
static bool MatchWhitespace(InputPosition* pos) {
|
while (true) {
|
if (MatchChar(std::isspace, pos)) continue;
|
if (MatchString("//", pos)) {
|
while (MatchChar([](char c) { return c != '\n'; }, pos)) {
|
}
|
continue;
|
}
|
return true;
|
}
|
}
|
|
static bool MatchIdentifier(InputPosition* pos) {
|
if (!MatchChar(std::isalpha, pos)) return false;
|
while (MatchChar(std::isalnum, pos) || MatchString("_", pos)) {
|
}
|
return true;
|
}
|
|
static bool MatchStringLiteral(InputPosition* pos) {
|
InputPosition current = *pos;
|
if (MatchString("\"", ¤t)) {
|
while (
|
(MatchString("\\", ¤t) && MatchAnyChar(¤t)) ||
|
MatchChar([](char c) { return c != '"' && c != '\n'; }, ¤t)) {
|
}
|
if (MatchString("\"", ¤t)) {
|
*pos = current;
|
return true;
|
}
|
}
|
current = *pos;
|
if (MatchString("'", ¤t)) {
|
while (
|
(MatchString("\\", ¤t) && MatchAnyChar(¤t)) ||
|
MatchChar([](char c) { return c != '\'' && c != '\n'; }, ¤t)) {
|
}
|
if (MatchString("'", ¤t)) {
|
*pos = current;
|
return true;
|
}
|
}
|
return false;
|
}
|
|
static bool MatchHexLiteral(InputPosition* pos) {
|
InputPosition current = *pos;
|
MatchString("-", ¤t);
|
if (MatchString("0x", ¤t) && MatchChar(std::isxdigit, ¤t)) {
|
while (MatchChar(std::isxdigit, ¤t)) {
|
}
|
*pos = current;
|
return true;
|
}
|
return false;
|
}
|
|
static bool MatchDecimalLiteral(InputPosition* pos) {
|
InputPosition current = *pos;
|
bool found_digit = false;
|
MatchString("-", ¤t);
|
while (MatchChar(std::isdigit, ¤t)) found_digit = true;
|
MatchString(".", ¤t);
|
while (MatchChar(std::isdigit, ¤t)) found_digit = true;
|
if (!found_digit) return false;
|
*pos = current;
|
if ((MatchString("e", ¤t) || MatchString("E", ¤t)) &&
|
(MatchString("+", ¤t) || MatchString("-", ¤t) || true) &&
|
MatchChar(std::isdigit, ¤t)) {
|
while (MatchChar(std::isdigit, ¤t)) {
|
}
|
*pos = current;
|
return true;
|
}
|
return true;
|
}
|
|
TorqueGrammar() : Grammar(&file) { SetWhitespace(MatchWhitespace); }
|
|
// Result: std::string
|
Symbol identifier = {Rule({Pattern(MatchIdentifier)}, YieldMatchedInput)};
|
|
// Result: std::string
|
Symbol stringLiteral = {
|
Rule({Pattern(MatchStringLiteral)}, YieldMatchedInput)};
|
|
// Result: std::string
|
Symbol externalString = {Rule({&stringLiteral}, StringLiteralUnquoteAction)};
|
|
// Result: std::string
|
Symbol decimalLiteral = {
|
Rule({Pattern(MatchDecimalLiteral)}, YieldMatchedInput),
|
Rule({Pattern(MatchHexLiteral)}, YieldMatchedInput)};
|
|
// Result: TypeList
|
Symbol* typeList = List<TypeExpression*>(&type, Token(","));
|
|
// Result: TypeExpression*
|
Symbol simpleType = {
|
Rule({Token("("), &type, Token(")")}),
|
Rule({CheckIf(Token("constexpr")), &identifier}, MakeBasicTypeExpression),
|
Rule({Token("builtin"), Token("("), typeList, Token(")"), Token("=>"),
|
&simpleType},
|
MakeFunctionTypeExpression)};
|
|
// Result: TypeExpression*
|
Symbol type = {Rule({&simpleType}), Rule({&type, Token("|"), &simpleType},
|
MakeUnionTypeExpression)};
|
|
// Result: GenericParameters
|
Symbol genericParameters = {
|
Rule({Token("<"),
|
List<std::string>(
|
Sequence({&identifier, Token(":"), Token("type")}), Token(",")),
|
Token(">")})};
|
|
// Result: TypeList
|
Symbol genericSpecializationTypeList = {
|
Rule({Token("<"), typeList, Token(">")})};
|
|
// Result: base::Optional<TypeList>
|
Symbol* optionalGenericParameters = Optional<TypeList>(&genericParameters);
|
|
// Result: ParameterList
|
Symbol typeListMaybeVarArgs = {
|
Rule({Token("("), List<TypeExpression*>(Sequence({&type, Token(",")})),
|
Token("..."), Token(")")},
|
MakeParameterListFromTypes<true>),
|
Rule({Token("("), typeList, Token(")")},
|
MakeParameterListFromTypes<false>)};
|
|
// Result: LabelAndTypes
|
Symbol labelParameter = {Rule(
|
{&identifier,
|
TryOrDefault<TypeList>(Sequence({Token("("), typeList, Token(")")}))},
|
MakeLabelAndTypes)};
|
|
// Result: TypeExpression*
|
Symbol optionalReturnType = {Rule({Token(":"), &type}),
|
Rule({}, MakeVoidType)};
|
|
// Result: LabelAndTypesVector
|
Symbol* optionalLabelList{TryOrDefault<LabelAndTypesVector>(
|
Sequence({Token("labels"),
|
NonemptyList<LabelAndTypes>(&labelParameter, Token(","))}))};
|
|
// Result: std::vector<std::string>
|
Symbol* optionalOtherwise{TryOrDefault<std::vector<std::string>>(
|
Sequence({Token("otherwise"),
|
NonemptyList<std::string>(&identifier, Token(","))}))};
|
|
// Result: NameAndTypeExpression
|
Symbol nameAndType = {
|
Rule({&identifier, Token(":"), &type}, MakeNameAndType)};
|
|
// Result: ParameterList
|
Symbol parameterListNoVararg = {
|
Rule({Token("("), List<NameAndTypeExpression>(&nameAndType, Token(",")),
|
Token(")")},
|
MakeParameterListFromNameAndTypeList<false>)};
|
|
// Result: ParameterList
|
Symbol parameterListAllowVararg = {
|
Rule({¶meterListNoVararg}),
|
Rule({Token("("),
|
NonemptyList<NameAndTypeExpression>(&nameAndType, Token(",")),
|
Token(","), Token("..."), &identifier, Token(")")},
|
MakeParameterListFromNameAndTypeList<true>)};
|
|
// Result: std::string
|
Symbol* OneOf(std::vector<std::string> alternatives) {
|
Symbol* result = NewSymbol();
|
for (const std::string& s : alternatives) {
|
result->AddRule(Rule({Token(s)}, YieldMatchedInput));
|
}
|
return result;
|
}
|
|
// Result: Expression*
|
Symbol* BinaryOperator(Symbol* nextLevel, Symbol* op) {
|
Symbol* result = NewSymbol();
|
*result = {Rule({nextLevel}),
|
Rule({result, op, nextLevel}, MakeBinaryOperator)};
|
return result;
|
}
|
|
// Result: Expression*
|
Symbol* expression = &assignmentExpression;
|
|
// Result: IncrementDecrementOperator
|
Symbol incrementDecrementOperator = {
|
Rule({Token("++")},
|
YieldIntegralConstant<IncrementDecrementOperator,
|
IncrementDecrementOperator::kIncrement>),
|
Rule({Token("--")},
|
YieldIntegralConstant<IncrementDecrementOperator,
|
IncrementDecrementOperator::kDecrement>)};
|
|
// Result: LocationExpression*
|
Symbol locationExpression = {
|
Rule(
|
{&identifier, TryOrDefault<TypeList>(&genericSpecializationTypeList)},
|
MakeIdentifierExpression),
|
Rule({&primaryExpression, Token("."), &identifier},
|
MakeFieldAccessExpression),
|
Rule({&primaryExpression, Token("["), expression, Token("]")},
|
MakeElementAccessExpression)};
|
|
// Result: std::vector<Expression*>
|
Symbol argumentList = {Rule(
|
{Token("("), List<Expression*>(expression, Token(",")), Token(")")})};
|
|
// Result: Expression*
|
Symbol callExpression = {
|
Rule({&identifier, TryOrDefault<TypeList>(&genericSpecializationTypeList),
|
&argumentList, optionalOtherwise},
|
MakeCall)};
|
|
// Result: Expression*
|
Symbol primaryExpression = {
|
Rule({&callExpression}),
|
Rule({&locationExpression},
|
CastParseResult<LocationExpression*, Expression*>),
|
Rule({&decimalLiteral}, MakeNumberLiteralExpression),
|
Rule({&stringLiteral}, MakeStringLiteralExpression),
|
Rule({&identifier, Token("{"), List<Expression*>(expression, Token(",")),
|
Token("}")},
|
MakeStructExpression),
|
Rule({Token("("), expression, Token(")")})};
|
|
// Result: Expression*
|
Symbol unaryExpression = {
|
Rule({&primaryExpression}),
|
Rule({OneOf({"+", "-", "!", "~"}), &unaryExpression}, MakeUnaryOperator),
|
Rule({&incrementDecrementOperator, &locationExpression},
|
MakeIncrementDecrementExpressionPrefix),
|
Rule({&locationExpression, &incrementDecrementOperator},
|
MakeIncrementDecrementExpressionPostfix)};
|
|
// Result: Expression*
|
Symbol* multiplicativeExpression =
|
BinaryOperator(&unaryExpression, OneOf({"*", "/", "%"}));
|
|
// Result: Expression*
|
Symbol* additiveExpression =
|
BinaryOperator(multiplicativeExpression, OneOf({"+", "-"}));
|
|
// Result: Expression*
|
Symbol* shiftExpression =
|
BinaryOperator(additiveExpression, OneOf({"<<", ">>", ">>>"}));
|
|
// Do not allow expressions like a < b > c because this is never
|
// useful and ambiguous with template parameters.
|
// Result: Expression*
|
Symbol relationalExpression = {
|
Rule({shiftExpression}),
|
Rule({shiftExpression, OneOf({"<", ">", "<=", ">="}), shiftExpression},
|
MakeBinaryOperator)};
|
|
// Result: Expression*
|
Symbol* equalityExpression =
|
BinaryOperator(&relationalExpression, OneOf({"==", "!="}));
|
|
// Result: Expression*
|
Symbol* bitwiseExpression =
|
BinaryOperator(equalityExpression, OneOf({"&", "|"}));
|
|
// Result: Expression*
|
Symbol logicalAndExpression = {
|
Rule({bitwiseExpression}),
|
Rule({&logicalAndExpression, Token("&&"), bitwiseExpression},
|
MakeLogicalAndExpression)};
|
|
// Result: Expression*
|
Symbol logicalOrExpression = {
|
Rule({&logicalAndExpression}),
|
Rule({&logicalOrExpression, Token("||"), &logicalAndExpression},
|
MakeLogicalOrExpression)};
|
|
// Result: Expression*
|
Symbol conditionalExpression = {
|
Rule({&logicalOrExpression}),
|
Rule({&logicalOrExpression, Token("?"), expression, Token(":"),
|
&conditionalExpression},
|
MakeConditionalExpression)};
|
|
// Result: base::Optional<std::string>
|
Symbol assignmentOperator = {
|
Rule({Token("=")}, YieldDefaultValue<base::Optional<std::string>>),
|
Rule({OneOf({"*=", "/=", "%=", "+=", "-=", "<<=", ">>=", ">>>=", "&=",
|
"^=", "|="})},
|
ExtractAssignmentOperator)};
|
|
// Result: Expression*
|
Symbol assignmentExpression = {
|
Rule({&conditionalExpression}),
|
Rule({&locationExpression, &assignmentOperator, &assignmentExpression},
|
MakeAssignmentExpression)};
|
|
// Result: Statement*
|
Symbol block = {Rule({CheckIf(Token("deferred")), Token("{"),
|
List<Statement*>(&statement), Token("}")},
|
MakeBlockStatement)};
|
|
// Result: LabelBlock*
|
Symbol labelBlock = {
|
Rule({Token("label"), &identifier,
|
TryOrDefault<ParameterList>(¶meterListNoVararg), &block},
|
MakeLabelBlock)};
|
|
// Result: ExpressionWithSource
|
Symbol expressionWithSource = {Rule({expression}, MakeExpressionWithSource)};
|
|
// Result: RangeExpression
|
Symbol rangeSpecifier = {
|
Rule({Token("["), Optional<Expression*>(expression), Token(":"),
|
Optional<Expression*>(expression), Token("]")},
|
MakeRangeExpression)};
|
|
// Result: Statement*
|
Symbol varDeclaration = {
|
Rule({OneOf({"let", "const"}), &identifier, Token(":"), &type},
|
MakeVarDeclarationStatement)};
|
|
// Result: Statement*
|
Symbol varDeclarationWithInitialization = {
|
Rule({OneOf({"let", "const"}), &identifier, Token(":"), &type, Token("="),
|
expression},
|
MakeVarDeclarationStatement)};
|
|
// Disallow ambiguous dangling else by only allowing an {atomarStatement} as
|
// a then-clause. Result: Statement*
|
Symbol atomarStatement = {
|
Rule({&block}),
|
Rule({expression, Token(";")}, MakeExpressionStatement),
|
Rule({Token("return"), Optional<Expression*>(expression), Token(";")},
|
MakeReturnStatement),
|
Rule({Token("tail"), &callExpression, Token(";")}, MakeTailCallStatement),
|
Rule({Token("break"), Token(";")}, MakeBreakStatement),
|
Rule({Token("continue"), Token(";")}, MakeContinueStatement),
|
Rule({Token("goto"), &identifier,
|
TryOrDefault<std::vector<Expression*>>(&argumentList), Token(";")},
|
MakeGotoStatement),
|
Rule({OneOf({"debug", "unreachable"}), Token(";")}, MakeDebugStatement)};
|
|
// Result: Statement*
|
Symbol statement = {
|
Rule({&atomarStatement}),
|
Rule({&varDeclaration, Token(";")}),
|
Rule({&varDeclarationWithInitialization, Token(";")}),
|
Rule({Token("if"), CheckIf(Token("constexpr")), Token("("), expression,
|
Token(")"), &atomarStatement,
|
Optional<Statement*>(Sequence({Token("else"), &statement}))},
|
MakeIfStatement),
|
Rule(
|
{
|
Token("typeswitch"), Token("("), expression, Token(")"),
|
Token("{"), NonemptyList<TypeswitchCase>(&typeswitchCase),
|
Token("}"),
|
},
|
MakeTypeswitchStatement),
|
Rule({Token("try"), &block, NonemptyList<LabelBlock*>(&labelBlock)},
|
MakeTryLabelStatement),
|
Rule({OneOf({"assert", "check"}), Token("("), &expressionWithSource,
|
Token(")"), Token(";")},
|
MakeAssertStatement),
|
Rule({Token("while"), Token("("), expression, Token(")"),
|
&atomarStatement},
|
MakeWhileStatement),
|
Rule({Token("for"), Token("("), &varDeclaration, Token("of"), expression,
|
Optional<RangeExpression>(&rangeSpecifier), Token(")"),
|
&atomarStatement},
|
MakeForOfLoopStatement),
|
Rule({Token("for"), Token("("),
|
Optional<Statement*>(&varDeclarationWithInitialization), Token(";"),
|
Optional<Expression*>(expression), Token(";"),
|
Optional<Expression*>(expression), Token(")"), &atomarStatement},
|
MakeForLoopStatement)};
|
|
// Result: TypeswitchCase
|
Symbol typeswitchCase = {
|
Rule({Token("case"), Token("("),
|
Optional<std::string>(Sequence({&identifier, Token(":")})), &type,
|
Token(")"), &block},
|
MakeTypeswitchCase)};
|
|
// Result: base::Optional<Statement*>
|
Symbol optionalBody = {
|
Rule({&block}, CastParseResult<Statement*, base::Optional<Statement*>>),
|
Rule({Token(";")}, YieldDefaultValue<base::Optional<Statement*>>)};
|
|
// Result: Declaration*
|
Symbol declaration = {
|
Rule({Token("const"), &identifier, Token(":"), &type, Token("="),
|
expression, Token(";")},
|
MakeConstDeclaration),
|
Rule({Token("const"), &identifier, Token(":"), &type, Token("generates"),
|
&externalString, Token(";")},
|
MakeExternConstDeclaration),
|
Rule({Token("type"), &identifier,
|
Optional<std::string>(Sequence({Token("extends"), &identifier})),
|
Optional<std::string>(
|
Sequence({Token("generates"), &externalString})),
|
Optional<std::string>(
|
Sequence({Token("constexpr"), &externalString})),
|
Token(";")},
|
MakeTypeDeclaration),
|
Rule({Token("type"), &identifier, Token("="), &type, Token(";")},
|
MakeTypeAliasDeclaration),
|
Rule({Token("extern"),
|
Optional<std::string>(
|
Sequence({Token("operator"), &externalString})),
|
Token("macro"), &identifier,
|
TryOrDefault<GenericParameters>(&genericParameters),
|
&typeListMaybeVarArgs, &optionalReturnType, optionalLabelList,
|
Token(";")},
|
MakeExternalMacro),
|
Rule({Token("extern"), CheckIf(Token("javascript")), Token("builtin"),
|
&identifier, TryOrDefault<GenericParameters>(&genericParameters),
|
&typeListMaybeVarArgs, &optionalReturnType, Token(";")},
|
MakeExternalBuiltin),
|
Rule({Token("extern"), Token("runtime"), &identifier,
|
&typeListMaybeVarArgs, &optionalReturnType, Token(";")},
|
MakeExternalRuntime),
|
Rule({Optional<std::string>(
|
Sequence({Token("operator"), &externalString})),
|
Token("macro"), &identifier,
|
TryOrDefault<GenericParameters>(&genericParameters),
|
¶meterListNoVararg, &optionalReturnType, optionalLabelList,
|
&optionalBody},
|
MakeTorqueMacroDeclaration),
|
Rule({CheckIf(Token("javascript")), Token("builtin"), &identifier,
|
TryOrDefault<GenericParameters>(&genericParameters),
|
¶meterListAllowVararg, &optionalReturnType, &optionalBody},
|
MakeTorqueBuiltinDeclaration),
|
Rule({&identifier, &genericSpecializationTypeList,
|
¶meterListAllowVararg, &optionalReturnType, optionalLabelList,
|
&block},
|
MakeSpecializationDeclaration),
|
Rule({Token("struct"), &identifier, Token("{"),
|
List<NameAndTypeExpression>(Sequence({&nameAndType, Token(";")})),
|
Token("}")},
|
MakeStructDeclaration)};
|
|
// Result: Declaration*
|
Symbol moduleDeclaration = {
|
Rule({Token("module"), &identifier, Token("{"),
|
List<Declaration*>(&declaration), Token("}")},
|
MakeExplicitModuleDeclaration)};
|
|
Symbol file = {Rule({&file, &moduleDeclaration}, AddGlobalDeclaration),
|
Rule({&file, &declaration}, AddGlobalDeclaration), Rule({})};
|
};
|
|
} // namespace
|
|
void ParseTorque(const std::string& input) { TorqueGrammar().Parse(input); }
|
|
} // namespace torque
|
} // namespace internal
|
} // namespace v8
|