• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/reader/wgsl/parser_impl_test_helper.h"
16 
17 namespace tint {
18 namespace reader {
19 namespace wgsl {
20 namespace {
21 
TEST_F(ParserImplTest,ConstExpr_TypeDecl)22 TEST_F(ParserImplTest, ConstExpr_TypeDecl) {
23   auto p = parser("vec2<f32>(1., 2.)");
24   auto e = p->expect_const_expr();
25   ASSERT_FALSE(p->has_error()) << p->error();
26   ASSERT_FALSE(e.errored);
27   ASSERT_TRUE(e->Is<ast::CallExpression>());
28 
29   auto* t = e->As<ast::CallExpression>();
30   ASSERT_TRUE(t->target.type->Is<ast::Vector>());
31   EXPECT_EQ(t->target.type->As<ast::Vector>()->width, 2u);
32 
33   ASSERT_EQ(t->args.size(), 2u);
34 
35   ASSERT_TRUE(t->args[0]->Is<ast::FloatLiteralExpression>());
36   EXPECT_FLOAT_EQ(t->args[0]->As<ast::FloatLiteralExpression>()->value, 1.);
37 
38   ASSERT_TRUE(t->args[1]->Is<ast::FloatLiteralExpression>());
39   EXPECT_FLOAT_EQ(t->args[1]->As<ast::FloatLiteralExpression>()->value, 2.);
40 }
41 
TEST_F(ParserImplTest,ConstExpr_TypeDecl_Empty)42 TEST_F(ParserImplTest, ConstExpr_TypeDecl_Empty) {
43   auto p = parser("vec2<f32>()");
44   auto e = p->expect_const_expr();
45   ASSERT_FALSE(p->has_error()) << p->error();
46   ASSERT_FALSE(e.errored);
47   ASSERT_TRUE(e->Is<ast::CallExpression>());
48 
49   auto* t = e->As<ast::CallExpression>();
50   ASSERT_TRUE(t->target.type->Is<ast::Vector>());
51   EXPECT_EQ(t->target.type->As<ast::Vector>()->width, 2u);
52 
53   ASSERT_EQ(t->args.size(), 0u);
54 }
55 
TEST_F(ParserImplTest,ConstExpr_TypeDecl_TrailingComma)56 TEST_F(ParserImplTest, ConstExpr_TypeDecl_TrailingComma) {
57   auto p = parser("vec2<f32>(1., 2.,)");
58   auto e = p->expect_const_expr();
59   ASSERT_FALSE(p->has_error()) << p->error();
60   ASSERT_FALSE(e.errored);
61   ASSERT_TRUE(e->Is<ast::CallExpression>());
62 
63   auto* t = e->As<ast::CallExpression>();
64   ASSERT_TRUE(t->target.type->Is<ast::Vector>());
65   EXPECT_EQ(t->target.type->As<ast::Vector>()->width, 2u);
66 
67   ASSERT_EQ(t->args.size(), 2u);
68   ASSERT_TRUE(t->args[0]->Is<ast::LiteralExpression>());
69   ASSERT_TRUE(t->args[1]->Is<ast::LiteralExpression>());
70 }
71 
TEST_F(ParserImplTest,ConstExpr_TypeDecl_MissingRightParen)72 TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingRightParen) {
73   auto p = parser("vec2<f32>(1., 2.");
74   auto e = p->expect_const_expr();
75   ASSERT_TRUE(p->has_error());
76   ASSERT_TRUE(e.errored);
77   ASSERT_EQ(e.value, nullptr);
78   EXPECT_EQ(p->error(), "1:17: expected ')' for type constructor");
79 }
80 
TEST_F(ParserImplTest,ConstExpr_TypeDecl_MissingLeftParen)81 TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingLeftParen) {
82   auto p = parser("vec2<f32> 1., 2.)");
83   auto e = p->expect_const_expr();
84   ASSERT_TRUE(p->has_error());
85   ASSERT_TRUE(e.errored);
86   ASSERT_EQ(e.value, nullptr);
87   EXPECT_EQ(p->error(), "1:11: expected '(' for type constructor");
88 }
89 
TEST_F(ParserImplTest,ConstExpr_TypeDecl_MissingComma)90 TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingComma) {
91   auto p = parser("vec2<f32>(1. 2.");
92   auto e = p->expect_const_expr();
93   ASSERT_TRUE(p->has_error());
94   ASSERT_TRUE(e.errored);
95   ASSERT_EQ(e.value, nullptr);
96   EXPECT_EQ(p->error(), "1:14: expected ')' for type constructor");
97 }
98 
TEST_F(ParserImplTest,ConstExpr_InvalidExpr)99 TEST_F(ParserImplTest, ConstExpr_InvalidExpr) {
100   auto p = parser("vec2<f32>(1., if(a) {})");
101   auto e = p->expect_const_expr();
102   ASSERT_TRUE(p->has_error());
103   ASSERT_TRUE(e.errored);
104   ASSERT_EQ(e.value, nullptr);
105   EXPECT_EQ(p->error(), "1:15: invalid type for const_expr");
106 }
107 
TEST_F(ParserImplTest,ConstExpr_ConstLiteral)108 TEST_F(ParserImplTest, ConstExpr_ConstLiteral) {
109   auto p = parser("true");
110   auto e = p->expect_const_expr();
111   ASSERT_FALSE(p->has_error()) << p->error();
112   ASSERT_FALSE(e.errored);
113   ASSERT_NE(e.value, nullptr);
114   ASSERT_TRUE(e.value->Is<ast::BoolLiteralExpression>());
115   EXPECT_TRUE(e.value->As<ast::BoolLiteralExpression>()->value);
116 }
117 
TEST_F(ParserImplTest,ConstExpr_ConstLiteral_Invalid)118 TEST_F(ParserImplTest, ConstExpr_ConstLiteral_Invalid) {
119   auto p = parser("invalid");
120   auto e = p->expect_const_expr();
121   ASSERT_TRUE(p->has_error());
122   ASSERT_TRUE(e.errored);
123   ASSERT_EQ(e.value, nullptr);
124   EXPECT_EQ(p->error(), "1:1: unable to parse const_expr");
125 }
126 
TEST_F(ParserImplTest,ConstExpr_TypeConstructor)127 TEST_F(ParserImplTest, ConstExpr_TypeConstructor) {
128   auto p = parser("S(0)");
129 
130   auto e = p->expect_const_expr();
131   ASSERT_FALSE(e.errored);
132   ASSERT_TRUE(e->Is<ast::CallExpression>());
133   ASSERT_NE(e->As<ast::CallExpression>()->target.type, nullptr);
134   ASSERT_TRUE(e->As<ast::CallExpression>()->target.type->Is<ast::TypeName>());
135   EXPECT_EQ(
136       e->As<ast::CallExpression>()->target.type->As<ast::TypeName>()->name,
137       p->builder().Symbols().Get("S"));
138 }
139 
TEST_F(ParserImplTest,ConstExpr_Recursion)140 TEST_F(ParserImplTest, ConstExpr_Recursion) {
141   std::stringstream out;
142   for (size_t i = 0; i < 200; i++) {
143     out << "f32(";
144   }
145   out << "1.0";
146   for (size_t i = 0; i < 200; i++) {
147     out << ")";
148   }
149   auto p = parser(out.str());
150   auto e = p->expect_const_expr();
151   ASSERT_TRUE(p->has_error());
152   ASSERT_TRUE(e.errored);
153   ASSERT_EQ(e.value, nullptr);
154   EXPECT_EQ(p->error(), "1:517: maximum parser recursive depth reached");
155 }
156 
TEST_F(ParserImplTest,UnaryOp_Recursion)157 TEST_F(ParserImplTest, UnaryOp_Recursion) {
158   std::stringstream out;
159   for (size_t i = 0; i < 200; i++) {
160     out << "!";
161   }
162   out << "1.0";
163   auto p = parser(out.str());
164   auto e = p->unary_expression();
165   ASSERT_TRUE(p->has_error());
166   ASSERT_TRUE(e.errored);
167   ASSERT_EQ(e.value, nullptr);
168   EXPECT_EQ(p->error(), "1:130: maximum parser recursive depth reached");
169 }
170 
171 }  // namespace
172 }  // namespace wgsl
173 }  // namespace reader
174 }  // namespace tint
175