]> Cypherpunks.ru repositories - gostls13.git/blob - test/range4.go
561b3b58b1e5f0b2937f0a33239c9432c1bc59a2
[gostls13.git] / test / range4.go
1 // run -goexperiment range
2
3 // Copyright 2023 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 // Test the 'for range' construct ranging over functions.
8
9 package main
10
11 var gj int
12
13 func yield4x(yield func() bool) {
14         _ = yield() && yield() && yield() && yield()
15 }
16
17 func yield4(yield func(int) bool) {
18         _ = yield(1) && yield(2) && yield(3) && yield(4)
19 }
20
21 func yield3(yield func(int) bool) {
22         _ = yield(1) && yield(2) && yield(3)
23 }
24
25 func yield2(yield func(int) bool) {
26         _ = yield(1) && yield(2)
27 }
28
29 func testfunc0() {
30         j := 0
31         for range yield4x {
32                 j++
33         }
34         if j != 4 {
35                 println("wrong count ranging over yield4x:", j)
36                 panic("testfunc0")
37         }
38
39         j = 0
40         for _ = range yield4 {
41                 j++
42         }
43         if j != 4 {
44                 println("wrong count ranging over yield4:", j)
45                 panic("testfunc0")
46         }
47 }
48
49 func testfunc1() {
50         bad := false
51         j := 1
52         for i := range yield4 {
53                 if i != j {
54                         println("range var", i, "want", j)
55                         bad = true
56                 }
57                 j++
58         }
59         if j != 5 {
60                 println("wrong count ranging over f:", j)
61                 bad = true
62         }
63         if bad {
64                 panic("testfunc1")
65         }
66 }
67
68 func testfunc2() {
69         bad := false
70         j := 1
71         var i int
72         for i = range yield4 {
73                 if i != j {
74                         println("range var", i, "want", j)
75                         bad = true
76                 }
77                 j++
78         }
79         if j != 5 {
80                 println("wrong count ranging over f:", j)
81                 bad = true
82         }
83         if i != 4 {
84                 println("wrong final i ranging over f:", i)
85                 bad = true
86         }
87         if bad {
88                 panic("testfunc2")
89         }
90 }
91
92 func testfunc3() {
93         bad := false
94         j := 1
95         var i int
96         for i = range yield4 {
97                 if i != j {
98                         println("range var", i, "want", j)
99                         bad = true
100                 }
101                 j++
102                 if i == 2 {
103                         break
104                 }
105                 continue
106         }
107         if j != 3 {
108                 println("wrong count ranging over f:", j)
109                 bad = true
110         }
111         if i != 2 {
112                 println("wrong final i ranging over f:", i)
113                 bad = true
114         }
115         if bad {
116                 panic("testfunc3")
117         }
118 }
119
120 func testfunc4() {
121         bad := false
122         j := 1
123         var i int
124         func() {
125                 for i = range yield4 {
126                         if i != j {
127                                 println("range var", i, "want", j)
128                                 bad = true
129                         }
130                         j++
131                         if i == 2 {
132                                 return
133                         }
134                 }
135         }()
136         if j != 3 {
137                 println("wrong count ranging over f:", j)
138                 bad = true
139         }
140         if i != 2 {
141                 println("wrong final i ranging over f:", i)
142                 bad = true
143         }
144         if bad {
145                 panic("testfunc3")
146         }
147 }
148
149 func func5() (int, int) {
150         for i := range yield4 {
151                 return 10, i
152         }
153         panic("still here")
154 }
155
156 func testfunc5() {
157         x, y := func5()
158         if x != 10 || y != 1 {
159                 println("wrong results", x, y, "want", 10, 1)
160                 panic("testfunc5")
161         }
162 }
163
164 func func6() (z, w int) {
165         for i := range yield4 {
166                 z = 10
167                 w = i
168                 return
169         }
170         panic("still here")
171 }
172
173 func testfunc6() {
174         x, y := func6()
175         if x != 10 || y != 1 {
176                 println("wrong results", x, y, "want", 10, 1)
177                 panic("testfunc6")
178         }
179 }
180
181 var saved []int
182
183 func save(x int) {
184         saved = append(saved, x)
185 }
186
187 func printslice(s []int) {
188         print("[")
189         for i, x := range s {
190                 if i > 0 {
191                         print(", ")
192                 }
193                 print(x)
194         }
195         print("]")
196 }
197
198 func eqslice(s, t []int) bool {
199         if len(s) != len(t) {
200                 return false
201         }
202         for i, x := range s {
203                 if x != t[i] {
204                         return false
205                 }
206         }
207         return true
208 }
209
210 func func7() {
211         defer save(-1)
212         for i := range yield4 {
213                 defer save(i)
214         }
215         defer save(5)
216 }
217
218 func checkslice(name string, saved, want []int) {
219         if !eqslice(saved, want) {
220                 print("wrong results ")
221                 printslice(saved)
222                 print(" want ")
223                 printslice(want)
224                 print("\n")
225                 panic(name)
226         }
227 }
228
229 func testfunc7() {
230         saved = nil
231         func7()
232         want := []int{5, 4, 3, 2, 1, -1}
233         checkslice("testfunc7", saved, want)
234 }
235
236 func func8() {
237         defer save(-1)
238         for i := range yield2 {
239                 for j := range yield3 {
240                         defer save(i*10 + j)
241                 }
242                 defer save(i)
243         }
244         defer save(-2)
245         for i := range yield4 {
246                 defer save(i)
247         }
248         defer save(-3)
249 }
250
251 func testfunc8() {
252         saved = nil
253         func8()
254         want := []int{-3, 4, 3, 2, 1, -2, 2, 23, 22, 21, 1, 13, 12, 11, -1}
255         checkslice("testfunc8", saved, want)
256 }
257
258 func func9() {
259         n := 0
260         for _ = range yield2 {
261                 for _ = range yield3 {
262                         n++
263                         defer save(n)
264                 }
265         }
266 }
267
268 func testfunc9() {
269         saved = nil
270         func9()
271         want := []int{6, 5, 4, 3, 2, 1}
272         checkslice("testfunc9", saved, want)
273 }
274
275 // test that range evaluates the index and value expressions
276 // exactly once per iteration.
277
278 var ncalls = 0
279
280 func getvar(p *int) *int {
281         ncalls++
282         return p
283 }
284
285 func iter2(list ...int) func(func(int, int) bool) {
286         return func(yield func(int, int) bool) {
287                 for i, x := range list {
288                         if !yield(i, x) {
289                                 return
290                         }
291                 }
292         }
293 }
294
295 func testcalls() {
296         var i, v int
297         ncalls = 0
298         si := 0
299         sv := 0
300         for *getvar(&i), *getvar(&v) = range iter2(1, 2) {
301                 si += i
302                 sv += v
303         }
304         if ncalls != 4 {
305                 println("wrong number of calls:", ncalls, "!= 4")
306                 panic("fail")
307         }
308         if si != 1 || sv != 3 {
309                 println("wrong sum in testcalls", si, sv)
310                 panic("fail")
311         }
312 }
313
314 func main() {
315         testfunc0()
316         testfunc1()
317         testfunc2()
318         testfunc3()
319         testfunc4()
320         testfunc5()
321         testfunc6()
322         testfunc7()
323         testfunc8()
324         testfunc9()
325         testcalls()
326 }