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