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