xref: /openbsd-src/gnu/usr.bin/perl/ext/B/t/f_map.t (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
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      <0> pushmark s
105# c      <#> gvsv[*_] s
106# d      <#> gv[*getkey] s/EARLYCV
107# e      <1> entersub[t5] lKS/TARG
108# f      <#> gvsv[*_] s
109# g      <@> list lK
110# h      <@> leave lKP
111#            goto 7
112# i  <0> pushmark s
113# j  <#> gv[*hash] s
114# k  <1> rv2hv[t2] lKRM*/1
115# l  <2> aassign[t10] KS/COMMON
116# m  <1> leavesub[1 ref] K/REFC,1
117EOT_EOT
118# 1  <;> nextstate(main 560 (eval 15):1) v:{
119# 2  <0> pushmark s
120# 3  <0> pushmark s
121# 4  <$> gv(*array) s
122# 5  <1> rv2av[t3] lKM/1
123# 6  <@> mapstart lK*              < 5.017002
124# 6  <@> mapstart lK               >=5.017002
125# 7  <|> mapwhile(other->8)[t4] lK
126# 8      <0> enter l
127# 9      <;> nextstate(main 559 (eval 15):1) v:{
128# a      <0> pushmark s
129# b      <0> pushmark s
130# c      <$> gvsv(*_) s
131# d      <$> gv(*getkey) s/EARLYCV
132# e      <1> entersub[t2] lKS/TARG
133# f      <$> gvsv(*_) s
134# g      <@> list lK
135# h      <@> leave lKP
136#            goto 7
137# i  <0> pushmark s
138# j  <$> gv(*hash) s
139# k  <1> rv2hv[t1] lKRM*/1
140# l  <2> aassign[t5] KS/COMMON
141# m  <1> leavesub[1 ref] K/REFC,1
142EONT_EONT
143
144
145=for gentest
146
147# chunk: {
148    %hash = ();
149    foreach $_ (@array) {
150	$hash{getkey($_)} = $_;
151    }
152}
153
154=cut
155
156checkOptree(note   => q{},
157	    bcopts => q{-exec},
158	    code   => q{{ %hash = (); foreach $_ (@array) { $hash{getkey($_)} = $_; } } },
159	    expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
160# 1  <;> nextstate(main 478 (eval 10):1) v:{
161# 2  <{> enterloop(next->u last->u redo->3)
162# 3  <;> nextstate(main 475 (eval 10):1) v
163# 4  <0> pushmark s
164# 5  <0> pushmark s
165# 6  <#> gv[*hash] s
166# 7  <1> rv2hv[t2] lKRM*/1
167# 8  <2> aassign[t3] vKS
168# 9  <;> nextstate(main 476 (eval 10):1) v:{
169# a  <0> pushmark sM
170# b  <#> gv[*array] s
171# c  <1> rv2av[t6] sKRM/1
172# d  <#> gv[*_] s
173# e  <1> rv2gv sKRM/1
174# f  <{> enteriter(next->q last->t redo->g) lKS/8
175# r  <0> iter s
176# s  <|> and(other->g) K/1
177# g      <;> nextstate(main 475 (eval 10):1) v:{
178# h      <#> gvsv[*_] s
179# i      <#> gv[*hash] s
180# j      <1> rv2hv sKR/1
181# k      <0> pushmark s
182# l      <#> gvsv[*_] s
183# m      <#> gv[*getkey] s/EARLYCV
184# n      <1> entersub[t10] sKS/TARG
185# o      <2> helem sKRM*/2
186# p      <2> sassign vKS/2
187# q      <0> unstack s
188#            goto r
189# t  <2> leaveloop KP/2
190# u  <2> leaveloop K/2
191# v  <1> leavesub[1 ref] K/REFC,1
192EOT_EOT
193# 1  <;> nextstate(main 562 (eval 15):1) v:{
194# 2  <{> enterloop(next->u last->u redo->3)
195# 3  <;> nextstate(main 559 (eval 15):1) v
196# 4  <0> pushmark s
197# 5  <0> pushmark s
198# 6  <$> gv(*hash) s
199# 7  <1> rv2hv[t1] lKRM*/1
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
258# h  <2> aassign[t10] KS/COMMON
259# i  <1> leavesub[1 ref] K/REFC,1
260EOT_EOT
261# 1  <;> nextstate(main 560 (eval 15):1) v
262# 2  <0> pushmark s
263# 3  <0> pushmark s
264# 4  <$> gv(*array) s
265# 5  <1> rv2av[t4] lKM/1
266# 6  <@> mapstart lK*              < 5.017002
267# 6  <@> mapstart lK               >=5.017002
268# 7  <|> mapwhile(other->8)[t5] lK
269# 8      <0> pushmark s
270# 9      <$> gvsv(*_) s
271# a      <1> lc[t2] sK/1
272# b      <@> stringify[t3] sK/1
273# c      <$> const(IV 1) s
274# d      <@> list lK
275# -      <@> scope lK              < 5.017002
276#            goto 7
277# e  <0> pushmark s
278# f  <$> gv(*hash) s
279# g  <1> rv2hv[t1] lKRM*/1
280# h  <2> aassign[t6] KS/COMMON
281# i  <1> leavesub[1 ref] K/REFC,1
282EONT_EONT
283
284
285=for gentest
286
287# chunk: %hash = map { ("\L$_", 1) } @array;  # this also works
288
289=cut
290
291checkOptree(note   => q{},
292	    bcopts => q{-exec},
293	    code   => q{%hash = map { ("\L$_", 1) } @array; },
294	    expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
295# 1  <;> nextstate(main 476 (eval 10):1) v
296# 2  <0> pushmark s
297# 3  <0> pushmark s
298# 4  <#> gv[*array] s
299# 5  <1> rv2av[t7] lKM/1
300# 6  <@> mapstart lK*              < 5.017002
301# 6  <@> mapstart lK               >=5.017002
302# 7  <|> mapwhile(other->8)[t9] lK
303# 8      <0> pushmark s
304# 9      <#> gvsv[*_] s
305# a      <1> lc[t4] sK/1
306# b      <@> stringify[t5] sK/1
307# c      <$> const[IV 1] s
308# d      <@> list lKP
309# -      <@> scope lK              < 5.017002
310#            goto 7
311# e  <0> pushmark s
312# f  <#> gv[*hash] s
313# g  <1> rv2hv[t2] lKRM*/1
314# h  <2> aassign[t10] KS/COMMON
315# i  <1> leavesub[1 ref] K/REFC,1
316EOT_EOT
317# 1  <;> nextstate(main 560 (eval 15):1) v
318# 2  <0> pushmark s
319# 3  <0> pushmark s
320# 4  <$> gv(*array) s
321# 5  <1> rv2av[t4] lKM/1
322# 6  <@> mapstart lK*              < 5.017002
323# 6  <@> mapstart lK               >=5.017002
324# 7  <|> mapwhile(other->8)[t5] lK
325# 8      <0> pushmark s
326# 9      <$> gvsv(*_) s
327# a      <1> lc[t2] sK/1
328# b      <@> stringify[t3] sK/1
329# c      <$> const(IV 1) s
330# d      <@> list lKP
331# -      <@> scope lK              < 5.017002
332#            goto 7
333# e  <0> pushmark s
334# f  <$> gv(*hash) s
335# g  <1> rv2hv[t1] lKRM*/1
336# h  <2> aassign[t6] KS/COMMON
337# i  <1> leavesub[1 ref] K/REFC,1
338EONT_EONT
339
340
341=for gentest
342
343# chunk: %hash = map {  lc($_), 1  } @array;  # as does this.
344
345=cut
346
347checkOptree(note   => q{},
348	    bcopts => q{-exec},
349	    code   => q{%hash = map { lc($_), 1 } @array; },
350	    expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
351# 1  <;> nextstate(main 476 (eval 10):1) v
352# 2  <0> pushmark s
353# 3  <0> pushmark s
354# 4  <#> gv[*array] s
355# 5  <1> rv2av[t6] lKM/1
356# 6  <@> mapstart lK*              < 5.017002
357# 6  <@> mapstart lK               >=5.017002
358# 7  <|> mapwhile(other->8)[t8] lK
359# 8      <0> pushmark s
360# 9      <#> gvsv[*_] s
361# a      <1> lc[t4] sK/1
362# b      <$> const[IV 1] s
363# c      <@> list lK
364# -      <@> scope lK              < 5.017002
365#            goto 7
366# d  <0> pushmark s
367# e  <#> gv[*hash] s
368# f  <1> rv2hv[t2] lKRM*/1
369# g  <2> aassign[t9] KS/COMMON
370# h  <1> leavesub[1 ref] K/REFC,1
371EOT_EOT
372# 1  <;> nextstate(main 589 (eval 26):1) v
373# 2  <0> pushmark s
374# 3  <0> pushmark s
375# 4  <$> gv(*array) s
376# 5  <1> rv2av[t3] lKM/1
377# 6  <@> mapstart lK*              < 5.017002
378# 6  <@> mapstart lK               >=5.017002
379# 7  <|> mapwhile(other->8)[t4] lK
380# 8      <0> pushmark s
381# 9      <$> gvsv(*_) s
382# a      <1> lc[t2] sK/1
383# b      <$> const(IV 1) s
384# c      <@> list lK
385# -      <@> scope lK              < 5.017002
386#            goto 7
387# d  <0> pushmark s
388# e  <$> gv(*hash) s
389# f  <1> rv2hv[t1] lKRM*/1
390# g  <2> aassign[t5] KS/COMMON
391# h  <1> leavesub[1 ref] K/REFC,1
392EONT_EONT
393
394
395=for gentest
396
397# chunk: %hash = map +( lc($_), 1 ), @array;  # this is EXPR and works!
398
399=cut
400
401checkOptree(note   => q{},
402	    bcopts => q{-exec},
403	    code   => q{%hash = map +( lc($_), 1 ), @array; },
404	    expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
405# 1  <;> nextstate(main 475 (eval 10):1) v
406# 2  <0> pushmark s
407# 3  <0> pushmark s
408# 4  <#> gv[*array] s
409# 5  <1> rv2av[t6] lKM/1
410# 6  <@> mapstart lK
411# 7  <|> mapwhile(other->8)[t7] lK
412# 8      <0> pushmark s
413# 9      <#> gvsv[*_] s
414# a      <1> lc[t4] sK/1
415# b      <$> const[IV 1] s
416# c      <@> list lKP
417#            goto 7
418# d  <0> pushmark s
419# e  <#> gv[*hash] s
420# f  <1> rv2hv[t2] lKRM*/1
421# g  <2> aassign[t8] KS/COMMON
422# h  <1> leavesub[1 ref] K/REFC,1
423EOT_EOT
424# 1  <;> nextstate(main 593 (eval 28):1) v
425# 2  <0> pushmark s
426# 3  <0> pushmark s
427# 4  <$> gv(*array) s
428# 5  <1> rv2av[t3] lKM/1
429# 6  <@> mapstart lK
430# 7  <|> mapwhile(other->8)[t4] lK
431# 8      <0> pushmark s
432# 9      <$> gvsv(*_) s
433# a      <1> lc[t2] sK/1
434# b      <$> const(IV 1) s
435# c      <@> list lKP
436#            goto 7
437# d  <0> pushmark s
438# e  <$> gv(*hash) s
439# f  <1> rv2hv[t1] lKRM*/1
440# g  <2> aassign[t5] KS/COMMON
441# h  <1> leavesub[1 ref] K/REFC,1
442EONT_EONT
443
444
445=for gentest
446
447# chunk: %hash = map  ( lc($_), 1 ), @array;  # evaluates to (1, @array)
448
449=cut
450
451checkOptree(note   => q{},
452	    bcopts => q{-exec},
453	    code   => q{%hash = map ( lc($_), 1 ), @array; },
454	    expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
455# 1  <;> nextstate(main 475 (eval 10):1) v
456# 2  <0> pushmark s
457# 3  <0> pushmark s
458# 4  <0> pushmark s
459# 5  <$> const[IV 1] sM
460# 6  <@> mapstart lK
461# 7  <|> mapwhile(other->8)[t5] lK
462# 8      <#> gvsv[*_] s
463# 9      <1> lc[t4] sK/1
464#            goto 7
465# a  <0> pushmark s
466# b  <#> gv[*hash] s
467# c  <1> rv2hv[t2] lKRM*/1
468# d  <2> aassign[t6] KS/COMMON
469# e  <#> gv[*array] s
470# f  <1> rv2av[t8] K/1
471# g  <@> list K
472# h  <1> leavesub[1 ref] K/REFC,1
473EOT_EOT
474# 1  <;> nextstate(main 597 (eval 30):1) v
475# 2  <0> pushmark s
476# 3  <0> pushmark s
477# 4  <0> pushmark s
478# 5  <$> const(IV 1) sM
479# 6  <@> mapstart lK
480# 7  <|> mapwhile(other->8)[t3] lK
481# 8      <$> gvsv(*_) s
482# 9      <1> lc[t2] sK/1
483#            goto 7
484# a  <0> pushmark s
485# b  <$> gv(*hash) s
486# c  <1> rv2hv[t1] lKRM*/1
487# d  <2> aassign[t4] KS/COMMON
488# e  <$> gv(*array) s
489# f  <1> rv2av[t5] K/1
490# g  <@> list K
491# h  <1> leavesub[1 ref] K/REFC,1
492EONT_EONT
493
494
495=for gentest
496
497# chunk: @hashes = map +{ lc($_), 1 }, @array # EXPR, so needs , at end
498
499=cut
500
501checkOptree(note   => q{},
502	    bcopts => q{-exec},
503	    code   => q{@hashes = map +{ lc($_), 1 }, @array },
504	    expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
505# 1  <;> nextstate(main 475 (eval 10):1) v
506# 2  <0> pushmark s
507# 3  <0> pushmark s
508# 4  <#> gv[*array] s
509# 5  <1> rv2av[t6] lKM/1
510# 6  <@> mapstart lK
511# 7  <|> mapwhile(other->8)[t7] lK
512# 8      <0> pushmark s
513# 9      <#> gvsv[*_] s
514# a      <1> lc[t4] sK/1
515# b      <$> const[IV 1] s
516# c      <@> anonhash sK*/1
517#            goto 7
518# d  <0> pushmark s
519# e  <#> gv[*hashes] s
520# f  <1> rv2av[t2] lKRM*/1
521# g  <2> aassign[t8] KS/COMMON
522# h  <1> leavesub[1 ref] K/REFC,1
523EOT_EOT
524# 1  <;> nextstate(main 601 (eval 32):1) v
525# 2  <0> pushmark s
526# 3  <0> pushmark s
527# 4  <$> gv(*array) s
528# 5  <1> rv2av[t3] lKM/1
529# 6  <@> mapstart lK
530# 7  <|> mapwhile(other->8)[t4] lK
531# 8      <0> pushmark s
532# 9      <$> gvsv(*_) s
533# a      <1> lc[t2] sK/1
534# b      <$> const(IV 1) s
535# c      <@> anonhash sK*/1
536#            goto 7
537# d  <0> pushmark s
538# e  <$> gv(*hashes) s
539# f  <1> rv2av[t1] lKRM*/1
540# g  <2> aassign[t5] KS/COMMON
541# h  <1> leavesub[1 ref] K/REFC,1
542EONT_EONT
543