Update `type_decl` and `primary_expression`
This CL updates the `type_decl` and `primary_expression` rules
to the new WGSL grammar.
Bug: tint:1633
Change-Id: Ifc457e01f43fe33e083fc8f9e316fdd02bfd87c3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/99881
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/reader/wgsl/parser_impl.cc b/src/tint/reader/wgsl/parser_impl.cc
index 99abd60..9335356 100644
--- a/src/tint/reader/wgsl/parser_impl.cc
+++ b/src/tint/reader/wgsl/parser_impl.cc
@@ -1182,26 +1182,7 @@
// type_decl
// : IDENTIFIER
-// | BOOL
-// | FLOAT32
-// | INT32
-// | UINT32
-// | VEC2 LESS_THAN type_decl GREATER_THAN
-// | VEC3 LESS_THAN type_decl GREATER_THAN
-// | VEC4 LESS_THAN type_decl GREATER_THAN
-// | PTR LESS_THAN storage_class, type_decl (COMMA access_mode)? GREATER_THAN
-// | array_attribute_list* ARRAY LESS_THAN type_decl COMMA element_count_expression GREATER_THAN
-// | array_attribute_list* ARRAY LESS_THAN type_decl GREATER_THAN
-// | MAT2x2 LESS_THAN type_decl GREATER_THAN
-// | MAT2x3 LESS_THAN type_decl GREATER_THAN
-// | MAT2x4 LESS_THAN type_decl GREATER_THAN
-// | MAT3x2 LESS_THAN type_decl GREATER_THAN
-// | MAT3x3 LESS_THAN type_decl GREATER_THAN
-// | MAT3x4 LESS_THAN type_decl GREATER_THAN
-// | MAT4x2 LESS_THAN type_decl GREATER_THAN
-// | MAT4x3 LESS_THAN type_decl GREATER_THAN
-// | MAT4x4 LESS_THAN type_decl GREATER_THAN
-// | texture_and_sampler_types
+// | type_decl_without_ident
Maybe<const ast::Type*> ParserImpl::type_decl() {
auto& t = peek();
Source source;
@@ -1209,57 +1190,7 @@
return builder_.create<ast::TypeName>(source, builder_.Symbols().Register(t.to_str()));
}
- if (match(Token::Type::kBool, &source)) {
- return builder_.ty.bool_(source);
- }
-
- if (match(Token::Type::kF16, &source)) {
- return builder_.ty.f16(source);
- }
-
- if (match(Token::Type::kF32, &source)) {
- return builder_.ty.f32(source);
- }
-
- if (match(Token::Type::kI32, &source)) {
- return builder_.ty.i32(source);
- }
-
- if (match(Token::Type::kU32, &source)) {
- return builder_.ty.u32(source);
- }
-
- if (t.IsVector()) {
- next(); // Consume the peek
- return expect_type_decl_vector(t);
- }
-
- if (match(Token::Type::kPtr)) {
- return expect_type_decl_pointer(t);
- }
-
- if (match(Token::Type::kAtomic)) {
- return expect_type_decl_atomic(t);
- }
-
- if (match(Token::Type::kArray, &source)) {
- return expect_type_decl_array(t);
- }
-
- if (t.IsMatrix()) {
- next(); // Consume the peek
- return expect_type_decl_matrix(t);
- }
-
- auto texture_or_sampler = texture_and_sampler_types();
- if (texture_or_sampler.errored) {
- return Failure::kErrored;
- }
- if (texture_or_sampler.matched) {
- return texture_or_sampler;
- }
-
- return Failure::kNoMatch;
+ return type_decl_without_ident();
}
Expect<const ast::Type*> ParserImpl::expect_type(std::string_view use) {
@@ -1314,47 +1245,6 @@
return builder_.ty.pointer(make_source_range_from(s), subtype.value, storage_class, access);
}
-Expect<const ast::Type*> ParserImpl::expect_type_decl_pointer(const Token& t) {
- const char* use = "ptr declaration";
-
- auto storage_class = ast::StorageClass::kNone;
- auto access = ast::Access::kUndefined;
-
- auto subtype = expect_lt_gt_block(use, [&]() -> Expect<const ast::Type*> {
- auto sc = expect_address_space(use);
- if (sc.errored) {
- return Failure::kErrored;
- }
- storage_class = sc.value;
-
- if (!expect(use, Token::Type::kComma)) {
- return Failure::kErrored;
- }
-
- auto type = expect_type(use);
- if (type.errored) {
- return Failure::kErrored;
- }
-
- if (match(Token::Type::kComma)) {
- auto ac = expect_access_mode("access control");
- if (ac.errored) {
- return Failure::kErrored;
- }
- access = ac.value;
- }
-
- return type.value;
- });
-
- if (subtype.errored) {
- return Failure::kErrored;
- }
-
- return builder_.ty.pointer(make_source_range_from(t.source()), subtype.value, storage_class,
- access);
-}
-
// LESS_THAN type_decl GREATER_THAN
Expect<const ast::Type*> ParserImpl::expect_type_decl_atomic(const Source& s) {
const char* use = "atomic declaration";
@@ -1367,17 +1257,6 @@
return builder_.ty.atomic(make_source_range_from(s), subtype.value);
}
-Expect<const ast::Type*> ParserImpl::expect_type_decl_atomic(const Token& t) {
- const char* use = "atomic declaration";
-
- auto subtype = expect_lt_gt_block(use, [&] { return expect_type(use); });
- if (subtype.errored) {
- return Failure::kErrored;
- }
-
- return builder_.ty.atomic(make_source_range_from(t.source()), subtype.value);
-}
-
// LESS_THAN type_decl GREATER_THAN
Expect<const ast::Type*> ParserImpl::expect_type_decl_vector(const Source& s, uint32_t count) {
const char* use = "vector";
@@ -1389,27 +1268,6 @@
return builder_.ty.vec(make_source_range_from(s), ty.value, count);
}
-Expect<const ast::Type*> ParserImpl::expect_type_decl_vector(const Token& t) {
- uint32_t count = 2;
- if (t.Is(Token::Type::kVec3)) {
- count = 3;
- } else if (t.Is(Token::Type::kVec4)) {
- count = 4;
- }
-
- const ast::Type* subtype = nullptr;
- if (peek_is(Token::Type::kLessThan)) {
- const char* use = "vector";
- auto ty = expect_lt_gt_block(use, [&] { return expect_type(use); });
- if (ty.errored) {
- return Failure::kErrored;
- }
- subtype = ty.value;
- }
-
- return builder_.ty.vec(make_source_range_from(t.source()), subtype, count);
-}
-
// LESS_THAN type_decl ( COMMA element_count_expression )? GREATER_THAN
Expect<const ast::Type*> ParserImpl::expect_type_decl_array(const Source& s) {
const char* use = "array declaration";
@@ -1451,46 +1309,6 @@
return builder_.ty.array(make_source_range_from(s), type_size->type, type_size->size);
}
-Expect<const ast::Type*> ParserImpl::expect_type_decl_array(const Token& t) {
- const char* use = "array declaration";
-
- struct TypeAndSize {
- const ast::Type* type = nullptr;
- const ast::Expression* size = nullptr;
- };
-
- if (!peek_is(Token::Type::kLessThan)) {
- return builder_.ty.array(make_source_range_from(t.source()), nullptr, nullptr);
- }
-
- auto type_size = expect_lt_gt_block(use, [&]() -> Expect<TypeAndSize> {
- auto type = expect_type(use);
- if (type.errored) {
- return Failure::kErrored;
- }
-
- if (!match(Token::Type::kComma)) {
- return TypeAndSize{type.value, nullptr};
- }
-
- auto size = element_count_expression();
- if (size.errored) {
- return Failure::kErrored;
- }
- if (!size.matched) {
- return add_error(peek(), "expected array size expression");
- }
-
- return TypeAndSize{type.value, size.value};
- });
-
- if (type_size.errored) {
- return Failure::kErrored;
- }
-
- return builder_.ty.array(make_source_range_from(t.source()), type_size->type, type_size->size);
-}
-
// LESS_THAN type_decl GREATER_THAN
Expect<const ast::Type*> ParserImpl::expect_type_decl_matrix(const Source& s,
const MatrixDimensions& dims) {
@@ -1503,33 +1321,6 @@
return builder_.ty.mat(make_source_range_from(s), ty.value, dims.columns, dims.rows);
}
-Expect<const ast::Type*> ParserImpl::expect_type_decl_matrix(const Token& t) {
- uint32_t rows = 2;
- uint32_t columns = 2;
- if (t.IsMat3xN()) {
- columns = 3;
- } else if (t.IsMat4xN()) {
- columns = 4;
- }
- if (t.IsMatNx3()) {
- rows = 3;
- } else if (t.IsMatNx4()) {
- rows = 4;
- }
-
- const ast::Type* subtype = nullptr;
- if (peek_is(Token::Type::kLessThan)) {
- const char* use = "matrix";
- auto ty = expect_lt_gt_block(use, [&] { return expect_type(use); });
- if (ty.errored) {
- return Failure::kErrored;
- }
- subtype = ty.value;
- }
-
- return builder_.ty.mat(make_source_range_from(t.source()), subtype, columns, rows);
-}
-
// address_space
// : 'function'
// | 'private'
@@ -2129,7 +1920,7 @@
return Failure::kErrored;
}
- auto initializer = expression();
+ auto initializer = maybe_expression();
if (initializer.errored) {
return Failure::kErrored;
}
@@ -2156,7 +1947,7 @@
return Failure::kErrored;
}
- auto initializer = expression();
+ auto initializer = maybe_expression();
if (initializer.errored) {
return Failure::kErrored;
}
@@ -2183,7 +1974,7 @@
const ast::Expression* initializer = nullptr;
if (match(Token::Type::kEqual)) {
- auto initializer_expr = expression();
+ auto initializer_expr = maybe_expression();
if (initializer_expr.errored) {
return Failure::kErrored;
}
@@ -2718,31 +2509,20 @@
}
// primary_expression
-// : IDENT argument_expression_list?
-// | type_decl argument_expression_list
+// : BITCAST LESS_THAN type_decl GREATER_THAN paren_expression
+// | callable argument_expression_list
// | const_literal
+// | IDENT argument_expression_list?
// | paren_expression
-// | BITCAST LESS_THAN type_decl GREATER_THAN paren_expression
+//
+// Note, PAREN_LEFT ( expression ( COMMA expression ) * COMMA? )? PAREN_RIGHT is replaced
+// with `argument_expression_list`.
+//
+// Note, this is matching the `callable` ident here instead of having to come from
+// callable so we can return a `type` from callable.
Maybe<const ast::Expression*> ParserImpl::primary_expression() {
auto& t = peek();
- auto lit = const_literal();
- if (lit.errored) {
- return Failure::kErrored;
- }
- if (lit.matched) {
- return lit.value;
- }
-
- if (t.Is(Token::Type::kParenLeft)) {
- auto paren = expect_paren_expression();
- if (paren.errored) {
- return Failure::kErrored;
- }
-
- return paren.value;
- }
-
if (match(Token::Type::kBitcast)) {
const char* use = "bitcast expression";
@@ -2759,6 +2539,27 @@
return create<ast::BitcastExpression>(t.source(), type.value, params.value);
}
+ auto call = callable();
+ if (call.errored) {
+ return Failure::kErrored;
+ }
+ if (call.matched) {
+ auto params = expect_argument_expression_list("type constructor");
+ if (params.errored) {
+ return Failure::kErrored;
+ }
+
+ return builder_.Construct(t.source(), call.value, std::move(params.value));
+ }
+
+ auto lit = const_literal();
+ if (lit.errored) {
+ return Failure::kErrored;
+ }
+ if (lit.matched) {
+ return lit.value;
+ }
+
if (t.IsIdentifier()) {
next();
@@ -2777,17 +2578,13 @@
return ident;
}
- auto type = type_decl();
- if (type.errored) {
- return Failure::kErrored;
- }
- if (type.matched) {
- auto params = expect_argument_expression_list("type constructor");
- if (params.errored) {
+ if (t.Is(Token::Type::kParenLeft)) {
+ auto paren = expect_paren_expression();
+ if (paren.errored) {
return Failure::kErrored;
}
- return builder_.Construct(t.source(), type.value, std::move(params.value));
+ return paren.value;
}
return Failure::kNoMatch;
diff --git a/src/tint/reader/wgsl/parser_impl.h b/src/tint/reader/wgsl/parser_impl.h
index 9323b9f..44525c0 100644
--- a/src/tint/reader/wgsl/parser_impl.h
+++ b/src/tint/reader/wgsl/parser_impl.h
@@ -950,11 +950,6 @@
Expect<const ast::Type*> expect_type_decl_array(const Source& s);
Expect<const ast::Type*> expect_type_decl_matrix(const Source& s, const MatrixDimensions& dims);
- Expect<const ast::Type*> expect_type_decl_pointer(const Token& t);
- Expect<const ast::Type*> expect_type_decl_atomic(const Token& t);
- Expect<const ast::Type*> expect_type_decl_vector(const Token& t);
- Expect<const ast::Type*> expect_type_decl_array(const Token& t);
- Expect<const ast::Type*> expect_type_decl_matrix(const Token& t);
Expect<const ast::Type*> expect_type(std::string_view use);
Maybe<const ast::Statement*> non_block_statement();
diff --git a/src/tint/reader/wgsl/parser_impl_type_decl_test.cc b/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
index 57c1b72..926f7c7 100644
--- a/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
@@ -528,22 +528,6 @@
EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 17u}}));
}
-TEST_F(ParserImplTest, TypeDecl_Array_InferTypeAndSize) {
- auto p = parser("array");
- auto t = p->type_decl();
- EXPECT_TRUE(t.matched);
- EXPECT_FALSE(t.errored);
- ASSERT_NE(t.value, nullptr) << p->error();
- ASSERT_FALSE(p->has_error());
- ASSERT_TRUE(t.value->Is<ast::Array>());
-
- auto* a = t.value->As<ast::Array>();
- EXPECT_FALSE(a->IsRuntimeArray());
- EXPECT_EQ(a->type, nullptr);
- EXPECT_EQ(a->count, nullptr);
- EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 6u}}));
-}
-
TEST_F(ParserImplTest, TypeDecl_Array_BadSize) {
auto p = parser("array<f32, !>");
auto t = p->type_decl();