]> Cypherpunks.ru repositories - gostls13.git/blob - test/range.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / range.go
1 // run
2
3 // Copyright 2009 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.
8
9 package main
10
11 // test range over channels
12
13 func gen(c chan int, lo, hi int) {
14         for i := lo; i <= hi; i++ {
15                 c <- i
16         }
17         close(c)
18 }
19
20 func seq(lo, hi int) chan int {
21         c := make(chan int)
22         go gen(c, lo, hi)
23         return c
24 }
25
26 const alphabet = "abcdefghijklmnopqrstuvwxyz"
27
28 func testblankvars() {
29         n := 0
30         for range alphabet {
31                 n++
32         }
33         if n != 26 {
34                 println("for range: wrong count", n, "want 26")
35                 panic("fail")
36         }
37         n = 0
38         for _ = range alphabet {
39                 n++
40         }
41         if n != 26 {
42                 println("for _ = range: wrong count", n, "want 26")
43                 panic("fail")
44         }
45         n = 0
46         for _, _ = range alphabet {
47                 n++
48         }
49         if n != 26 {
50                 println("for _, _ = range: wrong count", n, "want 26")
51                 panic("fail")
52         }
53         s := 0
54         for i, _ := range alphabet {
55                 s += i
56         }
57         if s != 325 {
58                 println("for i, _ := range: wrong sum", s, "want 325")
59                 panic("fail")
60         }
61         r := rune(0)
62         for _, v := range alphabet {
63                 r += v
64         }
65         if r != 2847 {
66                 println("for _, v := range: wrong sum", r, "want 2847")
67                 panic("fail")
68         }
69 }
70
71 func testchan() {
72         s := ""
73         for i := range seq('a', 'z') {
74                 s += string(i)
75         }
76         if s != alphabet {
77                 println("Wanted lowercase alphabet; got", s)
78                 panic("fail")
79         }
80         n := 0
81         for range seq('a', 'z') {
82                 n++
83         }
84         if n != 26 {
85                 println("testchan wrong count", n, "want 26")
86                 panic("fail")
87         }
88 }
89
90 // test that range over slice only evaluates
91 // the expression after "range" once.
92
93 var nmake = 0
94
95 func makeslice() []int {
96         nmake++
97         return []int{1, 2, 3, 4, 5}
98 }
99
100 func testslice() {
101         s := 0
102         nmake = 0
103         for _, v := range makeslice() {
104                 s += v
105         }
106         if nmake != 1 {
107                 println("range called makeslice", nmake, "times")
108                 panic("fail")
109         }
110         if s != 15 {
111                 println("wrong sum ranging over makeslice", s)
112                 panic("fail")
113         }
114
115         x := []int{10, 20}
116         y := []int{99}
117         i := 1
118         for i, x[i] = range y {
119                 break
120         }
121         if i != 0 || x[0] != 10 || x[1] != 99 {
122                 println("wrong parallel assignment", i, x[0], x[1])
123                 panic("fail")
124         }
125 }
126
127 func testslice1() {
128         s := 0
129         nmake = 0
130         for i := range makeslice() {
131                 s += i
132         }
133         if nmake != 1 {
134                 println("range called makeslice", nmake, "times")
135                 panic("fail")
136         }
137         if s != 10 {
138                 println("wrong sum ranging over makeslice", s)
139                 panic("fail")
140         }
141 }
142
143 func testslice2() {
144         n := 0
145         nmake = 0
146         for range makeslice() {
147                 n++
148         }
149         if nmake != 1 {
150                 println("range called makeslice", nmake, "times")
151                 panic("fail")
152         }
153         if n != 5 {
154                 println("wrong count ranging over makeslice", n)
155                 panic("fail")
156         }
157 }
158
159 // test that range over []byte(string) only evaluates
160 // the expression after "range" once.
161
162 func makenumstring() string {
163         nmake++
164         return "\x01\x02\x03\x04\x05"
165 }
166
167 func testslice3() {
168         s := byte(0)
169         nmake = 0
170         for _, v := range []byte(makenumstring()) {
171                 s += v
172         }
173         if nmake != 1 {
174                 println("range called makenumstring", nmake, "times")
175                 panic("fail")
176         }
177         if s != 15 {
178                 println("wrong sum ranging over []byte(makenumstring)", s)
179                 panic("fail")
180         }
181 }
182
183 // test that range over array only evaluates
184 // the expression after "range" once.
185
186 func makearray() [5]int {
187         nmake++
188         return [5]int{1, 2, 3, 4, 5}
189 }
190
191 func testarray() {
192         s := 0
193         nmake = 0
194         for _, v := range makearray() {
195                 s += v
196         }
197         if nmake != 1 {
198                 println("range called makearray", nmake, "times")
199                 panic("fail")
200         }
201         if s != 15 {
202                 println("wrong sum ranging over makearray", s)
203                 panic("fail")
204         }
205 }
206
207 func testarray1() {
208         s := 0
209         nmake = 0
210         for i := range makearray() {
211                 s += i
212         }
213         if nmake != 1 {
214                 println("range called makearray", nmake, "times")
215                 panic("fail")
216         }
217         if s != 10 {
218                 println("wrong sum ranging over makearray", s)
219                 panic("fail")
220         }
221 }
222
223 func testarray2() {
224         n := 0
225         nmake = 0
226         for range makearray() {
227                 n++
228         }
229         if nmake != 1 {
230                 println("range called makearray", nmake, "times")
231                 panic("fail")
232         }
233         if n != 5 {
234                 println("wrong count ranging over makearray", n)
235                 panic("fail")
236         }
237 }
238
239 func makearrayptr() *[5]int {
240         nmake++
241         return &[5]int{1, 2, 3, 4, 5}
242 }
243
244 func testarrayptr() {
245         nmake = 0
246         x := len(makearrayptr())
247         if x != 5 || nmake != 1 {
248                 println("len called makearrayptr", nmake, "times and got len", x)
249                 panic("fail")
250         }
251         nmake = 0
252         x = cap(makearrayptr())
253         if x != 5 || nmake != 1 {
254                 println("cap called makearrayptr", nmake, "times and got len", x)
255                 panic("fail")
256         }
257         s := 0
258         nmake = 0
259         for _, v := range makearrayptr() {
260                 s += v
261         }
262         if nmake != 1 {
263                 println("range called makearrayptr", nmake, "times")
264                 panic("fail")
265         }
266         if s != 15 {
267                 println("wrong sum ranging over makearrayptr", s)
268                 panic("fail")
269         }
270 }
271
272 func testarrayptr1() {
273         s := 0
274         nmake = 0
275         for i := range makearrayptr() {
276                 s += i
277         }
278         if nmake != 1 {
279                 println("range called makearrayptr", nmake, "times")
280                 panic("fail")
281         }
282         if s != 10 {
283                 println("wrong sum ranging over makearrayptr", s)
284                 panic("fail")
285         }
286 }
287
288 func testarrayptr2() {
289         n := 0
290         nmake = 0
291         for range makearrayptr() {
292                 n++
293         }
294         if nmake != 1 {
295                 println("range called makearrayptr", nmake, "times")
296                 panic("fail")
297         }
298         if n != 5 {
299                 println("wrong count ranging over makearrayptr", n)
300                 panic("fail")
301         }
302 }
303
304 // test that range over string only evaluates
305 // the expression after "range" once.
306
307 func makestring() string {
308         nmake++
309         return "abcd☺"
310 }
311
312 func teststring() {
313         var s rune
314         nmake = 0
315         for _, v := range makestring() {
316                 s += v
317         }
318         if nmake != 1 {
319                 println("range called makestring", nmake, "times")
320                 panic("fail")
321         }
322         if s != 'a'+'b'+'c'+'d'+'☺' {
323                 println("wrong sum ranging over makestring", s)
324                 panic("fail")
325         }
326
327         x := []rune{'a', 'b'}
328         i := 1
329         for i, x[i] = range "c" {
330                 break
331         }
332         if i != 0 || x[0] != 'a' || x[1] != 'c' {
333                 println("wrong parallel assignment", i, x[0], x[1])
334                 panic("fail")
335         }
336
337         y := []int{1, 2, 3}
338         r := rune(1)
339         for y[r], r = range "\x02" {
340                 break
341         }
342         if r != 2 || y[0] != 1 || y[1] != 0 || y[2] != 3 {
343                 println("wrong parallel assignment", r, y[0], y[1], y[2])
344                 panic("fail")
345         }
346 }
347
348 func teststring1() {
349         s := 0
350         nmake = 0
351         for i := range makestring() {
352                 s += i
353         }
354         if nmake != 1 {
355                 println("range called makestring", nmake, "times")
356                 panic("fail")
357         }
358         if s != 10 {
359                 println("wrong sum ranging over makestring", s)
360                 panic("fail")
361         }
362 }
363
364 func teststring2() {
365         n := 0
366         nmake = 0
367         for range makestring() {
368                 n++
369         }
370         if nmake != 1 {
371                 println("range called makestring", nmake, "times")
372                 panic("fail")
373         }
374         if n != 5 {
375                 println("wrong count ranging over makestring", n)
376                 panic("fail")
377         }
378 }
379
380 // test that range over map only evaluates
381 // the expression after "range" once.
382
383 func makemap() map[int]int {
384         nmake++
385         return map[int]int{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: '☺'}
386 }
387
388 func testmap() {
389         s := 0
390         nmake = 0
391         for _, v := range makemap() {
392                 s += v
393         }
394         if nmake != 1 {
395                 println("range called makemap", nmake, "times")
396                 panic("fail")
397         }
398         if s != 'a'+'b'+'c'+'d'+'☺' {
399                 println("wrong sum ranging over makemap", s)
400                 panic("fail")
401         }
402 }
403
404 func testmap1() {
405         s := 0
406         nmake = 0
407         for i := range makemap() {
408                 s += i
409         }
410         if nmake != 1 {
411                 println("range called makemap", nmake, "times")
412                 panic("fail")
413         }
414         if s != 10 {
415                 println("wrong sum ranging over makemap", s)
416                 panic("fail")
417         }
418 }
419
420 func testmap2() {
421         n := 0
422         nmake = 0
423         for range makemap() {
424                 n++
425         }
426         if nmake != 1 {
427                 println("range called makemap", nmake, "times")
428                 panic("fail")
429         }
430         if n != 5 {
431                 println("wrong count ranging over makemap", n)
432                 panic("fail")
433         }
434 }
435
436 // test that range evaluates the index and value expressions
437 // exactly once per iteration.
438
439 var ncalls = 0
440
441 func getvar(p *int) *int {
442         ncalls++
443         return p
444 }
445
446 func testcalls() {
447         var i, v int
448         si := 0
449         sv := 0
450         for *getvar(&i), *getvar(&v) = range [2]int{1, 2} {
451                 si += i
452                 sv += v
453         }
454         if ncalls != 4 {
455                 println("wrong number of calls:", ncalls, "!= 4")
456                 panic("fail")
457         }
458         if si != 1 || sv != 3 {
459                 println("wrong sum in testcalls", si, sv)
460                 panic("fail")
461         }
462
463         ncalls = 0
464         for *getvar(&i), *getvar(&v) = range [0]int{} {
465                 println("loop ran on empty array")
466                 panic("fail")
467         }
468         if ncalls != 0 {
469                 println("wrong number of calls:", ncalls, "!= 0")
470                 panic("fail")
471         }
472 }
473
474 func main() {
475         testblankvars()
476         testchan()
477         testarray()
478         testarray1()
479         testarray2()
480         testarrayptr()
481         testarrayptr1()
482         testarrayptr2()
483         testslice()
484         testslice1()
485         testslice2()
486         testslice3()
487         teststring()
488         teststring1()
489         teststring2()
490         testmap()
491         testmap1()
492         testmap2()
493         testcalls()
494 }