1 // Copyright 2020 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/ast/bitcast_expression.h"
16 #include "src/reader/wgsl/parser_impl_test_helper.h"
17
18 namespace tint {
19 namespace reader {
20 namespace wgsl {
21 namespace {
22
TEST_F(ParserImplTest,PrimaryExpression_Ident)23 TEST_F(ParserImplTest, PrimaryExpression_Ident) {
24 auto p = parser("a");
25 auto e = p->primary_expression();
26 EXPECT_TRUE(e.matched);
27 EXPECT_FALSE(e.errored);
28 EXPECT_FALSE(p->has_error()) << p->error();
29 ASSERT_NE(e.value, nullptr);
30 ASSERT_TRUE(e->Is<ast::IdentifierExpression>());
31 auto* ident = e->As<ast::IdentifierExpression>();
32 EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
33 }
34
TEST_F(ParserImplTest,PrimaryExpression_TypeDecl)35 TEST_F(ParserImplTest, PrimaryExpression_TypeDecl) {
36 auto p = parser("vec4<i32>(1, 2, 3, 4))");
37 auto e = p->primary_expression();
38 EXPECT_TRUE(e.matched);
39 EXPECT_FALSE(e.errored);
40 EXPECT_FALSE(p->has_error()) << p->error();
41 ASSERT_NE(e.value, nullptr);
42 ASSERT_TRUE(e->Is<ast::CallExpression>());
43 auto* call = e->As<ast::CallExpression>();
44
45 EXPECT_NE(call->target.type, nullptr);
46
47 ASSERT_EQ(call->args.size(), 4u);
48 const auto& val = call->args;
49 ASSERT_TRUE(val[0]->Is<ast::SintLiteralExpression>());
50 EXPECT_EQ(val[0]->As<ast::SintLiteralExpression>()->value, 1);
51
52 ASSERT_TRUE(val[1]->Is<ast::SintLiteralExpression>());
53 EXPECT_EQ(val[1]->As<ast::SintLiteralExpression>()->value, 2);
54
55 ASSERT_TRUE(val[2]->Is<ast::SintLiteralExpression>());
56 EXPECT_EQ(val[2]->As<ast::SintLiteralExpression>()->value, 3);
57
58 ASSERT_TRUE(val[3]->Is<ast::SintLiteralExpression>());
59 EXPECT_EQ(val[3]->As<ast::SintLiteralExpression>()->value, 4);
60 }
61
TEST_F(ParserImplTest,PrimaryExpression_TypeDecl_ZeroConstructor)62 TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_ZeroConstructor) {
63 auto p = parser("vec4<i32>()");
64 auto e = p->primary_expression();
65 EXPECT_TRUE(e.matched);
66 EXPECT_FALSE(e.errored);
67 EXPECT_FALSE(p->has_error()) << p->error();
68 ASSERT_NE(e.value, nullptr);
69
70 ASSERT_TRUE(e->Is<ast::CallExpression>());
71 auto* call = e->As<ast::CallExpression>();
72
73 ASSERT_EQ(call->args.size(), 0u);
74 }
75
TEST_F(ParserImplTest,PrimaryExpression_TypeDecl_InvalidTypeDecl)76 TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_InvalidTypeDecl) {
77 auto p = parser("vec4<if>(2., 3., 4., 5.)");
78 auto e = p->primary_expression();
79 EXPECT_FALSE(e.matched);
80 EXPECT_TRUE(e.errored);
81 EXPECT_EQ(e.value, nullptr);
82 ASSERT_TRUE(p->has_error());
83 EXPECT_EQ(p->error(), "1:6: invalid type for vector");
84 }
85
TEST_F(ParserImplTest,PrimaryExpression_TypeDecl_MissingLeftParen)86 TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_MissingLeftParen) {
87 auto p = parser("vec4<f32> 2., 3., 4., 5.)");
88 auto e = p->primary_expression();
89 EXPECT_FALSE(e.matched);
90 EXPECT_TRUE(e.errored);
91 EXPECT_EQ(e.value, nullptr);
92 ASSERT_TRUE(p->has_error());
93 EXPECT_EQ(p->error(), "1:11: expected '(' for type constructor");
94 }
95
TEST_F(ParserImplTest,PrimaryExpression_TypeDecl_MissingRightParen)96 TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_MissingRightParen) {
97 auto p = parser("vec4<f32>(2., 3., 4., 5.");
98 auto e = p->primary_expression();
99 EXPECT_FALSE(e.matched);
100 EXPECT_TRUE(e.errored);
101 EXPECT_EQ(e.value, nullptr);
102 ASSERT_TRUE(p->has_error());
103 EXPECT_EQ(p->error(), "1:25: expected ')' for type constructor");
104 }
105
TEST_F(ParserImplTest,PrimaryExpression_TypeDecl_InvalidValue)106 TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_InvalidValue) {
107 auto p = parser("i32(if(a) {})");
108 auto e = p->primary_expression();
109 EXPECT_FALSE(e.matched);
110 EXPECT_TRUE(e.errored);
111 EXPECT_EQ(e.value, nullptr);
112 ASSERT_TRUE(p->has_error());
113 EXPECT_EQ(p->error(), "1:5: expected ')' for type constructor");
114 }
115
TEST_F(ParserImplTest,PrimaryExpression_TypeDecl_StructConstructor_Empty)116 TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_StructConstructor_Empty) {
117 auto p = parser(R"(
118 struct S { a : i32; b : f32; };
119 S()
120 )");
121
122 p->expect_global_decl();
123 ASSERT_FALSE(p->has_error()) << p->error();
124
125 auto e = p->primary_expression();
126 EXPECT_TRUE(e.matched);
127 EXPECT_FALSE(e.errored);
128 EXPECT_FALSE(p->has_error()) << p->error();
129 ASSERT_NE(e.value, nullptr);
130
131 ASSERT_TRUE(e->Is<ast::CallExpression>());
132 auto* call = e->As<ast::CallExpression>();
133
134 ASSERT_NE(call->target.name, nullptr);
135 EXPECT_EQ(call->target.name->symbol, p->builder().Symbols().Get("S"));
136
137 ASSERT_EQ(call->args.size(), 0u);
138 }
139
TEST_F(ParserImplTest,PrimaryExpression_TypeDecl_StructConstructor_NotEmpty)140 TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_StructConstructor_NotEmpty) {
141 auto p = parser(R"(
142 struct S { a : i32; b : f32; };
143 S(1u, 2.0)
144 )");
145
146 p->expect_global_decl();
147 ASSERT_FALSE(p->has_error()) << p->error();
148
149 auto e = p->primary_expression();
150 EXPECT_TRUE(e.matched);
151 EXPECT_FALSE(e.errored);
152 EXPECT_FALSE(p->has_error()) << p->error();
153 ASSERT_NE(e.value, nullptr);
154
155 ASSERT_TRUE(e->Is<ast::CallExpression>());
156 auto* call = e->As<ast::CallExpression>();
157
158 ASSERT_NE(call->target.name, nullptr);
159 EXPECT_EQ(call->target.name->symbol, p->builder().Symbols().Get("S"));
160
161 ASSERT_EQ(call->args.size(), 2u);
162
163 ASSERT_TRUE(call->args[0]->Is<ast::UintLiteralExpression>());
164 EXPECT_EQ(call->args[0]->As<ast::UintLiteralExpression>()->value, 1u);
165
166 ASSERT_TRUE(call->args[1]->Is<ast::FloatLiteralExpression>());
167 EXPECT_EQ(call->args[1]->As<ast::FloatLiteralExpression>()->value, 2.f);
168 }
169
TEST_F(ParserImplTest,PrimaryExpression_ConstLiteral_True)170 TEST_F(ParserImplTest, PrimaryExpression_ConstLiteral_True) {
171 auto p = parser("true");
172 auto e = p->primary_expression();
173 EXPECT_TRUE(e.matched);
174 EXPECT_FALSE(e.errored);
175 EXPECT_FALSE(p->has_error()) << p->error();
176 ASSERT_NE(e.value, nullptr);
177 ASSERT_TRUE(e->Is<ast::BoolLiteralExpression>());
178 EXPECT_TRUE(e->As<ast::BoolLiteralExpression>()->value);
179 }
180
TEST_F(ParserImplTest,PrimaryExpression_ParenExpr)181 TEST_F(ParserImplTest, PrimaryExpression_ParenExpr) {
182 auto p = parser("(a == b)");
183 auto e = p->primary_expression();
184 EXPECT_TRUE(e.matched);
185 EXPECT_FALSE(e.errored);
186 EXPECT_FALSE(p->has_error()) << p->error();
187 ASSERT_NE(e.value, nullptr);
188 ASSERT_TRUE(e->Is<ast::BinaryExpression>());
189 }
190
TEST_F(ParserImplTest,PrimaryExpression_ParenExpr_MissingRightParen)191 TEST_F(ParserImplTest, PrimaryExpression_ParenExpr_MissingRightParen) {
192 auto p = parser("(a == b");
193 auto e = p->primary_expression();
194 EXPECT_FALSE(e.matched);
195 EXPECT_TRUE(e.errored);
196 EXPECT_EQ(e.value, nullptr);
197 ASSERT_TRUE(p->has_error());
198 EXPECT_EQ(p->error(), "1:8: expected ')'");
199 }
200
TEST_F(ParserImplTest,PrimaryExpression_ParenExpr_MissingExpr)201 TEST_F(ParserImplTest, PrimaryExpression_ParenExpr_MissingExpr) {
202 auto p = parser("()");
203 auto e = p->primary_expression();
204 EXPECT_FALSE(e.matched);
205 EXPECT_TRUE(e.errored);
206 EXPECT_EQ(e.value, nullptr);
207 ASSERT_TRUE(p->has_error());
208 EXPECT_EQ(p->error(), "1:2: unable to parse expression");
209 }
210
TEST_F(ParserImplTest,PrimaryExpression_ParenExpr_InvalidExpr)211 TEST_F(ParserImplTest, PrimaryExpression_ParenExpr_InvalidExpr) {
212 auto p = parser("(if (a) {})");
213 auto e = p->primary_expression();
214 EXPECT_FALSE(e.matched);
215 EXPECT_TRUE(e.errored);
216 EXPECT_EQ(e.value, nullptr);
217 ASSERT_TRUE(p->has_error());
218 EXPECT_EQ(p->error(), "1:2: unable to parse expression");
219 }
220
TEST_F(ParserImplTest,PrimaryExpression_Cast)221 TEST_F(ParserImplTest, PrimaryExpression_Cast) {
222 auto p = parser("f32(1)");
223
224 auto e = p->primary_expression();
225 EXPECT_TRUE(e.matched);
226 EXPECT_FALSE(e.errored);
227 EXPECT_FALSE(p->has_error()) << p->error();
228 ASSERT_NE(e.value, nullptr);
229
230 ASSERT_TRUE(e->Is<ast::CallExpression>());
231 auto* call = e->As<ast::CallExpression>();
232
233 ASSERT_TRUE(call->target.type->Is<ast::F32>());
234 ASSERT_EQ(call->args.size(), 1u);
235
236 ASSERT_TRUE(call->args[0]->Is<ast::IntLiteralExpression>());
237 }
238
TEST_F(ParserImplTest,PrimaryExpression_Bitcast)239 TEST_F(ParserImplTest, PrimaryExpression_Bitcast) {
240 auto p = parser("bitcast<f32>(1)");
241
242 auto e = p->primary_expression();
243 EXPECT_TRUE(e.matched);
244 EXPECT_FALSE(e.errored);
245 EXPECT_FALSE(p->has_error()) << p->error();
246 ASSERT_NE(e.value, nullptr);
247 ASSERT_TRUE(e->Is<ast::BitcastExpression>());
248
249 auto* c = e->As<ast::BitcastExpression>();
250 ASSERT_TRUE(c->type->Is<ast::F32>());
251 ASSERT_TRUE(c->expr->Is<ast::IntLiteralExpression>());
252 }
253
TEST_F(ParserImplTest,PrimaryExpression_Bitcast_MissingGreaterThan)254 TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingGreaterThan) {
255 auto p = parser("bitcast<f32(1)");
256 auto e = p->primary_expression();
257 EXPECT_FALSE(e.matched);
258 EXPECT_TRUE(e.errored);
259 EXPECT_EQ(e.value, nullptr);
260 ASSERT_TRUE(p->has_error());
261 EXPECT_EQ(p->error(), "1:12: expected '>' for bitcast expression");
262 }
263
TEST_F(ParserImplTest,PrimaryExpression_Bitcast_MissingType)264 TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingType) {
265 auto p = parser("bitcast<>(1)");
266 auto e = p->primary_expression();
267 EXPECT_FALSE(e.matched);
268 EXPECT_TRUE(e.errored);
269 EXPECT_EQ(e.value, nullptr);
270 ASSERT_TRUE(p->has_error());
271 EXPECT_EQ(p->error(), "1:9: invalid type for bitcast expression");
272 }
273
TEST_F(ParserImplTest,PrimaryExpression_Bitcast_MissingLeftParen)274 TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingLeftParen) {
275 auto p = parser("bitcast<f32>1)");
276 auto e = p->primary_expression();
277 EXPECT_FALSE(e.matched);
278 EXPECT_TRUE(e.errored);
279 EXPECT_EQ(e.value, nullptr);
280 ASSERT_TRUE(p->has_error());
281 EXPECT_EQ(p->error(), "1:13: expected '('");
282 }
283
TEST_F(ParserImplTest,PrimaryExpression_Bitcast_MissingRightParen)284 TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingRightParen) {
285 auto p = parser("bitcast<f32>(1");
286 auto e = p->primary_expression();
287 EXPECT_FALSE(e.matched);
288 EXPECT_TRUE(e.errored);
289 EXPECT_EQ(e.value, nullptr);
290 ASSERT_TRUE(p->has_error());
291 EXPECT_EQ(p->error(), "1:15: expected ')'");
292 }
293
TEST_F(ParserImplTest,PrimaryExpression_Bitcast_MissingExpression)294 TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingExpression) {
295 auto p = parser("bitcast<f32>()");
296 auto e = p->primary_expression();
297 EXPECT_FALSE(e.matched);
298 EXPECT_TRUE(e.errored);
299 EXPECT_EQ(e.value, nullptr);
300 ASSERT_TRUE(p->has_error());
301 EXPECT_EQ(p->error(), "1:14: unable to parse expression");
302 }
303
TEST_F(ParserImplTest,PrimaryExpression_bitcast_InvalidExpression)304 TEST_F(ParserImplTest, PrimaryExpression_bitcast_InvalidExpression) {
305 auto p = parser("bitcast<f32>(if (a) {})");
306 auto e = p->primary_expression();
307 EXPECT_FALSE(e.matched);
308 EXPECT_TRUE(e.errored);
309 EXPECT_EQ(e.value, nullptr);
310 ASSERT_TRUE(p->has_error());
311 EXPECT_EQ(p->error(), "1:14: unable to parse expression");
312 }
313
314 } // namespace
315 } // namespace wgsl
316 } // namespace reader
317 } // namespace tint
318