This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix ext/B/t/f_map.t failure
[perl5.git] / ext / B / t / f_map.t
1 #!perl
2
3 BEGIN {
4     unshift @INC, 't';
5     require Config;
6     if (($Config::Config{'extensions'} !~ /\bB\b/) ){
7         print "1..0 # Skip -- Perl configured without B module\n";
8         exit 0;
9     }
10     if (!$Config::Config{useperlio}) {
11         print "1..0 # Skip -- need perlio to walk the optree\n";
12         exit 0;
13     }
14 }
15 use OptreeCheck;
16 plan tests => 18;
17
18
19 =head1 f_map.t
20
21 Code test snippets here are adapted from `perldoc -f map`
22
23 Due to a bleadperl optimization (Dave Mitchell, circa may 04), the
24 (map|grep)(start|while) opcodes have different flags in 5.9, their
25 private flags /1, /2 are gone in blead (for the cases covered)
26
27 When the optree stuff was integrated into 5.8.6, these tests failed,
28 and were todo'd.  They're now done, by version-specific tweaking in
29 mkCheckRex(), therefore the skip is removed too.
30
31 =for gentest
32
33 # chunk: #!perl
34 # examples shamelessly snatched from perldoc -f map
35
36 =cut
37
38 =for gentest
39
40 # chunk: # translates a list of numbers to the corresponding characters.
41 @chars = map(chr, @nums);
42
43 =cut
44
45 checkOptree(note   => q{},
46             bcopts => q{-exec},
47             code   => q{@chars = map(chr, @nums); },
48             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
49 # 1  <;> nextstate(main 475 (eval 10):1) v:%
50 # 2  <0> pushmark s
51 # 3  <0> pushmark s
52 # 4  <#> gv[*nums] s
53 # 5  <1> rv2av[t7] lKM/1
54 # 6  <@> mapstart lK
55 # 7  <|> mapwhile(other->8)[t8] lK
56 # 8      <#> gvsv[*_] s
57 # 9      <1> chr[t5] sK/1
58 #            goto 7
59 # a  <0> pushmark s
60 # b  <#> gv[*chars] s
61 # c  <1> rv2av[t2] lKRM*/1
62 # d  <2> aassign[t9] KS/COMMON
63 # e  <1> leavesub[1 ref] K/REFC,1
64 EOT_EOT
65 # 1  <;> nextstate(main 559 (eval 15):1) v:%
66 # 2  <0> pushmark s
67 # 3  <0> pushmark s
68 # 4  <$> gv(*nums) s
69 # 5  <1> rv2av[t4] lKM/1
70 # 6  <@> mapstart lK
71 # 7  <|> mapwhile(other->8)[t5] lK
72 # 8      <$> gvsv(*_) s
73 # 9      <1> chr[t3] sK/1
74 #            goto 7
75 # a  <0> pushmark s
76 # b  <$> gv(*chars) s
77 # c  <1> rv2av[t1] lKRM*/1
78 # d  <2> aassign[t6] KS/COMMON
79 # e  <1> leavesub[1 ref] K/REFC,1
80 EONT_EONT
81
82
83 =for gentest
84
85 # chunk: %hash = map { getkey($_) => $_ } @array;
86
87 =cut
88
89 checkOptree(note   => q{},
90             bcopts => q{-exec},
91             code   => q{%hash = map { getkey($_) => $_ } @array; },
92             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
93 # 1  <;> nextstate(main 476 (eval 10):1) v:%,{
94 # 2  <0> pushmark s
95 # 3  <0> pushmark s
96 # 4  <#> gv[*array] s
97 # 5  <1> rv2av[t8] lKM/1
98 # 6  <@> mapstart lK*
99 # 7  <|> mapwhile(other->8)[t9] lK
100 # 8      <0> enter l
101 # 9      <;> nextstate(main 475 (eval 10):1) v:%,{
102 # a      <0> pushmark s
103 # b      <0> pushmark s
104 # c      <#> gvsv[*_] s
105 # d      <#> gv[*getkey] s/EARLYCV
106 # e      <1> entersub[t5] lKS/TARG
107 # f      <#> gvsv[*_] s
108 # g      <@> list lK
109 # h      <@> leave lKP
110 #            goto 7
111 # i  <0> pushmark s
112 # j  <#> gv[*hash] s
113 # k  <1> rv2hv[t2] lKRM*/1
114 # l  <2> aassign[t10] KS/COMMON
115 # m  <1> leavesub[1 ref] K/REFC,1
116 EOT_EOT
117 # 1  <;> nextstate(main 560 (eval 15):1) v:%,{
118 # 2  <0> pushmark s
119 # 3  <0> pushmark s
120 # 4  <$> gv(*array) s
121 # 5  <1> rv2av[t3] lKM/1
122 # 6  <@> mapstart lK*
123 # 7  <|> mapwhile(other->8)[t4] lK
124 # 8      <0> enter l
125 # 9      <;> nextstate(main 559 (eval 15):1) v:%,{
126 # a      <0> pushmark s
127 # b      <0> pushmark s
128 # c      <$> gvsv(*_) s
129 # d      <$> gv(*getkey) s/EARLYCV
130 # e      <1> entersub[t2] lKS/TARG
131 # f      <$> gvsv(*_) s
132 # g      <@> list lK
133 # h      <@> leave lKP
134 #            goto 7
135 # i  <0> pushmark s
136 # j  <$> gv(*hash) s
137 # k  <1> rv2hv[t1] lKRM*/1
138 # l  <2> aassign[t5] KS/COMMON
139 # m  <1> leavesub[1 ref] K/REFC,1
140 EONT_EONT
141
142
143 =for gentest
144
145 # chunk: {
146     %hash = ();
147     foreach $_ (@array) {
148         $hash{getkey($_)} = $_;
149     }
150 }
151
152 =cut
153
154 checkOptree(note   => q{},
155             bcopts => q{-exec},
156             code   => q{{ %hash = (); foreach $_ (@array) { $hash{getkey($_)} = $_; } } },
157             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
158 # 1  <;> nextstate(main 478 (eval 10):1) v:%,{
159 # 2  <{> enterloop(next->u last->u redo->3) 
160 # 3  <;> nextstate(main 475 (eval 10):1) v:%
161 # 4  <0> pushmark s
162 # 5  <0> pushmark s
163 # 6  <#> gv[*hash] s
164 # 7  <1> rv2hv[t2] lKRM*/1
165 # 8  <2> aassign[t3] vKS
166 # 9  <;> nextstate(main 476 (eval 10):1) v:%,{
167 # a  <0> pushmark sM
168 # b  <#> gv[*array] s
169 # c  <1> rv2av[t6] sKRM/1
170 # d  <#> gv[*_] s
171 # e  <1> rv2gv sKRM/1
172 # f  <{> enteriter(next->q last->t redo->g) lKS/8
173 # r  <0> iter s
174 # s  <|> and(other->g) K/1
175 # g      <;> nextstate(main 475 (eval 10):1) v:%,{
176 # h      <#> gvsv[*_] s
177 # i      <#> gv[*hash] s
178 # j      <1> rv2hv sKR/1
179 # k      <0> pushmark s
180 # l      <#> gvsv[*_] s
181 # m      <#> gv[*getkey] s/EARLYCV
182 # n      <1> entersub[t10] sKS/TARG
183 # o      <2> helem sKRM*/2
184 # p      <2> sassign vKS/2
185 # q      <0> unstack s
186 #            goto r
187 # t  <2> leaveloop KP/2
188 # u  <2> leaveloop K/2
189 # v  <1> leavesub[1 ref] K/REFC,1
190 EOT_EOT
191 # 1  <;> nextstate(main 562 (eval 15):1) v:%,{
192 # 2  <{> enterloop(next->u last->u redo->3) 
193 # 3  <;> nextstate(main 559 (eval 15):1) v:%
194 # 4  <0> pushmark s
195 # 5  <0> pushmark s
196 # 6  <$> gv(*hash) s
197 # 7  <1> rv2hv[t1] lKRM*/1
198 # 8  <2> aassign[t2] vKS
199 # 9  <;> nextstate(main 560 (eval 15):1) v:%,{
200 # a  <0> pushmark sM
201 # b  <$> gv(*array) s
202 # c  <1> rv2av[t3] sKRM/1
203 # d  <$> gv(*_) s
204 # e  <1> rv2gv sKRM/1
205 # f  <{> enteriter(next->q last->t redo->g) lKS/8
206 # r  <0> iter s
207 # s  <|> and(other->g) K/1
208 # g      <;> nextstate(main 559 (eval 15):1) v:%,{
209 # h      <$> gvsv(*_) s
210 # i      <$> gv(*hash) s
211 # j      <1> rv2hv sKR/1
212 # k      <0> pushmark s
213 # l      <$> gvsv(*_) s
214 # m      <$> gv(*getkey) s/EARLYCV
215 # n      <1> entersub[t4] sKS/TARG
216 # o      <2> helem sKRM*/2
217 # p      <2> sassign vKS/2
218 # q      <0> unstack s
219 #            goto r
220 # t  <2> leaveloop KP/2
221 # u  <2> leaveloop K/2
222 # v  <1> leavesub[1 ref] K/REFC,1
223 EONT_EONT
224
225
226 =for gentest
227
228 # chunk: #%hash = map {  "\L$_", 1  } @array;  # perl guesses EXPR.  wrong
229 %hash = map { +"\L$_", 1  } @array;  # perl guesses BLOCK. right
230
231 =cut
232
233 checkOptree(note   => q{},
234             bcopts => q{-exec},
235             code   => q{%hash = map { +"\L$_", 1 } @array; },
236             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
237 # 1  <;> nextstate(main 476 (eval 10):1) v:%
238 # 2  <0> pushmark s
239 # 3  <0> pushmark s
240 # 4  <#> gv[*array] s
241 # 5  <1> rv2av[t7] lKM/1
242 # 6  <@> mapstart lK*
243 # 7  <|> mapwhile(other->8)[t9] lK
244 # 8      <0> pushmark s
245 # 9      <#> gvsv[*_] s
246 # a      <1> lc[t4] sK/1
247 # b      <@> stringify[t5] sK/1
248 # c      <$> const[IV 1] s
249 # d      <@> list lK
250 # -      <@> scope lK
251 #            goto 7
252 # e  <0> pushmark s
253 # f  <#> gv[*hash] s
254 # g  <1> rv2hv[t2] lKRM*/1
255 # h  <2> aassign[t10] KS/COMMON
256 # i  <1> leavesub[1 ref] K/REFC,1
257 EOT_EOT
258 # 1  <;> nextstate(main 560 (eval 15):1) v:%
259 # 2  <0> pushmark s
260 # 3  <0> pushmark s
261 # 4  <$> gv(*array) s
262 # 5  <1> rv2av[t4] lKM/1
263 # 6  <@> mapstart lK*
264 # 7  <|> mapwhile(other->8)[t5] lK
265 # 8      <0> pushmark s
266 # 9      <$> gvsv(*_) s
267 # a      <1> lc[t2] sK/1
268 # b      <@> stringify[t3] sK/1
269 # c      <$> const(IV 1) s
270 # d      <@> list lK
271 # -      <@> scope lK
272 #            goto 7
273 # e  <0> pushmark s
274 # f  <$> gv(*hash) s
275 # g  <1> rv2hv[t1] lKRM*/1
276 # h  <2> aassign[t6] KS/COMMON
277 # i  <1> leavesub[1 ref] K/REFC,1
278 EONT_EONT
279
280
281 =for gentest
282
283 # chunk: %hash = map { ("\L$_", 1) } @array;  # this also works
284
285 =cut
286
287 checkOptree(note   => q{},
288             bcopts => q{-exec},
289             code   => q{%hash = map { ("\L$_", 1) } @array; },
290             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
291 # 1  <;> nextstate(main 476 (eval 10):1) v:%
292 # 2  <0> pushmark s
293 # 3  <0> pushmark s
294 # 4  <#> gv[*array] s
295 # 5  <1> rv2av[t7] lKM/1
296 # 6  <@> mapstart lK*
297 # 7  <|> mapwhile(other->8)[t9] lK
298 # 8      <0> pushmark s
299 # 9      <#> gvsv[*_] s
300 # a      <1> lc[t4] sK/1
301 # b      <@> stringify[t5] sK/1
302 # c      <$> const[IV 1] s
303 # d      <@> list lKP
304 # -      <@> scope lK
305 #            goto 7
306 # e  <0> pushmark s
307 # f  <#> gv[*hash] s
308 # g  <1> rv2hv[t2] lKRM*/1
309 # h  <2> aassign[t10] KS/COMMON
310 # i  <1> leavesub[1 ref] K/REFC,1
311 EOT_EOT
312 # 1  <;> nextstate(main 560 (eval 15):1) v:%
313 # 2  <0> pushmark s
314 # 3  <0> pushmark s
315 # 4  <$> gv(*array) s
316 # 5  <1> rv2av[t4] lKM/1
317 # 6  <@> mapstart lK*
318 # 7  <|> mapwhile(other->8)[t5] lK
319 # 8      <0> pushmark s
320 # 9      <$> gvsv(*_) s
321 # a      <1> lc[t2] sK/1
322 # b      <@> stringify[t3] sK/1
323 # c      <$> const(IV 1) s
324 # d      <@> list lKP
325 # -      <@> scope lK
326 #            goto 7
327 # e  <0> pushmark s
328 # f  <$> gv(*hash) s
329 # g  <1> rv2hv[t1] lKRM*/1
330 # h  <2> aassign[t6] KS/COMMON
331 # i  <1> leavesub[1 ref] K/REFC,1
332 EONT_EONT
333
334
335 =for gentest
336
337 # chunk: %hash = map {  lc($_), 1  } @array;  # as does this.
338
339 =cut
340
341 checkOptree(note   => q{},
342             bcopts => q{-exec},
343             code   => q{%hash = map { lc($_), 1 } @array; },
344             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
345 # 1  <;> nextstate(main 476 (eval 10):1) v:%
346 # 2  <0> pushmark s
347 # 3  <0> pushmark s
348 # 4  <#> gv[*array] s
349 # 5  <1> rv2av[t6] lKM/1
350 # 6  <@> mapstart lK*
351 # 7  <|> mapwhile(other->8)[t8] lK
352 # 8      <0> pushmark s
353 # 9      <#> gvsv[*_] s
354 # a      <1> lc[t4] sK/1
355 # b      <$> const[IV 1] s
356 # c      <@> list lK
357 # -      <@> scope lK
358 #            goto 7
359 # d  <0> pushmark s
360 # e  <#> gv[*hash] s
361 # f  <1> rv2hv[t2] lKRM*/1
362 # g  <2> aassign[t9] KS/COMMON
363 # h  <1> leavesub[1 ref] K/REFC,1
364 EOT_EOT
365 # 1  <;> nextstate(main 589 (eval 26):1) v:%
366 # 2  <0> pushmark s
367 # 3  <0> pushmark s
368 # 4  <$> gv(*array) s
369 # 5  <1> rv2av[t3] lKM/1
370 # 6  <@> mapstart lK*
371 # 7  <|> mapwhile(other->8)[t4] lK
372 # 8      <0> pushmark s
373 # 9      <$> gvsv(*_) s
374 # a      <1> lc[t2] sK/1
375 # b      <$> const(IV 1) s
376 # c      <@> list lK
377 # -      <@> scope lK
378 #            goto 7
379 # d  <0> pushmark s
380 # e  <$> gv(*hash) s
381 # f  <1> rv2hv[t1] lKRM*/1
382 # g  <2> aassign[t5] KS/COMMON
383 # h  <1> leavesub[1 ref] K/REFC,1
384 EONT_EONT
385
386
387 =for gentest
388
389 # chunk: %hash = map +( lc($_), 1 ), @array;  # this is EXPR and works!
390
391 =cut
392
393 checkOptree(note   => q{},
394             bcopts => q{-exec},
395             code   => q{%hash = map +( lc($_), 1 ), @array; },
396             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
397 # 1  <;> nextstate(main 475 (eval 10):1) v:%
398 # 2  <0> pushmark s
399 # 3  <0> pushmark s
400 # 4  <#> gv[*array] s
401 # 5  <1> rv2av[t6] lKM/1
402 # 6  <@> mapstart lK
403 # 7  <|> mapwhile(other->8)[t7] lK
404 # 8      <0> pushmark s
405 # 9      <#> gvsv[*_] s
406 # a      <1> lc[t4] sK/1
407 # b      <$> const[IV 1] s
408 # c      <@> list lKP
409 #            goto 7
410 # d  <0> pushmark s
411 # e  <#> gv[*hash] s
412 # f  <1> rv2hv[t2] lKRM*/1
413 # g  <2> aassign[t8] KS/COMMON
414 # h  <1> leavesub[1 ref] K/REFC,1
415 EOT_EOT
416 # 1  <;> nextstate(main 593 (eval 28):1) v:%
417 # 2  <0> pushmark s
418 # 3  <0> pushmark s
419 # 4  <$> gv(*array) s
420 # 5  <1> rv2av[t3] lKM/1
421 # 6  <@> mapstart lK
422 # 7  <|> mapwhile(other->8)[t4] lK
423 # 8      <0> pushmark s
424 # 9      <$> gvsv(*_) s
425 # a      <1> lc[t2] sK/1
426 # b      <$> const(IV 1) s
427 # c      <@> list lKP
428 #            goto 7
429 # d  <0> pushmark s
430 # e  <$> gv(*hash) s
431 # f  <1> rv2hv[t1] lKRM*/1
432 # g  <2> aassign[t5] KS/COMMON
433 # h  <1> leavesub[1 ref] K/REFC,1
434 EONT_EONT
435
436
437 =for gentest
438
439 # chunk: %hash = map  ( lc($_), 1 ), @array;  # evaluates to (1, @array)
440
441 =cut
442
443 checkOptree(note   => q{},
444             bcopts => q{-exec},
445             code   => q{%hash = map ( lc($_), 1 ), @array; },
446             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
447 # 1  <;> nextstate(main 475 (eval 10):1) v:%
448 # 2  <0> pushmark s
449 # 3  <0> pushmark s
450 # 4  <0> pushmark s
451 # 5  <$> const[IV 1] sM
452 # 6  <@> mapstart lK
453 # 7  <|> mapwhile(other->8)[t5] lK
454 # 8      <#> gvsv[*_] s
455 # 9      <1> lc[t4] sK/1
456 #            goto 7
457 # a  <0> pushmark s
458 # b  <#> gv[*hash] s
459 # c  <1> rv2hv[t2] lKRM*/1
460 # d  <2> aassign[t6] KS/COMMON
461 # e  <#> gv[*array] s
462 # f  <1> rv2av[t8] K/1
463 # g  <@> list K
464 # h  <1> leavesub[1 ref] K/REFC,1
465 EOT_EOT
466 # 1  <;> nextstate(main 597 (eval 30):1) v:%
467 # 2  <0> pushmark s
468 # 3  <0> pushmark s
469 # 4  <0> pushmark s
470 # 5  <$> const(IV 1) sM
471 # 6  <@> mapstart lK
472 # 7  <|> mapwhile(other->8)[t3] lK
473 # 8      <$> gvsv(*_) s
474 # 9      <1> lc[t2] sK/1
475 #            goto 7
476 # a  <0> pushmark s
477 # b  <$> gv(*hash) s
478 # c  <1> rv2hv[t1] lKRM*/1
479 # d  <2> aassign[t4] KS/COMMON
480 # e  <$> gv(*array) s
481 # f  <1> rv2av[t5] K/1
482 # g  <@> list K
483 # h  <1> leavesub[1 ref] K/REFC,1
484 EONT_EONT
485
486
487 =for gentest
488
489 # chunk: @hashes = map +{ lc($_), 1 }, @array # EXPR, so needs , at end
490
491 =cut
492
493 checkOptree(note   => q{},
494             bcopts => q{-exec},
495             code   => q{@hashes = map +{ lc($_), 1 }, @array },
496             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
497 # 1  <;> nextstate(main 475 (eval 10):1) v:%
498 # 2  <0> pushmark s
499 # 3  <0> pushmark s
500 # 4  <#> gv[*array] s
501 # 5  <1> rv2av[t6] lKM/1
502 # 6  <@> mapstart lK
503 # 7  <|> mapwhile(other->8)[t7] lK
504 # 8      <0> pushmark s
505 # 9      <#> gvsv[*_] s
506 # a      <1> lc[t4] sK/1
507 # b      <$> const[IV 1] s
508 # c      <@> anonhash sK*/1
509 #            goto 7
510 # d  <0> pushmark s
511 # e  <#> gv[*hashes] s
512 # f  <1> rv2av[t2] lKRM*/1
513 # g  <2> aassign[t8] KS/COMMON
514 # h  <1> leavesub[1 ref] K/REFC,1
515 EOT_EOT
516 # 1  <;> nextstate(main 601 (eval 32):1) v:%
517 # 2  <0> pushmark s
518 # 3  <0> pushmark s
519 # 4  <$> gv(*array) s
520 # 5  <1> rv2av[t3] lKM/1
521 # 6  <@> mapstart lK
522 # 7  <|> mapwhile(other->8)[t4] lK
523 # 8      <0> pushmark s
524 # 9      <$> gvsv(*_) s
525 # a      <1> lc[t2] sK/1
526 # b      <$> const(IV 1) s
527 # c      <@> anonhash sK*/1
528 #            goto 7
529 # d  <0> pushmark s
530 # e  <$> gv(*hashes) s
531 # f  <1> rv2av[t1] lKRM*/1
532 # g  <2> aassign[t5] KS/COMMON
533 # h  <1> leavesub[1 ref] K/REFC,1
534 EONT_EONT