wsgl parser: Prefix methods with `expect_`

... for those that will internally error if the grammar does not match,
otherwise will always return a valid AST object.

This helps identify whether the caller is expected to error or not.

Bug: tint:282
Change-Id: Ied94f717526a63033f2e6c9e94fca43dbf0b8f05
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/32001
Commit-Queue: Ben Clayton <bclayton@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
Ben Clayton 2020-11-09 15:49:33 +00:00 committed by Commit Bot service account
parent 8655b62207
commit 7b750dc733
10 changed files with 189 additions and 174 deletions

View File

@ -188,7 +188,7 @@ bool ParserImpl::Parse() {
// : global_decl* EOF
void ParserImpl::translation_unit() {
for (;;) {
global_decl();
expect_global_decl();
if (has_error())
return;
@ -206,7 +206,7 @@ void ParserImpl::translation_unit() {
// | type_alias SEMICOLON
// | struct_decl SEMICOLON
// | function_decl
void ParserImpl::global_decl() {
void ParserImpl::expect_global_decl() {
auto t = peek();
if (t.IsEof()) {
return;
@ -303,7 +303,7 @@ std::unique_ptr<ast::Variable> ParserImpl::global_variable_decl(
}
if (match(Token::Type::kEqual)) {
auto expr = const_expr();
auto expr = expect_const_expr();
if (has_error())
return nullptr;
if (expr == nullptr) {
@ -340,7 +340,7 @@ std::unique_ptr<ast::Variable> ParserImpl::global_constant_decl() {
return nullptr;
}
auto init = const_expr();
auto init = expect_const_expr();
if (has_error())
return nullptr;
if (init == nullptr) {
@ -896,10 +896,10 @@ ast::type::Type* ParserImpl::type_decl() {
return ctx_.type_mgr().Get(std::make_unique<ast::type::U32Type>());
}
if (t.IsVec2() || t.IsVec3() || t.IsVec4()) {
return type_decl_vector(t);
return expect_type_decl_vector(t);
}
if (t.IsPtr()) {
return type_decl_pointer(t);
return expect_type_decl_pointer(t);
}
auto decos = decoration_list();
@ -909,7 +909,7 @@ ast::type::Type* ParserImpl::type_decl() {
if (match(Token::Type::kArray)) {
auto array_decos = cast_decorations<ast::ArrayDecoration>(decos);
return type_decl_array(std::move(array_decos));
return expect_type_decl_array(std::move(array_decos));
}
expect_decorations_consumed(decos);
@ -917,7 +917,7 @@ ast::type::Type* ParserImpl::type_decl() {
if (t.IsMat2x2() || t.IsMat2x3() || t.IsMat2x4() || t.IsMat3x2() ||
t.IsMat3x3() || t.IsMat3x4() || t.IsMat4x2() || t.IsMat4x3() ||
t.IsMat4x4()) {
return type_decl_matrix(t);
return expect_type_decl_matrix(t);
}
auto* texture_or_sampler = texture_sampler_types();
@ -931,7 +931,7 @@ ast::type::Type* ParserImpl::type_decl() {
return nullptr;
}
ast::type::Type* ParserImpl::type_decl_pointer(Token t) {
ast::type::Type* ParserImpl::expect_type_decl_pointer(Token t) {
next(); // Consume the peek
t = next();
@ -972,7 +972,7 @@ ast::type::Type* ParserImpl::type_decl_pointer(Token t) {
std::make_unique<ast::type::PointerType>(subtype, sc));
}
ast::type::Type* ParserImpl::type_decl_vector(Token t) {
ast::type::Type* ParserImpl::expect_type_decl_vector(Token t) {
next(); // Consume the peek
uint32_t count = 2;
@ -1005,7 +1005,8 @@ ast::type::Type* ParserImpl::type_decl_vector(Token t) {
std::make_unique<ast::type::VectorType>(subtype, count));
}
ast::type::Type* ParserImpl::type_decl_array(ast::ArrayDecorationList decos) {
ast::type::Type* ParserImpl::expect_type_decl_array(
ast::ArrayDecorationList decos) {
const char* use = "array declaration";
if (!expect(use, Token::Type::kLessThan))
@ -1033,7 +1034,7 @@ ast::type::Type* ParserImpl::type_decl_array(ast::ArrayDecorationList decos) {
return ctx_.type_mgr().Get(std::move(ty));
}
ast::type::Type* ParserImpl::type_decl_matrix(Token t) {
ast::type::Type* ParserImpl::expect_type_decl_matrix(Token t) {
next(); // Consume the peek
uint32_t rows = 2;
@ -1140,7 +1141,7 @@ std::unique_ptr<ast::type::StructType> ParserImpl::struct_decl(
if (!expect_ident("struct declaration", &name))
return nullptr;
auto body = struct_body_decl();
auto body = expect_struct_body_decl();
if (has_error()) {
return nullptr;
}
@ -1152,14 +1153,14 @@ std::unique_ptr<ast::type::StructType> ParserImpl::struct_decl(
// struct_body_decl
// : BRACKET_LEFT struct_member* BRACKET_RIGHT
ast::StructMemberList ParserImpl::struct_body_decl() {
ast::StructMemberList ParserImpl::expect_struct_body_decl() {
return expect_brace_block("struct declaration", [&] {
ast::StructMemberList members;
while (!peek().IsBraceRight() && !peek().IsEof()) {
auto decos = decoration_list();
auto mem = struct_member(decos);
auto mem = expect_struct_member(decos);
if (has_error())
return ast::StructMemberList{};
if (mem == nullptr) {
@ -1176,7 +1177,7 @@ ast::StructMemberList ParserImpl::struct_body_decl() {
// struct_member
// : struct_member_decoration_decl+ variable_ident_decl SEMICOLON
std::unique_ptr<ast::StructMember> ParserImpl::struct_member(
std::unique_ptr<ast::StructMember> ParserImpl::expect_struct_member(
ast::DecorationList& decos) {
auto t = peek();
@ -1208,7 +1209,7 @@ std::unique_ptr<ast::Function> ParserImpl::function_decl(
auto func_decos = cast_decorations<ast::FunctionDecoration>(decos);
f->set_decorations(std::move(func_decos));
auto body = body_stmt();
auto body = expect_body_stmt();
if (has_error())
return nullptr;
@ -1241,7 +1242,7 @@ std::unique_ptr<ast::Function> ParserImpl::function_header() {
if (!expect_ident(use, &name))
return nullptr;
auto params = expect_paren_block(use, [&] { return param_list(); });
auto params = expect_paren_block(use, [&] { return expect_param_list(); });
if (has_error())
return nullptr;
@ -1266,7 +1267,7 @@ std::unique_ptr<ast::Function> ParserImpl::function_header() {
// param_list
// :
// | (variable_ident_decl COMMA)* variable_ident_decl
ast::VariableList ParserImpl::param_list() {
ast::VariableList ParserImpl::expect_param_list() {
auto t = peek();
ast::VariableList ret;
@ -1341,13 +1342,13 @@ std::pair<ast::Builtin, Source> ParserImpl::expect_builtin() {
// body_stmt
// : BRACKET_LEFT statements BRACKET_RIGHT
std::unique_ptr<ast::BlockStatement> ParserImpl::body_stmt() {
std::unique_ptr<ast::BlockStatement> ParserImpl::expect_body_stmt() {
return expect_brace_block("", [&] { return statements(); });
}
// paren_rhs_stmt
// : PAREN_LEFT logical_or_expression PAREN_RIGHT
std::unique_ptr<ast::Expression> ParserImpl::paren_rhs_stmt() {
std::unique_ptr<ast::Expression> ParserImpl::expect_paren_rhs_stmt() {
return expect_paren_block("", [&]() -> std::unique_ptr<ast::Expression> {
auto expr = logical_or_expression();
if (has_error())
@ -1495,7 +1496,7 @@ std::unique_ptr<ast::Statement> ParserImpl::statement() {
t = peek();
if (t.IsBraceLeft()) {
auto body = body_stmt();
auto body = expect_body_stmt();
if (has_error())
return nullptr;
if (body != nullptr)
@ -1589,7 +1590,7 @@ std::unique_ptr<ast::IfStatement> ParserImpl::if_stmt() {
if (!match(Token::Type::kIf, &source))
return nullptr;
auto condition = paren_rhs_stmt();
auto condition = expect_paren_rhs_stmt();
if (has_error())
return nullptr;
if (condition == nullptr) {
@ -1597,7 +1598,7 @@ std::unique_ptr<ast::IfStatement> ParserImpl::if_stmt() {
return nullptr;
}
auto body = body_stmt();
auto body = expect_body_stmt();
if (has_error())
return nullptr;
@ -1631,7 +1632,7 @@ ast::ElseStatementList ParserImpl::elseif_stmt() {
auto source = t.source();
next(); // Consume the peek
auto condition = paren_rhs_stmt();
auto condition = expect_paren_rhs_stmt();
if (has_error())
return {};
if (condition == nullptr) {
@ -1639,7 +1640,7 @@ ast::ElseStatementList ParserImpl::elseif_stmt() {
return {};
}
auto body = body_stmt();
auto body = expect_body_stmt();
if (has_error())
return {};
@ -1664,7 +1665,7 @@ std::unique_ptr<ast::ElseStatement> ParserImpl::else_stmt() {
auto source = t.source();
next(); // Consume the peek
auto body = body_stmt();
auto body = expect_body_stmt();
if (has_error())
return nullptr;
@ -1678,7 +1679,7 @@ std::unique_ptr<ast::SwitchStatement> ParserImpl::switch_stmt() {
if (!match(Token::Type::kSwitch, &source))
return nullptr;
auto condition = paren_rhs_stmt();
auto condition = expect_paren_rhs_stmt();
if (has_error())
return nullptr;
if (condition == nullptr) {
@ -1837,7 +1838,7 @@ ForHeader::~ForHeader() = default;
// SEMICOLON
// logical_or_expression? SEMICOLON
// (assignment_stmt | func_call_stmt)?
std::unique_ptr<ForHeader> ParserImpl::for_header() {
std::unique_ptr<ForHeader> ParserImpl::expect_for_header() {
std::unique_ptr<ast::Statement> initializer = nullptr;
if (initializer == nullptr) {
initializer = func_call_stmt();
@ -1894,7 +1895,8 @@ std::unique_ptr<ast::Statement> ParserImpl::for_stmt() {
if (!match(Token::Type::kFor, &source))
return nullptr;
auto header = expect_paren_block("for loop", [&] { return for_header(); });
auto header =
expect_paren_block("for loop", [&] { return expect_for_header(); });
if (header == nullptr)
return nullptr;
@ -1963,7 +1965,7 @@ std::unique_ptr<ast::CallStatement> ParserImpl::func_call_stmt() {
t = peek();
ast::ExpressionList params;
if (!t.IsParenRight() && !t.IsEof()) {
params = argument_expression_list();
params = expect_argument_expression_list();
if (has_error())
return nullptr;
}
@ -2003,7 +2005,7 @@ std::unique_ptr<ast::BlockStatement> ParserImpl::continuing_stmt() {
if (!match(Token::Type::kContinuing))
return std::make_unique<ast::BlockStatement>();
return body_stmt();
return expect_body_stmt();
}
// primary_expression
@ -2026,7 +2028,7 @@ std::unique_ptr<ast::Expression> ParserImpl::primary_expression() {
t = peek();
if (t.IsParenLeft()) {
auto paren = paren_rhs_stmt();
auto paren = expect_paren_rhs_stmt();
if (has_error())
return nullptr;
@ -2058,7 +2060,7 @@ std::unique_ptr<ast::Expression> ParserImpl::primary_expression() {
return nullptr;
}
auto params = paren_rhs_stmt();
auto params = expect_paren_rhs_stmt();
if (has_error())
return nullptr;
if (params == nullptr) {
@ -2083,7 +2085,7 @@ std::unique_ptr<ast::Expression> ParserImpl::primary_expression() {
auto ok = expect_paren_block("type constructor", [&] {
t = peek();
if (!t.IsParenRight() && !t.IsEof()) {
params = argument_expression_list();
params = expect_argument_expression_list();
if (has_error())
return false;
}
@ -2136,7 +2138,7 @@ std::unique_ptr<ast::Expression> ParserImpl::postfix_expr(
t = peek();
ast::ExpressionList params;
if (!t.IsParenRight() && !t.IsEof()) {
params = argument_expression_list();
params = expect_argument_expression_list();
if (has_error())
return nullptr;
}
@ -2176,7 +2178,7 @@ std::unique_ptr<ast::Expression> ParserImpl::postfix_expression() {
// argument_expression_list
// : (logical_or_expression COMMA)* logical_or_expression
ast::ExpressionList ParserImpl::argument_expression_list() {
ast::ExpressionList ParserImpl::expect_argument_expression_list() {
auto arg = logical_or_expression();
if (has_error())
return {};
@ -2242,7 +2244,7 @@ std::unique_ptr<ast::Expression> ParserImpl::unary_expression() {
// | STAR unary_expression multiplicative_expr
// | FORWARD_SLASH unary_expression multiplicative_expr
// | MODULO unary_expression multiplicative_expr
std::unique_ptr<ast::Expression> ParserImpl::multiplicative_expr(
std::unique_ptr<ast::Expression> ParserImpl::expect_multiplicative_expr(
std::unique_ptr<ast::Expression> lhs) {
auto t = peek();
@ -2267,7 +2269,7 @@ std::unique_ptr<ast::Expression> ParserImpl::multiplicative_expr(
add_error(peek(), "unable to parse right side of " + name + " expression");
return nullptr;
}
return multiplicative_expr(std::make_unique<ast::BinaryExpression>(
return expect_multiplicative_expr(std::make_unique<ast::BinaryExpression>(
source, op, std::move(lhs), std::move(rhs)));
}
@ -2280,14 +2282,14 @@ std::unique_ptr<ast::Expression> ParserImpl::multiplicative_expression() {
if (lhs == nullptr)
return nullptr;
return multiplicative_expr(std::move(lhs));
return expect_multiplicative_expr(std::move(lhs));
}
// additive_expr
// :
// | PLUS multiplicative_expression additive_expr
// | MINUS multiplicative_expression additive_expr
std::unique_ptr<ast::Expression> ParserImpl::additive_expr(
std::unique_ptr<ast::Expression> ParserImpl::expect_additive_expr(
std::unique_ptr<ast::Expression> lhs) {
auto t = peek();
@ -2309,7 +2311,7 @@ std::unique_ptr<ast::Expression> ParserImpl::additive_expr(
add_error(peek(), "unable to parse right side of + expression");
return nullptr;
}
return additive_expr(std::make_unique<ast::BinaryExpression>(
return expect_additive_expr(std::make_unique<ast::BinaryExpression>(
source, op, std::move(lhs), std::move(rhs)));
}
@ -2322,14 +2324,14 @@ std::unique_ptr<ast::Expression> ParserImpl::additive_expression() {
if (lhs == nullptr)
return nullptr;
return additive_expr(std::move(lhs));
return expect_additive_expr(std::move(lhs));
}
// shift_expr
// :
// | LESS_THAN LESS_THAN additive_expression shift_expr
// | GREATER_THAN GREATER_THAN additive_expression shift_expr
std::unique_ptr<ast::Expression> ParserImpl::shift_expr(
std::unique_ptr<ast::Expression> ParserImpl::expect_shift_expr(
std::unique_ptr<ast::Expression> lhs) {
auto t = peek();
auto source = t.source();
@ -2359,7 +2361,7 @@ std::unique_ptr<ast::Expression> ParserImpl::shift_expr(
" expression");
return nullptr;
}
return shift_expr(std::make_unique<ast::BinaryExpression>(
return expect_shift_expr(std::make_unique<ast::BinaryExpression>(
source, op, std::move(lhs), std::move(rhs)));
}
@ -2372,7 +2374,7 @@ std::unique_ptr<ast::Expression> ParserImpl::shift_expression() {
if (lhs == nullptr)
return nullptr;
return shift_expr(std::move(lhs));
return expect_shift_expr(std::move(lhs));
}
// relational_expr
@ -2381,7 +2383,7 @@ std::unique_ptr<ast::Expression> ParserImpl::shift_expression() {
// | GREATER_THAN shift_expression relational_expr
// | LESS_THAN_EQUAL shift_expression relational_expr
// | GREATER_THAN_EQUAL shift_expression relational_expr
std::unique_ptr<ast::Expression> ParserImpl::relational_expr(
std::unique_ptr<ast::Expression> ParserImpl::expect_relational_expr(
std::unique_ptr<ast::Expression> lhs) {
auto t = peek();
ast::BinaryOp op = ast::BinaryOp::kNone;
@ -2407,7 +2409,7 @@ std::unique_ptr<ast::Expression> ParserImpl::relational_expr(
add_error(peek(), "unable to parse right side of " + name + " expression");
return nullptr;
}
return relational_expr(std::make_unique<ast::BinaryExpression>(
return expect_relational_expr(std::make_unique<ast::BinaryExpression>(
source, op, std::move(lhs), std::move(rhs)));
}
@ -2420,14 +2422,14 @@ std::unique_ptr<ast::Expression> ParserImpl::relational_expression() {
if (lhs == nullptr)
return nullptr;
return relational_expr(std::move(lhs));
return expect_relational_expr(std::move(lhs));
}
// equality_expr
// :
// | EQUAL_EQUAL relational_expression equality_expr
// | NOT_EQUAL relational_expression equality_expr
std::unique_ptr<ast::Expression> ParserImpl::equality_expr(
std::unique_ptr<ast::Expression> ParserImpl::expect_equality_expr(
std::unique_ptr<ast::Expression> lhs) {
auto t = peek();
ast::BinaryOp op = ast::BinaryOp::kNone;
@ -2449,7 +2451,7 @@ std::unique_ptr<ast::Expression> ParserImpl::equality_expr(
add_error(peek(), "unable to parse right side of " + name + " expression");
return nullptr;
}
return equality_expr(std::make_unique<ast::BinaryExpression>(
return expect_equality_expr(std::make_unique<ast::BinaryExpression>(
source, op, std::move(lhs), std::move(rhs)));
}
@ -2462,13 +2464,13 @@ std::unique_ptr<ast::Expression> ParserImpl::equality_expression() {
if (lhs == nullptr)
return nullptr;
return equality_expr(std::move(lhs));
return expect_equality_expr(std::move(lhs));
}
// and_expr
// :
// | AND equality_expression and_expr
std::unique_ptr<ast::Expression> ParserImpl::and_expr(
std::unique_ptr<ast::Expression> ParserImpl::expect_and_expr(
std::unique_ptr<ast::Expression> lhs) {
auto t = peek();
if (!t.IsAnd())
@ -2484,7 +2486,7 @@ std::unique_ptr<ast::Expression> ParserImpl::and_expr(
add_error(peek(), "unable to parse right side of & expression");
return nullptr;
}
return and_expr(std::make_unique<ast::BinaryExpression>(
return expect_and_expr(std::make_unique<ast::BinaryExpression>(
source, ast::BinaryOp::kAnd, std::move(lhs), std::move(rhs)));
}
@ -2497,13 +2499,13 @@ std::unique_ptr<ast::Expression> ParserImpl::and_expression() {
if (lhs == nullptr)
return nullptr;
return and_expr(std::move(lhs));
return expect_and_expr(std::move(lhs));
}
// exclusive_or_expr
// :
// | XOR and_expression exclusive_or_expr
std::unique_ptr<ast::Expression> ParserImpl::exclusive_or_expr(
std::unique_ptr<ast::Expression> ParserImpl::expect_exclusive_or_expr(
std::unique_ptr<ast::Expression> lhs) {
auto t = peek();
if (!t.IsXor())
@ -2519,7 +2521,7 @@ std::unique_ptr<ast::Expression> ParserImpl::exclusive_or_expr(
add_error(peek(), "unable to parse right side of ^ expression");
return nullptr;
}
return exclusive_or_expr(std::make_unique<ast::BinaryExpression>(
return expect_exclusive_or_expr(std::make_unique<ast::BinaryExpression>(
source, ast::BinaryOp::kXor, std::move(lhs), std::move(rhs)));
}
@ -2532,13 +2534,13 @@ std::unique_ptr<ast::Expression> ParserImpl::exclusive_or_expression() {
if (lhs == nullptr)
return nullptr;
return exclusive_or_expr(std::move(lhs));
return expect_exclusive_or_expr(std::move(lhs));
}
// inclusive_or_expr
// :
// | OR exclusive_or_expression inclusive_or_expr
std::unique_ptr<ast::Expression> ParserImpl::inclusive_or_expr(
std::unique_ptr<ast::Expression> ParserImpl::expect_inclusive_or_expr(
std::unique_ptr<ast::Expression> lhs) {
auto t = peek();
if (!t.IsOr())
@ -2554,7 +2556,7 @@ std::unique_ptr<ast::Expression> ParserImpl::inclusive_or_expr(
add_error(peek(), "unable to parse right side of | expression");
return nullptr;
}
return inclusive_or_expr(std::make_unique<ast::BinaryExpression>(
return expect_inclusive_or_expr(std::make_unique<ast::BinaryExpression>(
source, ast::BinaryOp::kOr, std::move(lhs), std::move(rhs)));
}
@ -2567,13 +2569,13 @@ std::unique_ptr<ast::Expression> ParserImpl::inclusive_or_expression() {
if (lhs == nullptr)
return nullptr;
return inclusive_or_expr(std::move(lhs));
return expect_inclusive_or_expr(std::move(lhs));
}
// logical_and_expr
// :
// | AND_AND inclusive_or_expression logical_and_expr
std::unique_ptr<ast::Expression> ParserImpl::logical_and_expr(
std::unique_ptr<ast::Expression> ParserImpl::expect_logical_and_expr(
std::unique_ptr<ast::Expression> lhs) {
auto t = peek();
if (!t.IsAndAnd())
@ -2589,7 +2591,7 @@ std::unique_ptr<ast::Expression> ParserImpl::logical_and_expr(
add_error(peek(), "unable to parse right side of && expression");
return nullptr;
}
return logical_and_expr(std::make_unique<ast::BinaryExpression>(
return expect_logical_and_expr(std::make_unique<ast::BinaryExpression>(
source, ast::BinaryOp::kLogicalAnd, std::move(lhs), std::move(rhs)));
}
@ -2602,13 +2604,13 @@ std::unique_ptr<ast::Expression> ParserImpl::logical_and_expression() {
if (lhs == nullptr)
return nullptr;
return logical_and_expr(std::move(lhs));
return expect_logical_and_expr(std::move(lhs));
}
// logical_or_expr
// :
// | OR_OR logical_and_expression logical_or_expr
std::unique_ptr<ast::Expression> ParserImpl::logical_or_expr(
std::unique_ptr<ast::Expression> ParserImpl::expect_logical_or_expr(
std::unique_ptr<ast::Expression> lhs) {
auto t = peek();
if (!t.IsOrOr())
@ -2624,7 +2626,7 @@ std::unique_ptr<ast::Expression> ParserImpl::logical_or_expr(
add_error(peek(), "unable to parse right side of || expression");
return nullptr;
}
return logical_or_expr(std::make_unique<ast::BinaryExpression>(
return expect_logical_or_expr(std::make_unique<ast::BinaryExpression>(
source, ast::BinaryOp::kLogicalOr, std::move(lhs), std::move(rhs)));
}
@ -2637,7 +2639,7 @@ std::unique_ptr<ast::Expression> ParserImpl::logical_or_expression() {
if (lhs == nullptr)
return nullptr;
return logical_or_expr(std::move(lhs));
return expect_logical_or_expr(std::move(lhs));
}
// assignment_stmt
@ -2725,12 +2727,12 @@ std::unique_ptr<ast::Literal> ParserImpl::const_literal() {
// const_expr
// : type_decl PAREN_LEFT (const_expr COMMA)? const_expr PAREN_RIGHT
// | const_literal
std::unique_ptr<ast::ConstructorExpression> ParserImpl::const_expr() {
return const_expr_internal(0);
std::unique_ptr<ast::ConstructorExpression> ParserImpl::expect_const_expr() {
return expect_const_expr_internal(0);
}
std::unique_ptr<ast::ConstructorExpression> ParserImpl::const_expr_internal(
uint32_t depth) {
std::unique_ptr<ast::ConstructorExpression>
ParserImpl::expect_const_expr_internal(uint32_t depth) {
auto t = peek();
if (depth > kMaxConstExprDepth) {
@ -2744,7 +2746,7 @@ std::unique_ptr<ast::ConstructorExpression> ParserImpl::const_expr_internal(
if (type != nullptr) {
ast::ExpressionList params;
bool ok = expect_paren_block("type constructor", [&] {
auto param = const_expr_internal(depth + 1);
auto param = expect_const_expr_internal(depth + 1);
if (has_error())
return false;
if (param == nullptr) {
@ -2753,7 +2755,7 @@ std::unique_ptr<ast::ConstructorExpression> ParserImpl::const_expr_internal(
}
params.push_back(std::move(param));
while (match(Token::Type::kComma)) {
param = const_expr_internal(depth + 1);
param = expect_const_expr_internal(depth + 1);
if (has_error())
return false;
if (param == nullptr) {

View File

@ -155,8 +155,8 @@ class ParserImpl {
/// Parses the `translation_unit` grammar element
void translation_unit();
/// Parses the `global_decl` grammar element
void global_decl();
/// Parses the `global_decl` grammar element, erroring on parse failure.
void expect_global_decl();
/// Parses a `global_variable_decl` grammar element with the initial
/// `variable_decoration_list*` provided as |decos|.
/// @returns the variable parsed or nullptr
@ -190,14 +190,16 @@ class ParserImpl {
/// @param decos the list of decorations for the struct declaration.
std::unique_ptr<ast::type::StructType> struct_decl(
ast::DecorationList& decos);
/// Parses a `struct_body_decl` grammar element
/// Parses a `struct_body_decl` grammar element, erroring on parse failure.
/// @returns the struct members
ast::StructMemberList struct_body_decl();
ast::StructMemberList expect_struct_body_decl();
/// Parses a `struct_member` grammar element with the initial
/// `struct_member_decoration_decl+` provided as |decos|.
/// `struct_member_decoration_decl+` provided as |decos|, erroring on parse
/// failure.
/// @param decos the list of decorations for the struct member.
/// @returns the struct member or nullptr
std::unique_ptr<ast::StructMember> struct_member(ast::DecorationList& decos);
std::unique_ptr<ast::StructMember> expect_struct_member(
ast::DecorationList& decos);
/// Parses a `function_decl` grammar element with the initial
/// `function_decoration_decl*` provided as |decos|.
/// @param decos the list of decorations for the function declaration.
@ -233,9 +235,9 @@ class ParserImpl {
/// Parses a `function_header` grammar element
/// @returns the parsed function nullptr otherwise
std::unique_ptr<ast::Function> function_header();
/// Parses a `param_list` grammar element
/// Parses a `param_list` grammar element, erroring on parse failure.
/// @returns the parsed variables
ast::VariableList param_list();
ast::VariableList expect_param_list();
/// Parses a `pipeline_stage` grammar element, erroring if the next token does
/// not match a stage name.
/// @returns the pipeline stage or PipelineStage::kNone if none matched, along
@ -246,12 +248,12 @@ class ParserImpl {
/// @returns the builtin or Builtin::kNone if none matched, along with the
/// source location for the stage.
std::pair<ast::Builtin, Source> expect_builtin();
/// Parses a `body_stmt` grammar element
/// Parses a `body_stmt` grammar element, erroring on parse failure.
/// @returns the parsed statements
std::unique_ptr<ast::BlockStatement> body_stmt();
/// Parses a `paren_rhs_stmt` grammar element
std::unique_ptr<ast::BlockStatement> expect_body_stmt();
/// Parses a `paren_rhs_stmt` grammar element, erroring on parse failure.
/// @returns the parsed element or nullptr
std::unique_ptr<ast::Expression> paren_rhs_stmt();
std::unique_ptr<ast::Expression> expect_paren_rhs_stmt();
/// Parses a `statements` grammar element
/// @returns the statements parsed
std::unique_ptr<ast::BlockStatement> statements();
@ -297,9 +299,9 @@ class ParserImpl {
/// Parses a `loop_stmt` grammar element
/// @returns the parsed loop or nullptr
std::unique_ptr<ast::LoopStatement> loop_stmt();
/// Parses a `for_header` grammar element
/// Parses a `for_header` grammar element, erroring on parse failure.
/// @returns the parsed for header or nullptr
std::unique_ptr<ForHeader> for_header();
std::unique_ptr<ForHeader> expect_for_header();
/// Parses a `for_stmt` grammar element
/// @returns the parsed for loop or nullptr
std::unique_ptr<ast::Statement> for_stmt();
@ -309,15 +311,16 @@ class ParserImpl {
/// Parses a `const_literal` grammar element
/// @returns the const literal parsed or nullptr if none found
std::unique_ptr<ast::Literal> const_literal();
/// Parses a `const_expr` grammar element
/// Parses a `const_expr` grammar element, erroring on parse failure.
/// @returns the parsed constructor expression or nullptr on error
std::unique_ptr<ast::ConstructorExpression> const_expr();
std::unique_ptr<ast::ConstructorExpression> expect_const_expr();
/// Parses a `primary_expression` grammar element
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> primary_expression();
/// Parses a `argument_expression_list` grammar element
/// Parses a `argument_expression_list` grammar element, erroring on parse
/// failure.
/// @returns the list of arguments
ast::ExpressionList argument_expression_list();
ast::ExpressionList expect_argument_expression_list();
/// Parses the recursive portion of the postfix_expression
/// @param prefix the left side of the expression
/// @returns the parsed expression or nullptr
@ -329,82 +332,92 @@ class ParserImpl {
/// Parses a `unary_expression` grammar element
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> unary_expression();
/// Parses the recursive part of the `multiplicative_expression`
/// Parses the recursive part of the `multiplicative_expression`, erroring on
/// parse failure.
/// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> multiplicative_expr(
std::unique_ptr<ast::Expression> expect_multiplicative_expr(
std::unique_ptr<ast::Expression> lhs);
/// Parses the `multiplicative_expression` grammar element
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> multiplicative_expression();
/// Parses the recursive part of the `additive_expression`
/// Parses the recursive part of the `additive_expression`, erroring on parse
/// failure.
/// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> additive_expr(
std::unique_ptr<ast::Expression> expect_additive_expr(
std::unique_ptr<ast::Expression> lhs);
/// Parses the `additive_expression` grammar element
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> additive_expression();
/// Parses the recursive part of the `shift_expression`
/// Parses the recursive part of the `shift_expression`, erroring on parse
/// failure.
/// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> shift_expr(
std::unique_ptr<ast::Expression> expect_shift_expr(
std::unique_ptr<ast::Expression> lhs);
/// Parses the `shift_expression` grammar element
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> shift_expression();
/// Parses the recursive part of the `relational_expression`
/// Parses the recursive part of the `relational_expression`, erroring on
/// parse failure.
/// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> relational_expr(
std::unique_ptr<ast::Expression> expect_relational_expr(
std::unique_ptr<ast::Expression> lhs);
/// Parses the `relational_expression` grammar element
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> relational_expression();
/// Parses the recursive part of the `equality_expression`
/// Parses the recursive part of the `equality_expression`, erroring on parse
/// failure.
/// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> equality_expr(
std::unique_ptr<ast::Expression> expect_equality_expr(
std::unique_ptr<ast::Expression> lhs);
/// Parses the `equality_expression` grammar element
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> equality_expression();
/// Parses the recursive part of the `and_expression`
/// Parses the recursive part of the `and_expression`, erroring on parse
/// failure.
/// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> and_expr(
std::unique_ptr<ast::Expression> expect_and_expr(
std::unique_ptr<ast::Expression> lhs);
/// Parses the `and_expression` grammar element
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> and_expression();
/// Parses the recursive part of the `exclusive_or_expression`
/// Parses the recursive part of the `exclusive_or_expression`, erroring on
/// parse failure.
/// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> exclusive_or_expr(
std::unique_ptr<ast::Expression> expect_exclusive_or_expr(
std::unique_ptr<ast::Expression> lhs);
/// Parses the `exclusive_or_expression` grammar elememnt
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> exclusive_or_expression();
/// Parses the recursive part of the `inclusive_or_expression`
/// Parses the recursive part of the `inclusive_or_expression`, erroring on
/// parse failure.
/// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> inclusive_or_expr(
std::unique_ptr<ast::Expression> expect_inclusive_or_expr(
std::unique_ptr<ast::Expression> lhs);
/// Parses the `inclusive_or_expression` grammar element
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> inclusive_or_expression();
/// Parses the recursive part of the `logical_and_expression`
/// Parses the recursive part of the `logical_and_expression`, erroring on
/// parse failure.
/// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> logical_and_expr(
std::unique_ptr<ast::Expression> expect_logical_and_expr(
std::unique_ptr<ast::Expression> lhs);
/// Parses a `logical_and_expression` grammar element
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> logical_and_expression();
/// Parses the recursive part of the `logical_or_expression`
/// Parses the recursive part of the `logical_or_expression`, erroring on
/// parse failure.
/// @param lhs the left side of the expression
/// @returns the parsed expression or nullptr
std::unique_ptr<ast::Expression> logical_or_expr(
std::unique_ptr<ast::Expression> expect_logical_or_expr(
std::unique_ptr<ast::Expression> lhs);
/// Parses a `logical_or_expression` grammar element
/// @returns the parsed expression or nullptr
@ -528,12 +541,12 @@ class ParserImpl {
/// Used to ensure that all decorations are consumed.
bool expect_decorations_consumed(const ast::DecorationList& list);
ast::type::Type* type_decl_pointer(Token t);
ast::type::Type* type_decl_vector(Token t);
ast::type::Type* type_decl_array(ast::ArrayDecorationList decos);
ast::type::Type* type_decl_matrix(Token t);
ast::type::Type* expect_type_decl_pointer(Token t);
ast::type::Type* expect_type_decl_vector(Token t);
ast::type::Type* expect_type_decl_array(ast::ArrayDecorationList decos);
ast::type::Type* expect_type_decl_matrix(Token t);
std::unique_ptr<ast::ConstructorExpression> const_expr_internal(
std::unique_ptr<ast::ConstructorExpression> expect_const_expr_internal(
uint32_t depth);
Context& ctx_;

View File

@ -28,7 +28,7 @@ namespace {
TEST_F(ParserImplTest, ArgumentExpressionList_Parses) {
auto* p = parser("a");
auto e = p->argument_expression_list();
auto e = p->expect_argument_expression_list();
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_EQ(e.size(), 1u);
@ -37,7 +37,7 @@ TEST_F(ParserImplTest, ArgumentExpressionList_Parses) {
TEST_F(ParserImplTest, ArgumentExpressionList_ParsesMultiple) {
auto* p = parser("a, -33, 1+2");
auto e = p->argument_expression_list();
auto e = p->expect_argument_expression_list();
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_EQ(e.size(), 3u);
@ -48,14 +48,14 @@ TEST_F(ParserImplTest, ArgumentExpressionList_ParsesMultiple) {
TEST_F(ParserImplTest, ArgumentExpressionList_HandlesMissingExpression) {
auto* p = parser("a, ");
auto e = p->argument_expression_list();
auto e = p->expect_argument_expression_list();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:4: unable to parse argument expression after comma");
}
TEST_F(ParserImplTest, ArgumentExpressionList_HandlesInvalidExpression) {
auto* p = parser("if(a) {}");
auto e = p->argument_expression_list();
auto e = p->expect_argument_expression_list();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:1: unable to parse argument expression");
}

View File

@ -26,7 +26,7 @@ TEST_F(ParserImplTest, BodyStmt) {
discard;
return 1 + b / 2;
})");
auto e = p->body_stmt();
auto e = p->expect_body_stmt();
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_EQ(e->size(), 2u);
EXPECT_TRUE(e->get(0)->IsDiscard());
@ -35,21 +35,21 @@ TEST_F(ParserImplTest, BodyStmt) {
TEST_F(ParserImplTest, BodyStmt_Empty) {
auto* p = parser("{}");
auto e = p->body_stmt();
auto e = p->expect_body_stmt();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_EQ(e->size(), 0u);
}
TEST_F(ParserImplTest, BodyStmt_InvalidStmt) {
auto* p = parser("{fn main() -> void {}}");
auto e = p->body_stmt();
auto e = p->expect_body_stmt();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:2: expected '}'");
}
TEST_F(ParserImplTest, BodyStmt_MissingRightParen) {
auto* p = parser("{return;");
auto e = p->body_stmt();
auto e = p->expect_body_stmt();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:9: expected '}'");
}

View File

@ -28,7 +28,7 @@ namespace {
TEST_F(ParserImplTest, ConstExpr_TypeDecl) {
auto* p = parser("vec2<f32>(1., 2.)");
auto e = p->const_expr();
auto e = p->expect_const_expr();
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e, nullptr);
ASSERT_TRUE(e->IsConstructor());
@ -56,7 +56,7 @@ TEST_F(ParserImplTest, ConstExpr_TypeDecl) {
TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingRightParen) {
auto* p = parser("vec2<f32>(1., 2.");
auto e = p->const_expr();
auto e = p->expect_const_expr();
ASSERT_TRUE(p->has_error());
ASSERT_EQ(e, nullptr);
EXPECT_EQ(p->error(), "1:17: expected ')' for type constructor");
@ -64,7 +64,7 @@ TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingRightParen) {
TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingLeftParen) {
auto* p = parser("vec2<f32> 1., 2.)");
auto e = p->const_expr();
auto e = p->expect_const_expr();
ASSERT_TRUE(p->has_error());
ASSERT_EQ(e, nullptr);
EXPECT_EQ(p->error(), "1:11: expected '(' for type constructor");
@ -72,7 +72,7 @@ TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingLeftParen) {
TEST_F(ParserImplTest, ConstExpr_TypeDecl_HangingComma) {
auto* p = parser("vec2<f32>(1.,)");
auto e = p->const_expr();
auto e = p->expect_const_expr();
ASSERT_TRUE(p->has_error());
ASSERT_EQ(e, nullptr);
EXPECT_EQ(p->error(), "1:14: unable to parse const literal");
@ -80,7 +80,7 @@ TEST_F(ParserImplTest, ConstExpr_TypeDecl_HangingComma) {
TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingComma) {
auto* p = parser("vec2<f32>(1. 2.");
auto e = p->const_expr();
auto e = p->expect_const_expr();
ASSERT_TRUE(p->has_error());
ASSERT_EQ(e, nullptr);
EXPECT_EQ(p->error(), "1:14: expected ')' for type constructor");
@ -88,7 +88,7 @@ TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingComma) {
TEST_F(ParserImplTest, ConstExpr_MissingExpr) {
auto* p = parser("vec2<f32>()");
auto e = p->const_expr();
auto e = p->expect_const_expr();
ASSERT_TRUE(p->has_error());
ASSERT_EQ(e, nullptr);
EXPECT_EQ(p->error(), "1:11: unable to parse const literal");
@ -96,7 +96,7 @@ TEST_F(ParserImplTest, ConstExpr_MissingExpr) {
TEST_F(ParserImplTest, ConstExpr_InvalidExpr) {
auto* p = parser("vec2<f32>(1., if(a) {})");
auto e = p->const_expr();
auto e = p->expect_const_expr();
ASSERT_TRUE(p->has_error());
ASSERT_EQ(e, nullptr);
EXPECT_EQ(p->error(), "1:15: unable to parse const literal");
@ -104,7 +104,7 @@ TEST_F(ParserImplTest, ConstExpr_InvalidExpr) {
TEST_F(ParserImplTest, ConstExpr_ConstLiteral) {
auto* p = parser("true");
auto e = p->const_expr();
auto e = p->expect_const_expr();
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e, nullptr);
ASSERT_TRUE(e->IsConstructor());
@ -116,7 +116,7 @@ TEST_F(ParserImplTest, ConstExpr_ConstLiteral) {
TEST_F(ParserImplTest, ConstExpr_ConstLiteral_Invalid) {
auto* p = parser("invalid");
auto e = p->const_expr();
auto e = p->expect_const_expr();
ASSERT_TRUE(p->has_error());
ASSERT_EQ(e, nullptr);
EXPECT_EQ(p->error(), "1:1: unknown constructed type 'invalid'");
@ -132,7 +132,7 @@ TEST_F(ParserImplTest, ConstExpr_Recursion) {
out << ")";
}
auto* p = parser(out.str());
auto e = p->const_expr();
auto e = p->expect_const_expr();
ASSERT_TRUE(p->has_error());
ASSERT_EQ(e, nullptr);
EXPECT_EQ(p->error(), "1:517: max const_expr depth reached");

View File

@ -25,13 +25,13 @@ namespace {
TEST_F(ParserImplTest, GlobalDecl_Semicolon) {
auto* p = parser(";");
p->global_decl();
p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error();
}
TEST_F(ParserImplTest, GlobalDecl_GlobalVariable) {
auto* p = parser("var<out> a : vec2<i32> = vec2<i32>(1, 2);");
p->global_decl();
p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error();
auto m = p->module();
@ -43,21 +43,21 @@ TEST_F(ParserImplTest, GlobalDecl_GlobalVariable) {
TEST_F(ParserImplTest, GlobalDecl_GlobalVariable_Invalid) {
auto* p = parser("var<out> a : vec2<invalid>;");
p->global_decl();
p->expect_global_decl();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:19: unknown constructed type 'invalid'");
}
TEST_F(ParserImplTest, GlobalDecl_GlobalVariable_MissingSemicolon) {
auto* p = parser("var<out> a : vec2<i32>");
p->global_decl();
p->expect_global_decl();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:23: expected ';' for variable declaration");
}
TEST_F(ParserImplTest, GlobalDecl_GlobalConstant) {
auto* p = parser("const a : i32 = 2;");
p->global_decl();
p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error();
auto m = p->module();
@ -69,21 +69,21 @@ TEST_F(ParserImplTest, GlobalDecl_GlobalConstant) {
TEST_F(ParserImplTest, GlobalDecl_GlobalConstant_Invalid) {
auto* p = parser("const a : vec2<i32>;");
p->global_decl();
p->expect_global_decl();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:20: missing = for const declaration");
}
TEST_F(ParserImplTest, GlobalDecl_GlobalConstant_MissingSemicolon) {
auto* p = parser("const a : vec2<i32> = vec2<i32>(1, 2)");
p->global_decl();
p->expect_global_decl();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:38: expected ';' for constant declaration");
}
TEST_F(ParserImplTest, GlobalDecl_TypeAlias) {
auto* p = parser("type A = i32;");
p->global_decl();
p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error();
auto m = p->module();
@ -97,8 +97,8 @@ TEST_F(ParserImplTest, GlobalDecl_TypeAlias_StructIdent) {
a : f32;
};
type B = A;)");
p->global_decl();
p->global_decl();
p->expect_global_decl();
p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error();
auto m = p->module();
@ -115,21 +115,21 @@ type B = A;)");
TEST_F(ParserImplTest, GlobalDecl_TypeAlias_Invalid) {
auto* p = parser("type A = invalid;");
p->global_decl();
p->expect_global_decl();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:10: unknown constructed type 'invalid'");
}
TEST_F(ParserImplTest, GlobalDecl_TypeAlias_MissingSemicolon) {
auto* p = parser("type A = i32");
p->global_decl();
p->expect_global_decl();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:13: expected ';' for type alias");
}
TEST_F(ParserImplTest, GlobalDecl_Function) {
auto* p = parser("fn main() -> void { return; }");
p->global_decl();
p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error();
auto m = p->module();
@ -139,7 +139,7 @@ TEST_F(ParserImplTest, GlobalDecl_Function) {
TEST_F(ParserImplTest, GlobalDecl_Function_WithDecoration) {
auto* p = parser("[[workgroup_size(2)]] fn main() -> void { return; }");
p->global_decl();
p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error();
auto m = p->module();
@ -149,14 +149,14 @@ TEST_F(ParserImplTest, GlobalDecl_Function_WithDecoration) {
TEST_F(ParserImplTest, GlobalDecl_Function_Invalid) {
auto* p = parser("fn main() -> { return; }");
p->global_decl();
p->expect_global_decl();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:14: unable to determine function return type");
}
TEST_F(ParserImplTest, GlobalDecl_ParsesStruct) {
auto* p = parser("struct A { b: i32; c: f32;};");
p->global_decl();
p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error();
auto m = p->module();
@ -174,7 +174,7 @@ TEST_F(ParserImplTest, GlobalDecl_ParsesStruct) {
TEST_F(ParserImplTest, GlobalDecl_Struct_WithStride) {
auto* p =
parser("struct A { [[offset(0)]] data: [[stride(4)]] array<f32>; };");
p->global_decl();
p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error();
auto m = p->module();
@ -198,7 +198,7 @@ TEST_F(ParserImplTest, GlobalDecl_Struct_WithStride) {
TEST_F(ParserImplTest, GlobalDecl_Struct_WithDecoration) {
auto* p = parser("[[block]] struct A { [[offset(0)]] data: f32; };");
p->global_decl();
p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error();
auto m = p->module();
@ -216,14 +216,14 @@ TEST_F(ParserImplTest, GlobalDecl_Struct_WithDecoration) {
TEST_F(ParserImplTest, GlobalDecl_Struct_Invalid) {
auto* p = parser("[[block]] A {};");
p->global_decl();
p->expect_global_decl();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:11: expected declaration after decorations");
}
TEST_F(ParserImplTest, GlobalDecl_StructMissing_Semi) {
auto* p = parser("[[block]] struct A {}");
p->global_decl();
p->expect_global_decl();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:22: expected ';' for struct declaration");
}

View File

@ -32,7 +32,7 @@ TEST_F(ParserImplTest, ParamList_Single) {
auto* i32 = tm()->Get(std::make_unique<ast::type::I32Type>());
auto* p = parser("a : i32");
auto e = p->param_list();
auto e = p->expect_param_list();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_EQ(e.size(), 1u);
@ -52,7 +52,7 @@ TEST_F(ParserImplTest, ParamList_Multiple) {
auto* vec2 = tm()->Get(std::make_unique<ast::type::VectorType>(f32, 2));
auto* p = parser("a : i32, b: f32, c: vec2<f32>");
auto e = p->param_list();
auto e = p->expect_param_list();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_EQ(e.size(), 3u);
@ -86,14 +86,14 @@ TEST_F(ParserImplTest, ParamList_Multiple) {
TEST_F(ParserImplTest, ParamList_Empty) {
auto* p = parser("");
auto e = p->param_list();
auto e = p->expect_param_list();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_EQ(e.size(), 0u);
}
TEST_F(ParserImplTest, ParamList_HangingComma) {
auto* p = parser("a : i32,");
auto e = p->param_list();
auto e = p->expect_param_list();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:8: found , but no variable declaration");
}

View File

@ -23,7 +23,7 @@ namespace {
TEST_F(ParserImplTest, ParenRhsStmt) {
auto* p = parser("(a + b)");
auto e = p->paren_rhs_stmt();
auto e = p->expect_paren_rhs_stmt();
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_NE(e, nullptr);
ASSERT_TRUE(e->IsBinary());
@ -31,7 +31,7 @@ TEST_F(ParserImplTest, ParenRhsStmt) {
TEST_F(ParserImplTest, ParenRhsStmt_MissingLeftParen) {
auto* p = parser("true)");
auto e = p->paren_rhs_stmt();
auto e = p->expect_paren_rhs_stmt();
ASSERT_TRUE(p->has_error());
ASSERT_EQ(e, nullptr);
EXPECT_EQ(p->error(), "1:1: expected '('");
@ -39,7 +39,7 @@ TEST_F(ParserImplTest, ParenRhsStmt_MissingLeftParen) {
TEST_F(ParserImplTest, ParenRhsStmt_MissingRightParen) {
auto* p = parser("(true");
auto e = p->paren_rhs_stmt();
auto e = p->expect_paren_rhs_stmt();
ASSERT_TRUE(p->has_error());
ASSERT_EQ(e, nullptr);
EXPECT_EQ(p->error(), "1:6: expected ')'");
@ -47,7 +47,7 @@ TEST_F(ParserImplTest, ParenRhsStmt_MissingRightParen) {
TEST_F(ParserImplTest, ParenRhsStmt_InvalidExpression) {
auto* p = parser("(if (a() {})");
auto e = p->paren_rhs_stmt();
auto e = p->expect_paren_rhs_stmt();
ASSERT_TRUE(p->has_error());
ASSERT_EQ(e, nullptr);
EXPECT_EQ(p->error(), "1:2: unable to parse expression");
@ -55,7 +55,7 @@ TEST_F(ParserImplTest, ParenRhsStmt_InvalidExpression) {
TEST_F(ParserImplTest, ParenRhsStmt_MissingExpression) {
auto* p = parser("()");
auto e = p->paren_rhs_stmt();
auto e = p->expect_paren_rhs_stmt();
ASSERT_TRUE(p->has_error());
ASSERT_EQ(e, nullptr);
EXPECT_EQ(p->error(), "1:2: unable to parse expression");

View File

@ -27,7 +27,7 @@ TEST_F(ParserImplTest, StructBodyDecl_Parses) {
auto* i32 = tm()->Get(std::make_unique<ast::type::I32Type>());
auto* p = parser("{a : i32;}");
auto m = p->struct_body_decl();
auto m = p->expect_struct_body_decl();
ASSERT_FALSE(p->has_error());
ASSERT_EQ(m.size(), 1u);
@ -39,7 +39,7 @@ TEST_F(ParserImplTest, StructBodyDecl_Parses) {
TEST_F(ParserImplTest, StructBodyDecl_ParsesEmpty) {
auto* p = parser("{}");
auto m = p->struct_body_decl();
auto m = p->expect_struct_body_decl();
ASSERT_FALSE(p->has_error());
ASSERT_EQ(m.size(), 0u);
}
@ -49,7 +49,7 @@ TEST_F(ParserImplTest, StructBodyDecl_InvalidMember) {
{
[[offset(nan)]] a : i32;
})");
auto m = p->struct_body_decl();
auto m = p->expect_struct_body_decl();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(),
"3:12: expected signed integer literal for offset decoration");
@ -57,7 +57,7 @@ TEST_F(ParserImplTest, StructBodyDecl_InvalidMember) {
TEST_F(ParserImplTest, StructBodyDecl_MissingClosingBracket) {
auto* p = parser("{a : i32;");
auto m = p->struct_body_decl();
auto m = p->expect_struct_body_decl();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:10: expected '}' for struct declaration");
}
@ -68,7 +68,7 @@ TEST_F(ParserImplTest, StructBodyDecl_InvalidToken) {
a : i32;
1.23
} )");
auto m = p->struct_body_decl();
auto m = p->expect_struct_body_decl();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "4:3: invalid identifier declaration");
}

View File

@ -30,7 +30,7 @@ TEST_F(ParserImplTest, StructMember_Parses) {
auto* p = parser("a : i32;");
auto decos = p->decoration_list();
EXPECT_EQ(decos.size(), 0u);
auto m = p->struct_member(decos);
auto m = p->expect_struct_member(decos);
ASSERT_FALSE(p->has_error());
ASSERT_NE(m, nullptr);
@ -50,7 +50,7 @@ TEST_F(ParserImplTest, StructMember_ParsesWithDecoration) {
auto* p = parser("[[offset(2)]] a : i32;");
auto decos = p->decoration_list();
EXPECT_EQ(decos.size(), 1u);
auto m = p->struct_member(decos);
auto m = p->expect_struct_member(decos);
ASSERT_FALSE(p->has_error());
ASSERT_NE(m, nullptr);
@ -73,7 +73,7 @@ TEST_F(ParserImplTest, StructMember_ParsesWithMultipleDecorations) {
[[offset(4)]] a : i32;)");
auto decos = p->decoration_list();
EXPECT_EQ(decos.size(), 2u);
auto m = p->struct_member(decos);
auto m = p->expect_struct_member(decos);
ASSERT_FALSE(p->has_error());
ASSERT_NE(m, nullptr);
@ -94,7 +94,7 @@ TEST_F(ParserImplTest, StructMember_ParsesWithMultipleDecorations) {
TEST_F(ParserImplTest, StructMember_InvalidDecoration) {
auto* p = parser("[[offset(nan)]] a : i32;");
auto decos = p->decoration_list();
auto m = p->struct_member(decos);
auto m = p->expect_struct_member(decos);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(m, nullptr);
EXPECT_EQ(p->error(),
@ -104,7 +104,7 @@ TEST_F(ParserImplTest, StructMember_InvalidDecoration) {
TEST_F(ParserImplTest, StructMember_InvalidVariable) {
auto* p = parser("[[offset(4)]] a : B;");
auto decos = p->decoration_list();
auto m = p->struct_member(decos);
auto m = p->expect_struct_member(decos);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(m, nullptr);
EXPECT_EQ(p->error(), "1:19: unknown constructed type 'B'");
@ -113,7 +113,7 @@ TEST_F(ParserImplTest, StructMember_InvalidVariable) {
TEST_F(ParserImplTest, StructMember_MissingSemicolon) {
auto* p = parser("a : i32");
auto decos = p->decoration_list();
auto m = p->struct_member(decos);
auto m = p->expect_struct_member(decos);
ASSERT_TRUE(p->has_error());
ASSERT_EQ(m, nullptr);
EXPECT_EQ(p->error(), "1:8: expected ';' for struct member");