This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #46947] Parse method-BLOCK arguments as a term
[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*              < 5.017002
99 # 6  <@> mapstart lK               >=5.017002
100 # 7  <|> mapwhile(other->8)[t9] lK
101 # 8      <0> enter l
102 # 9      <;> nextstate(main 475 (eval 10):1) v:{
103 # a      <0> pushmark s
104 # b      <#> gvsv[*_] s
105 # c      <#> gv[*getkey] s/EARLYCV
106 # d      <1> entersub[t5] lKS/TARG
107 # e      <#> gvsv[*_] s
108 # f      <@> leave lKP
109 #            goto 7
110 # g  <0> pushmark s
111 # h  <#> gv[*hash] s
112 # i  <1> rv2hv[t2] lKRM*/1         < 5.019006
113 # i  <1> rv2hv lKRM*/1             >=5.019006
114 # j  <2> aassign[t10] KS/COMMON
115 # k  <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*              < 5.017002
123 # 6  <@> mapstart lK               >=5.017002
124 # 7  <|> mapwhile(other->8)[t4] lK
125 # 8      <0> enter l
126 # 9      <;> nextstate(main 559 (eval 15):1) v:{
127 # a      <0> pushmark s
128 # b      <$> gvsv(*_) s
129 # c      <$> gv(*getkey) s/EARLYCV
130 # d      <1> entersub[t2] lKS/TARG
131 # e      <$> gvsv(*_) s
132 # f      <@> leave lKP
133 #            goto 7
134 # g  <0> pushmark s
135 # h  <$> gv(*hash) s
136 # i  <1> rv2hv[t1] lKRM*/1         < 5.019006
137 # i  <1> rv2hv lKRM*/1             >=5.019006
138 # j  <2> aassign[t5] KS/COMMON
139 # k  <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         < 5.019006
165 # 7  <1> rv2hv lKRM*/1             >=5.019006
166 # 8  <2> aassign[t3] vKS
167 # 9  <;> nextstate(main 476 (eval 10):1) v:{
168 # a  <0> pushmark sM
169 # b  <#> gv[*array] s
170 # c  <1> rv2av[t6] sKRM/1
171 # d  <#> gv[*_] s
172 # e  <1> rv2gv sKRM/1
173 # f  <{> enteriter(next->q last->t redo->g) lKS/8
174 # r  <0> iter s
175 # s  <|> and(other->g) K/1
176 # g      <;> nextstate(main 475 (eval 10):1) v:{
177 # h      <#> gvsv[*_] s
178 # i      <#> gv[*hash] s
179 # j      <1> rv2hv sKR/1
180 # k      <0> pushmark s
181 # l      <#> gvsv[*_] s
182 # m      <#> gv[*getkey] s/EARLYCV
183 # n      <1> entersub[t10] sKS/TARG
184 # o      <2> helem sKRM*/2
185 # p      <2> sassign vKS/2
186 # q      <0> unstack s
187 #            goto r
188 # t  <2> leaveloop KP/2
189 # u  <2> leaveloop K/2
190 # v  <1> leavesub[1 ref] K/REFC,1
191 EOT_EOT
192 # 1  <;> nextstate(main 562 (eval 15):1) v:{
193 # 2  <{> enterloop(next->u last->u redo->3) 
194 # 3  <;> nextstate(main 559 (eval 15):1) v
195 # 4  <0> pushmark s
196 # 5  <0> pushmark s
197 # 6  <$> gv(*hash) s
198 # 7  <1> rv2hv[t1] lKRM*/1         < 5.019006
199 # 7  <1> rv2hv lKRM*/1             >=5.019006
200 # 8  <2> aassign[t2] vKS
201 # 9  <;> nextstate(main 560 (eval 15):1) v:{
202 # a  <0> pushmark sM
203 # b  <$> gv(*array) s
204 # c  <1> rv2av[t3] sKRM/1
205 # d  <$> gv(*_) s
206 # e  <1> rv2gv sKRM/1
207 # f  <{> enteriter(next->q last->t redo->g) lKS/8
208 # r  <0> iter s
209 # s  <|> and(other->g) K/1
210 # g      <;> nextstate(main 559 (eval 15):1) v:{
211 # h      <$> gvsv(*_) s
212 # i      <$> gv(*hash) s
213 # j      <1> rv2hv sKR/1
214 # k      <0> pushmark s
215 # l      <$> gvsv(*_) s
216 # m      <$> gv(*getkey) s/EARLYCV
217 # n      <1> entersub[t4] sKS/TARG
218 # o      <2> helem sKRM*/2
219 # p      <2> sassign vKS/2
220 # q      <0> unstack s
221 #            goto r
222 # t  <2> leaveloop KP/2
223 # u  <2> leaveloop K/2
224 # v  <1> leavesub[1 ref] K/REFC,1
225 EONT_EONT
226
227
228 =for gentest
229
230 # chunk: #%hash = map {  "\L$_", 1  } @array;  # perl guesses EXPR.  wrong
231 %hash = map { +"\L$_", 1  } @array;  # perl guesses BLOCK. right
232
233 =cut
234
235 checkOptree(note   => q{},
236             bcopts => q{-exec},
237             code   => q{%hash = map { +"\L$_", 1 } @array; },
238             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
239 # 1  <;> nextstate(main 476 (eval 10):1) v
240 # 2  <0> pushmark s
241 # 3  <0> pushmark s
242 # 4  <#> gv[*array] s
243 # 5  <1> rv2av[t7] lKM/1
244 # 6  <@> mapstart lK*              < 5.017002
245 # 6  <@> mapstart lK               >=5.017002
246 # 7  <|> mapwhile(other->8)[t9] lK
247 # 8      <0> pushmark s
248 # 9      <#> gvsv[*_] s
249 # a      <1> lc[t4] sK/1
250 # b      <@> stringify[t5] sK/1
251 # c      <$> const[IV 1] s
252 # d      <@> list lK
253 # -      <@> scope lK              < 5.017002
254 #            goto 7
255 # e  <0> pushmark s
256 # f  <#> gv[*hash] s
257 # g  <1> rv2hv[t2] lKRM*/1         < 5.019006
258 # g  <1> rv2hv lKRM*/1             >=5.019006
259 # h  <2> aassign[t10] KS/COMMON
260 # i  <1> leavesub[1 ref] K/REFC,1
261 EOT_EOT
262 # 1  <;> nextstate(main 560 (eval 15):1) v
263 # 2  <0> pushmark s
264 # 3  <0> pushmark s
265 # 4  <$> gv(*array) s
266 # 5  <1> rv2av[t4] lKM/1
267 # 6  <@> mapstart lK*              < 5.017002
268 # 6  <@> mapstart lK               >=5.017002
269 # 7  <|> mapwhile(other->8)[t5] lK
270 # 8      <0> pushmark s
271 # 9      <$> gvsv(*_) s
272 # a      <1> lc[t2] sK/1
273 # b      <@> stringify[t3] sK/1
274 # c      <$> const(IV 1) s
275 # d      <@> list lK
276 # -      <@> scope lK              < 5.017002
277 #            goto 7
278 # e  <0> pushmark s
279 # f  <$> gv(*hash) s
280 # g  <1> rv2hv[t1] lKRM*/1         < 5.019006
281 # g  <1> rv2hv lKRM*/1             >=5.019006
282 # h  <2> aassign[t6] KS/COMMON
283 # i  <1> leavesub[1 ref] K/REFC,1
284 EONT_EONT
285
286
287 =for gentest
288
289 # chunk: %hash = map { ("\L$_", 1) } @array;  # this also works
290
291 =cut
292
293 checkOptree(note   => q{},
294             bcopts => q{-exec},
295             code   => q{%hash = map { ("\L$_", 1) } @array; },
296             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
297 # 1  <;> nextstate(main 476 (eval 10):1) v
298 # 2  <0> pushmark s
299 # 3  <0> pushmark s
300 # 4  <#> gv[*array] s
301 # 5  <1> rv2av[t7] lKM/1
302 # 6  <@> mapstart lK*              < 5.017002
303 # 6  <@> mapstart lK               >=5.017002
304 # 7  <|> mapwhile(other->8)[t9] lK
305 # 8      <0> pushmark s
306 # 9      <#> gvsv[*_] s
307 # a      <1> lc[t4] sK/1
308 # b      <@> stringify[t5] sK/1
309 # c      <$> const[IV 1] s
310 # d      <@> list lKP
311 # -      <@> scope lK              < 5.017002
312 #            goto 7
313 # e  <0> pushmark s
314 # f  <#> gv[*hash] s
315 # g  <1> rv2hv[t2] lKRM*/1         < 5.019006
316 # g  <1> rv2hv lKRM*/1             >=5.019006
317 # h  <2> aassign[t10] KS/COMMON
318 # i  <1> leavesub[1 ref] K/REFC,1
319 EOT_EOT
320 # 1  <;> nextstate(main 560 (eval 15):1) v
321 # 2  <0> pushmark s
322 # 3  <0> pushmark s
323 # 4  <$> gv(*array) s
324 # 5  <1> rv2av[t4] lKM/1
325 # 6  <@> mapstart lK*              < 5.017002
326 # 6  <@> mapstart lK               >=5.017002
327 # 7  <|> mapwhile(other->8)[t5] lK
328 # 8      <0> pushmark s
329 # 9      <$> gvsv(*_) s
330 # a      <1> lc[t2] sK/1
331 # b      <@> stringify[t3] sK/1
332 # c      <$> const(IV 1) s
333 # d      <@> list lKP
334 # -      <@> scope lK              < 5.017002
335 #            goto 7
336 # e  <0> pushmark s
337 # f  <$> gv(*hash) s
338 # g  <1> rv2hv[t1] lKRM*/1         < 5.019006
339 # g  <1> rv2hv lKRM*/1             >=5.019006
340 # h  <2> aassign[t6] KS/COMMON
341 # i  <1> leavesub[1 ref] K/REFC,1
342 EONT_EONT
343
344
345 =for gentest
346
347 # chunk: %hash = map {  lc($_), 1  } @array;  # as does this.
348
349 =cut
350
351 checkOptree(note   => q{},
352             bcopts => q{-exec},
353             code   => q{%hash = map { lc($_), 1 } @array; },
354             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
355 # 1  <;> nextstate(main 476 (eval 10):1) v
356 # 2  <0> pushmark s
357 # 3  <0> pushmark s
358 # 4  <#> gv[*array] s
359 # 5  <1> rv2av[t6] lKM/1
360 # 6  <@> mapstart lK*              < 5.017002
361 # 6  <@> mapstart lK               >=5.017002
362 # 7  <|> mapwhile(other->8)[t8] lK
363 # 8      <0> pushmark s
364 # 9      <#> gvsv[*_] s
365 # a      <1> lc[t4] sK/1
366 # b      <$> const[IV 1] s
367 # c      <@> list lK
368 # -      <@> scope lK              < 5.017002
369 #            goto 7
370 # d  <0> pushmark s
371 # e  <#> gv[*hash] s
372 # f  <1> rv2hv[t2] lKRM*/1         < 5.019006
373 # f  <1> rv2hv lKRM*/1             >=5.019006
374 # g  <2> aassign[t9] KS/COMMON
375 # h  <1> leavesub[1 ref] K/REFC,1
376 EOT_EOT
377 # 1  <;> nextstate(main 589 (eval 26):1) v
378 # 2  <0> pushmark s
379 # 3  <0> pushmark s
380 # 4  <$> gv(*array) s
381 # 5  <1> rv2av[t3] lKM/1
382 # 6  <@> mapstart lK*              < 5.017002
383 # 6  <@> mapstart lK               >=5.017002
384 # 7  <|> mapwhile(other->8)[t4] lK
385 # 8      <0> pushmark s
386 # 9      <$> gvsv(*_) s
387 # a      <1> lc[t2] sK/1
388 # b      <$> const(IV 1) s
389 # c      <@> list lK
390 # -      <@> scope lK              < 5.017002
391 #            goto 7
392 # d  <0> pushmark s
393 # e  <$> gv(*hash) s
394 # f  <1> rv2hv[t1] lKRM*/1         < 5.019006
395 # f  <1> rv2hv lKRM*/1             >=5.019006
396 # g  <2> aassign[t5] KS/COMMON
397 # h  <1> leavesub[1 ref] K/REFC,1
398 EONT_EONT
399
400
401 =for gentest
402
403 # chunk: %hash = map +( lc($_), 1 ), @array;  # this is EXPR and works!
404
405 =cut
406
407 checkOptree(note   => q{},
408             bcopts => q{-exec},
409             code   => q{%hash = map +( lc($_), 1 ), @array; },
410             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
411 # 1  <;> nextstate(main 475 (eval 10):1) v
412 # 2  <0> pushmark s
413 # 3  <0> pushmark s
414 # 4  <#> gv[*array] s
415 # 5  <1> rv2av[t6] lKM/1
416 # 6  <@> mapstart lK
417 # 7  <|> mapwhile(other->8)[t7] lK
418 # 8      <0> pushmark s
419 # 9      <#> gvsv[*_] s
420 # a      <1> lc[t4] sK/1
421 # b      <$> const[IV 1] s
422 # c      <@> list lKP
423 #            goto 7
424 # d  <0> pushmark s
425 # e  <#> gv[*hash] s
426 # f  <1> rv2hv[t2] lKRM*/1         < 5.019006
427 # f  <1> rv2hv lKRM*/1             >=5.019006
428 # g  <2> aassign[t8] KS/COMMON
429 # h  <1> leavesub[1 ref] K/REFC,1
430 EOT_EOT
431 # 1  <;> nextstate(main 593 (eval 28):1) v
432 # 2  <0> pushmark s
433 # 3  <0> pushmark s
434 # 4  <$> gv(*array) s
435 # 5  <1> rv2av[t3] lKM/1
436 # 6  <@> mapstart lK
437 # 7  <|> mapwhile(other->8)[t4] lK
438 # 8      <0> pushmark s
439 # 9      <$> gvsv(*_) s
440 # a      <1> lc[t2] sK/1
441 # b      <$> const(IV 1) s
442 # c      <@> list lKP
443 #            goto 7
444 # d  <0> pushmark s
445 # e  <$> gv(*hash) s
446 # f  <1> rv2hv[t1] lKRM*/1         < 5.019006
447 # f  <1> rv2hv lKRM*/1             >=5.019006
448 # g  <2> aassign[t5] KS/COMMON
449 # h  <1> leavesub[1 ref] K/REFC,1
450 EONT_EONT
451
452
453 =for gentest
454
455 # chunk: %hash = map  ( lc($_), 1 ), @array;  # evaluates to (1, @array)
456
457 =cut
458
459 checkOptree(note   => q{},
460             bcopts => q{-exec},
461             code   => q{%hash = map ( lc($_), 1 ), @array; },
462             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
463 # 1  <;> nextstate(main 475 (eval 10):1) v
464 # 2  <0> pushmark s
465 # 3  <0> pushmark s
466 # 4  <0> pushmark s
467 # 5  <$> const[IV 1] sM
468 # 6  <@> mapstart lK
469 # 7  <|> mapwhile(other->8)[t5] lK
470 # 8      <#> gvsv[*_] s
471 # 9      <1> lc[t4] sK/1
472 #            goto 7
473 # a  <0> pushmark s
474 # b  <#> gv[*hash] s
475 # c  <1> rv2hv[t2] lKRM*/1         < 5.019006
476 # c  <1> rv2hv lKRM*/1             >=5.019006
477 # d  <2> aassign[t6] KS/COMMON
478 # e  <#> gv[*array] s
479 # f  <1> rv2av[t8] K/1
480 # g  <@> list K
481 # h  <1> leavesub[1 ref] K/REFC,1
482 EOT_EOT
483 # 1  <;> nextstate(main 597 (eval 30):1) v
484 # 2  <0> pushmark s
485 # 3  <0> pushmark s
486 # 4  <0> pushmark s
487 # 5  <$> const(IV 1) sM
488 # 6  <@> mapstart lK
489 # 7  <|> mapwhile(other->8)[t3] lK
490 # 8      <$> gvsv(*_) s
491 # 9      <1> lc[t2] sK/1
492 #            goto 7
493 # a  <0> pushmark s
494 # b  <$> gv(*hash) s
495 # c  <1> rv2hv[t1] lKRM*/1         < 5.019006
496 # c  <1> rv2hv lKRM*/1             >=5.019006
497 # d  <2> aassign[t4] KS/COMMON
498 # e  <$> gv(*array) s
499 # f  <1> rv2av[t5] K/1
500 # g  <@> list K
501 # h  <1> leavesub[1 ref] K/REFC,1
502 EONT_EONT
503
504
505 =for gentest
506
507 # chunk: @hashes = map +{ lc($_), 1 }, @array # EXPR, so needs , at end
508
509 =cut
510
511 checkOptree(note   => q{},
512             bcopts => q{-exec},
513             code   => q{@hashes = map +{ lc($_), 1 }, @array },
514             expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
515 # 1  <;> nextstate(main 475 (eval 10):1) v
516 # 2  <0> pushmark s
517 # 3  <0> pushmark s
518 # 4  <#> gv[*array] s
519 # 5  <1> rv2av[t6] lKM/1
520 # 6  <@> mapstart lK
521 # 7  <|> mapwhile(other->8)[t7] lK
522 # 8      <0> pushmark s
523 # 9      <#> gvsv[*_] s
524 # a      <1> lc[t4] sK/1
525 # b      <$> const[IV 1] s
526 # c      <@> anonhash sK*/1
527 #            goto 7
528 # d  <0> pushmark s
529 # e  <#> gv[*hashes] s
530 # f  <1> rv2av[t2] lKRM*/1
531 # g  <2> aassign[t8] KS/COMMON
532 # h  <1> leavesub[1 ref] K/REFC,1
533 EOT_EOT
534 # 1  <;> nextstate(main 601 (eval 32):1) v
535 # 2  <0> pushmark s
536 # 3  <0> pushmark s
537 # 4  <$> gv(*array) s
538 # 5  <1> rv2av[t3] lKM/1
539 # 6  <@> mapstart lK
540 # 7  <|> mapwhile(other->8)[t4] lK
541 # 8      <0> pushmark s
542 # 9      <$> gvsv(*_) s
543 # a      <1> lc[t2] sK/1
544 # b      <$> const(IV 1) s
545 # c      <@> anonhash sK*/1
546 #            goto 7
547 # d  <0> pushmark s
548 # e  <$> gv(*hashes) s
549 # f  <1> rv2av[t1] lKRM*/1
550 # g  <2> aassign[t5] KS/COMMON
551 # h  <1> leavesub[1 ref] K/REFC,1
552 EONT_EONT