This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Simplify ck_grep
[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 #            goto 7
251 # e  <0> pushmark s
252 # f  <#> gv[*hash] s
253 # g  <1> rv2hv[t2] lKRM*/1
254 # h  <2> aassign[t10] KS/COMMON
255 # i  <1> leavesub[1 ref] K/REFC,1
256 EOT_EOT
257 # 1  <;> nextstate(main 560 (eval 15):1) v
258 # 2  <0> pushmark s
259 # 3  <0> pushmark s
260 # 4  <$> gv(*array) s
261 # 5  <1> rv2av[t4] lKM/1
262 # 6  <@> mapstart lK
263 # 7  <|> mapwhile(other->8)[t5] lK
264 # 8      <0> pushmark s
265 # 9      <$> gvsv(*_) s
266 # a      <1> lc[t2] sK/1
267 # b      <@> stringify[t3] sK/1
268 # c      <$> const(IV 1) s
269 # d      <@> list lK
270 #            goto 7
271 # e  <0> pushmark s
272 # f  <$> gv(*hash) s
273 # g  <1> rv2hv[t1] lKRM*/1
274 # h  <2> aassign[t6] KS/COMMON
275 # i  <1> leavesub[1 ref] K/REFC,1
276 EONT_EONT
277
278
279 =for gentest
280
281 # chunk: %hash = map { ("\L$_", 1) } @array;  # this also works
282
283 =cut
284
285 checkOptree(note   => q{},
286             bcopts => q{-exec},
287             code   => q{%hash = map { ("\L$_", 1) } @array; },
288             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
289 # 1  <;> nextstate(main 476 (eval 10):1) v
290 # 2  <0> pushmark s
291 # 3  <0> pushmark s
292 # 4  <#> gv[*array] s
293 # 5  <1> rv2av[t7] lKM/1
294 # 6  <@> mapstart lK
295 # 7  <|> mapwhile(other->8)[t9] lK
296 # 8      <0> pushmark s
297 # 9      <#> gvsv[*_] s
298 # a      <1> lc[t4] sK/1
299 # b      <@> stringify[t5] sK/1
300 # c      <$> const[IV 1] s
301 # d      <@> list lKP
302 #            goto 7
303 # e  <0> pushmark s
304 # f  <#> gv[*hash] s
305 # g  <1> rv2hv[t2] lKRM*/1
306 # h  <2> aassign[t10] KS/COMMON
307 # i  <1> leavesub[1 ref] K/REFC,1
308 EOT_EOT
309 # 1  <;> nextstate(main 560 (eval 15):1) v
310 # 2  <0> pushmark s
311 # 3  <0> pushmark s
312 # 4  <$> gv(*array) s
313 # 5  <1> rv2av[t4] lKM/1
314 # 6  <@> mapstart lK
315 # 7  <|> mapwhile(other->8)[t5] lK
316 # 8      <0> pushmark s
317 # 9      <$> gvsv(*_) s
318 # a      <1> lc[t2] sK/1
319 # b      <@> stringify[t3] sK/1
320 # c      <$> const(IV 1) s
321 # d      <@> list lKP
322 #            goto 7
323 # e  <0> pushmark s
324 # f  <$> gv(*hash) s
325 # g  <1> rv2hv[t1] lKRM*/1
326 # h  <2> aassign[t6] KS/COMMON
327 # i  <1> leavesub[1 ref] K/REFC,1
328 EONT_EONT
329
330
331 =for gentest
332
333 # chunk: %hash = map {  lc($_), 1  } @array;  # as does this.
334
335 =cut
336
337 checkOptree(note   => q{},
338             bcopts => q{-exec},
339             code   => q{%hash = map { lc($_), 1 } @array; },
340             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
341 # 1  <;> nextstate(main 476 (eval 10):1) v
342 # 2  <0> pushmark s
343 # 3  <0> pushmark s
344 # 4  <#> gv[*array] s
345 # 5  <1> rv2av[t6] lKM/1
346 # 6  <@> mapstart lK
347 # 7  <|> mapwhile(other->8)[t8] lK
348 # 8      <0> pushmark s
349 # 9      <#> gvsv[*_] s
350 # a      <1> lc[t4] sK/1
351 # b      <$> const[IV 1] s
352 # c      <@> list lK
353 #            goto 7
354 # d  <0> pushmark s
355 # e  <#> gv[*hash] s
356 # f  <1> rv2hv[t2] lKRM*/1
357 # g  <2> aassign[t9] KS/COMMON
358 # h  <1> leavesub[1 ref] K/REFC,1
359 EOT_EOT
360 # 1  <;> nextstate(main 589 (eval 26):1) v
361 # 2  <0> pushmark s
362 # 3  <0> pushmark s
363 # 4  <$> gv(*array) s
364 # 5  <1> rv2av[t3] lKM/1
365 # 6  <@> mapstart lK
366 # 7  <|> mapwhile(other->8)[t4] lK
367 # 8      <0> pushmark s
368 # 9      <$> gvsv(*_) s
369 # a      <1> lc[t2] sK/1
370 # b      <$> const(IV 1) s
371 # c      <@> list lK
372 #            goto 7
373 # d  <0> pushmark s
374 # e  <$> gv(*hash) s
375 # f  <1> rv2hv[t1] lKRM*/1
376 # g  <2> aassign[t5] KS/COMMON
377 # h  <1> leavesub[1 ref] K/REFC,1
378 EONT_EONT
379
380
381 =for gentest
382
383 # chunk: %hash = map +( lc($_), 1 ), @array;  # this is EXPR and works!
384
385 =cut
386
387 checkOptree(note   => q{},
388             bcopts => q{-exec},
389             code   => q{%hash = map +( lc($_), 1 ), @array; },
390             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
391 # 1  <;> nextstate(main 475 (eval 10):1) v
392 # 2  <0> pushmark s
393 # 3  <0> pushmark s
394 # 4  <#> gv[*array] s
395 # 5  <1> rv2av[t6] lKM/1
396 # 6  <@> mapstart lK
397 # 7  <|> mapwhile(other->8)[t7] lK
398 # 8      <0> pushmark s
399 # 9      <#> gvsv[*_] s
400 # a      <1> lc[t4] sK/1
401 # b      <$> const[IV 1] s
402 # c      <@> list lKP
403 #            goto 7
404 # d  <0> pushmark s
405 # e  <#> gv[*hash] s
406 # f  <1> rv2hv[t2] lKRM*/1
407 # g  <2> aassign[t8] KS/COMMON
408 # h  <1> leavesub[1 ref] K/REFC,1
409 EOT_EOT
410 # 1  <;> nextstate(main 593 (eval 28):1) v
411 # 2  <0> pushmark s
412 # 3  <0> pushmark s
413 # 4  <$> gv(*array) s
414 # 5  <1> rv2av[t3] lKM/1
415 # 6  <@> mapstart lK
416 # 7  <|> mapwhile(other->8)[t4] lK
417 # 8      <0> pushmark s
418 # 9      <$> gvsv(*_) s
419 # a      <1> lc[t2] sK/1
420 # b      <$> const(IV 1) s
421 # c      <@> list lKP
422 #            goto 7
423 # d  <0> pushmark s
424 # e  <$> gv(*hash) s
425 # f  <1> rv2hv[t1] lKRM*/1
426 # g  <2> aassign[t5] KS/COMMON
427 # h  <1> leavesub[1 ref] K/REFC,1
428 EONT_EONT
429
430
431 =for gentest
432
433 # chunk: %hash = map  ( lc($_), 1 ), @array;  # evaluates to (1, @array)
434
435 =cut
436
437 checkOptree(note   => q{},
438             bcopts => q{-exec},
439             code   => q{%hash = map ( lc($_), 1 ), @array; },
440             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
441 # 1  <;> nextstate(main 475 (eval 10):1) v
442 # 2  <0> pushmark s
443 # 3  <0> pushmark s
444 # 4  <0> pushmark s
445 # 5  <$> const[IV 1] sM
446 # 6  <@> mapstart lK
447 # 7  <|> mapwhile(other->8)[t5] lK
448 # 8      <#> gvsv[*_] s
449 # 9      <1> lc[t4] sK/1
450 #            goto 7
451 # a  <0> pushmark s
452 # b  <#> gv[*hash] s
453 # c  <1> rv2hv[t2] lKRM*/1
454 # d  <2> aassign[t6] KS/COMMON
455 # e  <#> gv[*array] s
456 # f  <1> rv2av[t8] K/1
457 # g  <@> list K
458 # h  <1> leavesub[1 ref] K/REFC,1
459 EOT_EOT
460 # 1  <;> nextstate(main 597 (eval 30):1) v
461 # 2  <0> pushmark s
462 # 3  <0> pushmark s
463 # 4  <0> pushmark s
464 # 5  <$> const(IV 1) sM
465 # 6  <@> mapstart lK
466 # 7  <|> mapwhile(other->8)[t3] lK
467 # 8      <$> gvsv(*_) s
468 # 9      <1> lc[t2] sK/1
469 #            goto 7
470 # a  <0> pushmark s
471 # b  <$> gv(*hash) s
472 # c  <1> rv2hv[t1] lKRM*/1
473 # d  <2> aassign[t4] KS/COMMON
474 # e  <$> gv(*array) s
475 # f  <1> rv2av[t5] K/1
476 # g  <@> list K
477 # h  <1> leavesub[1 ref] K/REFC,1
478 EONT_EONT
479
480
481 =for gentest
482
483 # chunk: @hashes = map +{ lc($_), 1 }, @array # EXPR, so needs , at end
484
485 =cut
486
487 checkOptree(note   => q{},
488             bcopts => q{-exec},
489             code   => q{@hashes = map +{ lc($_), 1 }, @array },
490             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
491 # 1  <;> nextstate(main 475 (eval 10):1) v
492 # 2  <0> pushmark s
493 # 3  <0> pushmark s
494 # 4  <#> gv[*array] s
495 # 5  <1> rv2av[t6] lKM/1
496 # 6  <@> mapstart lK
497 # 7  <|> mapwhile(other->8)[t7] lK
498 # 8      <0> pushmark s
499 # 9      <#> gvsv[*_] s
500 # a      <1> lc[t4] sK/1
501 # b      <$> const[IV 1] s
502 # c      <@> anonhash sK*/1
503 #            goto 7
504 # d  <0> pushmark s
505 # e  <#> gv[*hashes] s
506 # f  <1> rv2av[t2] lKRM*/1
507 # g  <2> aassign[t8] KS/COMMON
508 # h  <1> leavesub[1 ref] K/REFC,1
509 EOT_EOT
510 # 1  <;> nextstate(main 601 (eval 32):1) v
511 # 2  <0> pushmark s
512 # 3  <0> pushmark s
513 # 4  <$> gv(*array) s
514 # 5  <1> rv2av[t3] lKM/1
515 # 6  <@> mapstart lK
516 # 7  <|> mapwhile(other->8)[t4] lK
517 # 8      <0> pushmark s
518 # 9      <$> gvsv(*_) s
519 # a      <1> lc[t2] sK/1
520 # b      <$> const(IV 1) s
521 # c      <@> anonhash sK*/1
522 #            goto 7
523 # d  <0> pushmark s
524 # e  <$> gv(*hashes) s
525 # f  <1> rv2av[t1] lKRM*/1
526 # g  <2> aassign[t5] KS/COMMON
527 # h  <1> leavesub[1 ref] K/REFC,1
528 EONT_EONT