• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 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/transform/for_loop_to_loop.h"
16 
17 #include "src/transform/test_helper.h"
18 
19 namespace tint {
20 namespace transform {
21 namespace {
22 
23 using ForLoopToLoopTest = TransformTest;
24 
TEST_F(ForLoopToLoopTest,EmptyModule)25 TEST_F(ForLoopToLoopTest, EmptyModule) {
26   auto* src = "";
27   auto* expect = src;
28 
29   auto got = Run<ForLoopToLoop>(src);
30 
31   EXPECT_EQ(expect, str(got));
32 }
33 
34 // Test an empty for loop.
TEST_F(ForLoopToLoopTest,Empty)35 TEST_F(ForLoopToLoopTest, Empty) {
36   auto* src = R"(
37 fn f() {
38   for (;;) {
39   }
40 }
41 )";
42 
43   auto* expect = R"(
44 fn f() {
45   loop {
46   }
47 }
48 )";
49 
50   auto got = Run<ForLoopToLoop>(src);
51 
52   EXPECT_EQ(expect, str(got));
53 }
54 
55 // Test a for loop with non-empty body.
TEST_F(ForLoopToLoopTest,Body)56 TEST_F(ForLoopToLoopTest, Body) {
57   auto* src = R"(
58 fn f() {
59   for (;;) {
60     discard;
61   }
62 }
63 )";
64 
65   auto* expect = R"(
66 fn f() {
67   loop {
68     discard;
69   }
70 }
71 )";
72 
73   auto got = Run<ForLoopToLoop>(src);
74 
75   EXPECT_EQ(expect, str(got));
76 }
77 
78 // Test a for loop declaring a variable in the initializer statement.
TEST_F(ForLoopToLoopTest,InitializerStatementDecl)79 TEST_F(ForLoopToLoopTest, InitializerStatementDecl) {
80   auto* src = R"(
81 fn f() {
82   for (var i: i32;;) {
83 
84   }
85 }
86 )";
87 
88   auto* expect = R"(
89 fn f() {
90   {
91     var i : i32;
92     loop {
93     }
94   }
95 }
96 )";
97 
98   auto got = Run<ForLoopToLoop>(src);
99 
100   EXPECT_EQ(expect, str(got));
101 }
102 
103 // Test a for loop declaring and initializing a variable in the initializer
104 // statement.
TEST_F(ForLoopToLoopTest,InitializerStatementDeclEqual)105 TEST_F(ForLoopToLoopTest, InitializerStatementDeclEqual) {
106   auto* src = R"(
107 fn f() {
108   for (var i: i32 = 0;;) {
109   }
110 }
111 )";
112 
113   auto* expect = R"(
114 fn f() {
115   {
116     var i : i32 = 0;
117     loop {
118     }
119   }
120 }
121 )";
122 
123   auto got = Run<ForLoopToLoop>(src);
124 
125   EXPECT_EQ(expect, str(got));
126 }
127 
128 // Test a for loop declaring a const variable in the initializer statement.
TEST_F(ForLoopToLoopTest,InitializerStatementConstDecl)129 TEST_F(ForLoopToLoopTest, InitializerStatementConstDecl) {
130   auto* src = R"(
131 fn f() {
132   for (let i: i32 = 0;;) {
133   }
134 }
135 )";
136 
137   auto* expect = R"(
138 fn f() {
139   {
140     let i : i32 = 0;
141     loop {
142     }
143   }
144 }
145 )";
146 
147   auto got = Run<ForLoopToLoop>(src);
148 
149   EXPECT_EQ(expect, str(got));
150 }
151 
152 // Test a for loop assigning a variable in the initializer statement.
TEST_F(ForLoopToLoopTest,InitializerStatementAssignment)153 TEST_F(ForLoopToLoopTest, InitializerStatementAssignment) {
154   auto* src = R"(
155 fn f() {
156   var i: i32;
157   for (i = 0;;) {
158 
159   }
160 }
161 )";
162 
163   auto* expect = R"(
164 fn f() {
165   var i : i32;
166   {
167     i = 0;
168     loop {
169     }
170   }
171 }
172 )";
173 
174   auto got = Run<ForLoopToLoop>(src);
175 
176   EXPECT_EQ(expect, str(got));
177 }
178 
179 // Test a for loop calling a function in the initializer statement.
TEST_F(ForLoopToLoopTest,InitializerStatementFuncCall)180 TEST_F(ForLoopToLoopTest, InitializerStatementFuncCall) {
181   auto* src = R"(
182 fn a(x : i32, y : i32) {
183 }
184 
185 fn f() {
186   var b : i32;
187   var c : i32;
188   for (a(b,c);;) { }
189 }
190 )";
191 
192   auto* expect = R"(
193 fn a(x : i32, y : i32) {
194 }
195 
196 fn f() {
197   var b : i32;
198   var c : i32;
199   {
200     a(b, c);
201     loop {
202     }
203   }
204 }
205 )";
206 
207   auto got = Run<ForLoopToLoop>(src);
208 
209   EXPECT_EQ(expect, str(got));
210 }
211 
212 // Test a for loop with a break condition
TEST_F(ForLoopToLoopTest,BreakCondition)213 TEST_F(ForLoopToLoopTest, BreakCondition) {
214   auto* src = R"(
215 fn f() {
216   for (; 0 == 1;) {
217   }
218 }
219 )";
220 
221   auto* expect = R"(
222 fn f() {
223   loop {
224     if (!((0 == 1))) {
225       break;
226     }
227   }
228 }
229 )";
230 
231   auto got = Run<ForLoopToLoop>(src);
232 
233   EXPECT_EQ(expect, str(got));
234 }
235 
236 // Test a for loop assigning a variable in the continuing statement.
TEST_F(ForLoopToLoopTest,ContinuingAssignment)237 TEST_F(ForLoopToLoopTest, ContinuingAssignment) {
238   auto* src = R"(
239 fn f() {
240   var x: i32;
241   for (;;x = 2) {
242   }
243 }
244 )";
245 
246   auto* expect = R"(
247 fn f() {
248   var x : i32;
249   loop {
250 
251     continuing {
252       x = 2;
253     }
254   }
255 }
256 )";
257 
258   auto got = Run<ForLoopToLoop>(src);
259 
260   EXPECT_EQ(expect, str(got));
261 }
262 
263 // Test a for loop calling a function in the continuing statement.
TEST_F(ForLoopToLoopTest,ContinuingFuncCall)264 TEST_F(ForLoopToLoopTest, ContinuingFuncCall) {
265   auto* src = R"(
266 fn a(x : i32, y : i32) {
267 }
268 
269 fn f() {
270   var b : i32;
271   var c : i32;
272   for (;;a(b,c)) {
273   }
274 }
275 )";
276 
277   auto* expect = R"(
278 fn a(x : i32, y : i32) {
279 }
280 
281 fn f() {
282   var b : i32;
283   var c : i32;
284   loop {
285 
286     continuing {
287       a(b, c);
288     }
289   }
290 }
291 )";
292 
293   auto got = Run<ForLoopToLoop>(src);
294 
295   EXPECT_EQ(expect, str(got));
296 }
297 
298 // Test a for loop with all statements non-empty.
TEST_F(ForLoopToLoopTest,All)299 TEST_F(ForLoopToLoopTest, All) {
300   auto* src = R"(
301 fn f() {
302   var a : i32;
303   for(var i : i32 = 0; i < 4; i = i + 1) {
304     if (a == 0) {
305       continue;
306     }
307     a = a + 2;
308   }
309 }
310 )";
311 
312   auto* expect = R"(
313 fn f() {
314   var a : i32;
315   {
316     var i : i32 = 0;
317     loop {
318       if (!((i < 4))) {
319         break;
320       }
321       if ((a == 0)) {
322         continue;
323       }
324       a = (a + 2);
325 
326       continuing {
327         i = (i + 1);
328       }
329     }
330   }
331 }
332 )";
333 
334   auto got = Run<ForLoopToLoop>(src);
335 
336   EXPECT_EQ(expect, str(got));
337 }
338 
339 }  // namespace
340 }  // namespace transform
341 }  // namespace tint
342