xref: /openbsd/gnu/usr.bin/perl/ext/B/t/f_map.t (revision 264ca280)
1#!perl
2
3BEGIN {
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}
15use OptreeCheck;
16plan tests => 18;
17
18
19=head1 f_map.t
20
21Code test snippets here are adapted from `perldoc -f map`
22
23Due to a bleadperl optimization (Dave Mitchell, circa may 04), the
24(map|grep)(start|while) opcodes have different flags in 5.9, their
25private flags /1, /2 are gone in blead (for the cases covered)
26
27When the optree stuff was integrated into 5.8.6, these tests failed,
28and were todo'd.  They're now done, by version-specific tweaking in
29mkCheckRex(), 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
45checkOptree(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
64EOT_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
80EONT_EONT
81
82
83=for gentest
84
85# chunk: %hash = map { getkey($_) => $_ } @array;
86
87=cut
88
89checkOptree(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
116EOT_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
140EONT_EONT
141
142
143=for gentest
144
145# chunk: {
146    %hash = ();
147    foreach $_ (@array) {
148	$hash{getkey($_)} = $_;
149    }
150}
151
152=cut
153
154checkOptree(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
191EOT_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
225EONT_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
235checkOptree(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
261EOT_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
284EONT_EONT
285
286
287=for gentest
288
289# chunk: %hash = map { ("\L$_", 1) } @array;  # this also works
290
291=cut
292
293checkOptree(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
319EOT_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
342EONT_EONT
343
344
345=for gentest
346
347# chunk: %hash = map {  lc($_), 1  } @array;  # as does this.
348
349=cut
350
351checkOptree(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
376EOT_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
398EONT_EONT
399
400
401=for gentest
402
403# chunk: %hash = map +( lc($_), 1 ), @array;  # this is EXPR and works!
404
405=cut
406
407checkOptree(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
430EOT_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
450EONT_EONT
451
452
453=for gentest
454
455# chunk: %hash = map  ( lc($_), 1 ), @array;  # evaluates to (1, @array)
456
457=cut
458
459checkOptree(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
482EOT_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
502EONT_EONT
503
504
505=for gentest
506
507# chunk: @hashes = map +{ lc($_), 1 }, @array # EXPR, so needs , at end
508
509=cut
510
511checkOptree(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
533EOT_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
552EONT_EONT
553