From f68519ee3f12e5ba41a022ef88ce3d6c3901807f Mon Sep 17 00:00:00 2001 From: Zefram Date: Wed, 6 Dec 2017 00:09:42 +0000 Subject: [PATCH] add "whereis" "whereis" is like "whereso" except that it performs an implicit smartmatch. --- MANIFEST | 1 + gv.c | 3 +- keywords.c | 32 +++- keywords.h | 15 +- lib/B/Deparse-core.t | 1 + lib/B/Deparse.pm | 21 ++- lib/B/Deparse.t | 20 ++- perly.act | 428 +++++++++++++++++++++++++------------------------ perly.h | 2 +- perly.tab | 50 +++--- perly.y | 16 +- pod/perldiag.pod | 24 ++- pod/perlexperiment.pod | 3 +- pod/perlfunc.pod | 9 +- pod/perlsyn.pod | 57 ++++--- regen/keywords.pl | 2 + t/op/coreamp.t | 3 +- t/op/coresubs.t | 2 +- t/op/cproto.t | 3 +- t/op/whereis.t | 78 +++++++++ toke.c | 6 +- 21 files changed, 481 insertions(+), 295 deletions(-) create mode 100644 t/op/whereis.t diff --git a/MANIFEST b/MANIFEST index 03a002f..e0f01b9 100644 --- a/MANIFEST +++ b/MANIFEST @@ -5806,6 +5806,7 @@ t/op/ver.t See if v-strings and the %v format flag work t/op/waitpid.t See if waitpid works t/op/wantarray.t See if wantarray works t/op/warn.t See if warn works +t/op/whereis.t See if whereis works t/op/whereso.t See if whereso works t/op/while.t See if while loops work t/op/write.t See if write works (formats work) diff --git a/gv.c b/gv.c index 015903c..dd930b5 100644 --- a/gv.c +++ b/gv.c @@ -535,7 +535,8 @@ S_maybe_add_coresub(pTHX_ HV * const stash, GV *gv, case KEY_s : case KEY_say : case KEY_sort : case KEY_state: case KEY_sub : case KEY_tr : case KEY_UNITCHECK: case KEY_unless: - case KEY_until: case KEY_use : case KEY_whereso : case KEY_while : + case KEY_until: case KEY_use : + case KEY_whereis: case KEY_whereso: case KEY_while: case KEY_x : case KEY_xor : case KEY_y : return NULL; case KEY_chdir: diff --git a/keywords.c b/keywords.c index 217efa3b..23e6145 100644 --- a/keywords.c +++ b/keywords.c @@ -1876,7 +1876,7 @@ Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords) goto unknown; } - case 7: /* 30 tokens of length 7 */ + case 7: /* 31 tokens of length 7 */ switch (name[0]) { case 'D': @@ -2299,11 +2299,29 @@ Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords) case 'h': if (name[2] == 'e' && name[3] == 'r' && - name[4] == 'e' && - name[5] == 's' && - name[6] == 'o') - { /* whereso */ - return (all_keywords || FEATURE_SWITCH_IS_ENABLED ? KEY_whereso : 0); + name[4] == 'e') + { + switch (name[5]) + { + case 'i': + if (name[6] == 's') + { /* whereis */ + return (all_keywords || FEATURE_SWITCH_IS_ENABLED ? KEY_whereis : 0); + } + + goto unknown; + + case 's': + if (name[6] == 'o') + { /* whereso */ + return (all_keywords || FEATURE_SWITCH_IS_ENABLED ? KEY_whereso : 0); + } + + goto unknown; + + default: + goto unknown; + } } goto unknown; @@ -3408,5 +3426,5 @@ unknown: } /* Generated from: - * fa7d552d13fad7c3ad101e3f8d5301a9780147c26623ecb3e75f0ec7f0d24cc3 regen/keywords.pl + * b2741ab99701d1c72b58afb96a9f210532b6f6ce81aacdf5188a4871c16ee239 regen/keywords.pl * ex: set ro: */ diff --git a/keywords.h b/keywords.h index d630d02..d65879a 100644 --- a/keywords.h +++ b/keywords.h @@ -260,13 +260,14 @@ #define KEY_waitpid 244 #define KEY_wantarray 245 #define KEY_warn 246 -#define KEY_whereso 247 -#define KEY_while 248 -#define KEY_write 249 -#define KEY_x 250 -#define KEY_xor 251 -#define KEY_y 252 +#define KEY_whereis 247 +#define KEY_whereso 248 +#define KEY_while 249 +#define KEY_write 250 +#define KEY_x 251 +#define KEY_xor 252 +#define KEY_y 253 /* Generated from: - * fa7d552d13fad7c3ad101e3f8d5301a9780147c26623ecb3e75f0ec7f0d24cc3 regen/keywords.pl + * b2741ab99701d1c72b58afb96a9f210532b6f6ce81aacdf5188a4871c16ee239 regen/keywords.pl * ex: set ro: */ diff --git a/lib/B/Deparse-core.t b/lib/B/Deparse-core.t index e1984c8..d9e1f5d 100644 --- a/lib/B/Deparse-core.t +++ b/lib/B/Deparse-core.t @@ -378,6 +378,7 @@ my %not_tested = map { $_ => 1} qw( unless until use + whereis whereso while y diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm index 387bb1e..aa86156 100644 --- a/lib/B/Deparse.pm +++ b/lib/B/Deparse.pm @@ -2246,6 +2246,7 @@ my %feature_keywords = ( state => 'state', say => 'say', given => 'switch', + whereis => 'switch', whereso => 'switch', evalbytes=>'evalbytes', __SUB__ => '__SUB__', @@ -2539,14 +2540,28 @@ sub pp_lock { unop(@_, "lock") } sub pp_continue { unop(@_, "continue"); } +sub _op_is_defsv { + my($self, $op) = @_; + $op->name eq "null" && !null($op->first) && null($op->first->sibling) + and $op = $op->first; + $op->name eq "gvsv" && $self->gv_name($self->gv_or_padgv($op)) eq "_"; +} + sub pp_leavewhereso { my($self, $op, $cx) = @_; - my $whereso = $self->keyword("whereso"); my $enterop = $op->first; my $cond = $enterop->first; + my $block = $cond->sibling; + my $keyword = "whereso"; + if ($cond->name eq "smartmatch" && $self->{expand} < 2 && + $self->_op_is_defsv($cond->first)) { + $cond = $cond->last; + $keyword = "whereis"; + } my $cond_str = $self->deparse($cond, 1); - my $block = $self->deparse($cond->sibling, 0); - return "$whereso ($cond_str) {\n\t$block\n\b}\cK"; + $keyword = $self->keyword($keyword); + $block = $self->deparse($block, 0); + return "$keyword ($cond_str) {\n\t$block\n\b}\cK"; } sub pp_exists { diff --git a/lib/B/Deparse.t b/lib/B/Deparse.t index b8d98ca..e90cbed 100644 --- a/lib/B/Deparse.t +++ b/lib/B/Deparse.t @@ -1028,7 +1028,8 @@ my $d = \[]; # implicit smartmatch in given/whereso given ('foo') { whereso ('bar') { continue; } - whereso ($_ ~~ 'quux') { continue; } + whereso ($_ == 3) { continue; } + whereis ('quux') { continue; } 0; } #### @@ -1514,6 +1515,9 @@ CORE::given ($x) { CORE::whereso (3) { continue; } + CORE::whereis (5) { + continue; + } next; } CORE::evalbytes ''; @@ -1530,6 +1534,9 @@ CORE::given ($x) { CORE::whereso (3) { continue; } + CORE::whereis (5) { + continue; + } next; } CORE::evalbytes ''; @@ -1541,6 +1548,9 @@ CORE::given ($x) { CORE::whereso (3) { continue; } + CORE::whereis (5) { + continue; + } next; } CORE::evalbytes ''; @@ -1557,6 +1567,9 @@ CORE::given ($x) { CORE::whereso (3) { continue; } + CORE::whereis (5) { + continue; + } next; } CORE::evalbytes ''; @@ -1570,6 +1583,9 @@ CORE::given ($x) { CORE::whereso (3) { continue; } + CORE::whereis (5) { + continue; + } next; } CORE::evalbytes ''; @@ -1598,6 +1614,7 @@ my sub tr; my sub unless; my sub until; my sub use; +my sub whereis; my sub whereso; my sub while; CORE::if ($1) { die; } @@ -1621,6 +1638,7 @@ CORE::unless ($1) { die; } CORE::until ($1) { die; } die CORE::until $1; CORE::use strict; +CORE::whereis (5) { die; } CORE::whereso ($1 ~~ $2) { die; } CORE::while ($1) { die; } die CORE::while $1; diff --git a/perly.act b/perly.act index 5587da0..42c9c02 100644 --- a/perly.act +++ b/perly.act @@ -392,12 +392,18 @@ case 2: case 39: #line 382 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = block_end((ps[-3].val.ival), newWHERESOOP((ps[-2].val.opval), op_scope((ps[0].val.opval)))); } + { + OP *cond = (ps[-2].val.opval); + if ((ps[-5].val.ival)) + cond = newBINOP(OP_SMARTMATCH, 0, newDEFSVOP(), + scalar(cond)); + (yyval.opval) = block_end((ps[-3].val.ival), newWHERESOOP(cond, op_scope((ps[0].val.opval)))); + } break; case 40: -#line 384 "perly.y" /* yacc.c:1646 */ +#line 390 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = block_end((ps[-5].val.ival), newWHILEOP(0, 1, NULL, @@ -408,7 +414,7 @@ case 2: break; case 41: -#line 391 "perly.y" /* yacc.c:1646 */ +#line 397 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = block_end((ps[-5].val.ival), newWHILEOP(0, 1, NULL, @@ -419,19 +425,19 @@ case 2: break; case 42: -#line 398 "perly.y" /* yacc.c:1646 */ +#line 404 "perly.y" /* yacc.c:1646 */ { parser->expect = XTERM; } break; case 43: -#line 400 "perly.y" /* yacc.c:1646 */ +#line 406 "perly.y" /* yacc.c:1646 */ { parser->expect = XTERM; } break; case 44: -#line 403 "perly.y" /* yacc.c:1646 */ +#line 409 "perly.y" /* yacc.c:1646 */ { OP *initop = (ps[-9].val.opval); OP *forop = newWHILEOP(0, 1, NULL, @@ -450,7 +456,7 @@ case 2: break; case 45: -#line 418 "perly.y" /* yacc.c:1646 */ +#line 424 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = block_end((ps[-6].val.ival), newFOROP(0, (ps[-5].val.opval), (ps[-3].val.opval), (ps[-1].val.opval), (ps[0].val.opval))); parser->copline = (line_t)(ps[-8].val.ival); @@ -459,7 +465,7 @@ case 2: break; case 46: -#line 423 "perly.y" /* yacc.c:1646 */ +#line 429 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = block_end((ps[-4].val.ival), newFOROP(0, op_lvalue((ps[-6].val.opval), OP_ENTERLOOP), (ps[-3].val.opval), (ps[-1].val.opval), (ps[0].val.opval))); @@ -469,13 +475,13 @@ case 2: break; case 47: -#line 429 "perly.y" /* yacc.c:1646 */ +#line 435 "perly.y" /* yacc.c:1646 */ { parser->in_my = 0; (yyval.opval) = my((ps[0].val.opval)); } break; case 48: -#line 431 "perly.y" /* yacc.c:1646 */ +#line 437 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = block_end( (ps[-7].val.ival), @@ -492,7 +498,7 @@ case 2: break; case 49: -#line 444 "perly.y" /* yacc.c:1646 */ +#line 450 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = block_end((ps[-4].val.ival), newFOROP( 0, op_lvalue(newUNOP(OP_REFGEN, 0, @@ -504,7 +510,7 @@ case 2: break; case 50: -#line 452 "perly.y" /* yacc.c:1646 */ +#line 458 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = block_end((ps[-4].val.ival), newFOROP(0, NULL, (ps[-3].val.opval), (ps[-1].val.opval), (ps[0].val.opval))); @@ -514,7 +520,7 @@ case 2: break; case 51: -#line 458 "perly.y" /* yacc.c:1646 */ +#line 464 "perly.y" /* yacc.c:1646 */ { /* a block is a loop that happens once */ (yyval.opval) = newWHILEOP(0, 1, NULL, @@ -524,7 +530,7 @@ case 2: break; case 52: -#line 464 "perly.y" /* yacc.c:1646 */ +#line 470 "perly.y" /* yacc.c:1646 */ { package((ps[-2].val.opval)); if ((ps[-3].val.opval)) { @@ -535,7 +541,7 @@ case 2: break; case 53: -#line 471 "perly.y" /* yacc.c:1646 */ +#line 477 "perly.y" /* yacc.c:1646 */ { /* a block is a loop that happens once */ (yyval.opval) = newWHILEOP(0, 1, NULL, @@ -547,7 +553,7 @@ case 2: break; case 54: -#line 479 "perly.y" /* yacc.c:1646 */ +#line 485 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[-1].val.opval); } @@ -555,7 +561,7 @@ case 2: break; case 55: -#line 483 "perly.y" /* yacc.c:1646 */ +#line 489 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLISTOP(OP_DIE, 0, newOP(OP_PUSHMARK, 0), newSVOP(OP_CONST, 0, newSVpvs("Unimplemented"))); @@ -564,7 +570,7 @@ case 2: break; case 56: -#line 488 "perly.y" /* yacc.c:1646 */ +#line 494 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; parser->copline = NOLINE; @@ -573,7 +579,7 @@ case 2: break; case 57: -#line 496 "perly.y" /* yacc.c:1646 */ +#line 502 "perly.y" /* yacc.c:1646 */ { OP *list; if ((ps[0].val.opval)) { OP *term = (ps[0].val.opval); @@ -592,74 +598,80 @@ case 2: break; case 58: -#line 513 "perly.y" /* yacc.c:1646 */ +#line 519 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 59: -#line 515 "perly.y" /* yacc.c:1646 */ +#line 521 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_unscope((ps[-1].val.opval)); } break; case 60: -#line 520 "perly.y" /* yacc.c:1646 */ +#line 526 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 61: -#line 522 "perly.y" /* yacc.c:1646 */ +#line 528 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 62: -#line 524 "perly.y" /* yacc.c:1646 */ +#line 530 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[0].val.opval), (ps[-2].val.opval)); } break; case 63: -#line 526 "perly.y" /* yacc.c:1646 */ +#line 532 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOGOP(OP_OR, 0, (ps[0].val.opval), (ps[-2].val.opval)); } break; case 64: -#line 528 "perly.y" /* yacc.c:1646 */ +#line 534 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOOPOP(OPf_PARENS, 1, scalar((ps[0].val.opval)), (ps[-2].val.opval)); } break; case 65: -#line 530 "perly.y" /* yacc.c:1646 */ +#line 536 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOOPOP(OPf_PARENS, 1, (ps[0].val.opval), (ps[-2].val.opval)); } break; case 66: -#line 532 "perly.y" /* yacc.c:1646 */ +#line 538 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newFOROP(0, NULL, (ps[0].val.opval), (ps[-2].val.opval), NULL); parser->copline = (line_t)(ps[-1].val.ival); } break; case 67: -#line 535 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = newWHERESOOP((ps[0].val.opval), op_scope((ps[-2].val.opval))); } +#line 541 "perly.y" /* yacc.c:1646 */ + { + OP *cond = (ps[0].val.opval); + if ((ps[-1].val.ival)) + cond = newBINOP(OP_SMARTMATCH, 0, newDEFSVOP(), + scalar(cond)); + (yyval.opval) = newWHERESOOP(cond, op_scope((ps[-2].val.opval))); + } break; case 68: -#line 540 "perly.y" /* yacc.c:1646 */ +#line 552 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 69: -#line 542 "perly.y" /* yacc.c:1646 */ +#line 554 "perly.y" /* yacc.c:1646 */ { ((ps[0].val.opval))->op_flags |= OPf_PARENS; (yyval.opval) = op_scope((ps[0].val.opval)); @@ -668,7 +680,7 @@ case 2: break; case 70: -#line 547 "perly.y" /* yacc.c:1646 */ +#line 559 "perly.y" /* yacc.c:1646 */ { parser->copline = (line_t)(ps[-5].val.ival); (yyval.opval) = newCONDOP(0, newSTATEOP(OPf_SPECIAL,NULL,(ps[-3].val.opval)), @@ -679,19 +691,19 @@ case 2: break; case 71: -#line 557 "perly.y" /* yacc.c:1646 */ +#line 569 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 72: -#line 559 "perly.y" /* yacc.c:1646 */ +#line 571 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_scope((ps[0].val.opval)); } break; case 73: -#line 564 "perly.y" /* yacc.c:1646 */ +#line 576 "perly.y" /* yacc.c:1646 */ { (yyval.ival) = (PL_min_intro_pending && PL_max_intro_pending >= PL_min_intro_pending); intro_my(); } @@ -699,13 +711,13 @@ case 2: break; case 74: -#line 570 "perly.y" /* yacc.c:1646 */ +#line 582 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 76: -#line 576 "perly.y" /* yacc.c:1646 */ +#line 588 "perly.y" /* yacc.c:1646 */ { YYSTYPE tmplval; (void)scan_num("1", &tmplval); (yyval.opval) = tmplval.opval; } @@ -713,118 +725,118 @@ case 2: break; case 78: -#line 584 "perly.y" /* yacc.c:1646 */ +#line 596 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = invert(scalar((ps[0].val.opval))); } break; case 79: -#line 589 "perly.y" /* yacc.c:1646 */ +#line 601 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); intro_my(); } break; case 80: -#line 593 "perly.y" /* yacc.c:1646 */ +#line 605 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); intro_my(); } break; case 81: -#line 596 "perly.y" /* yacc.c:1646 */ +#line 608 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 82: -#line 597 "perly.y" /* yacc.c:1646 */ +#line 609 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 83: -#line 601 "perly.y" /* yacc.c:1646 */ +#line 613 "perly.y" /* yacc.c:1646 */ { (yyval.ival) = start_subparse(FALSE, 0); SAVEFREESV(PL_compcv); } break; case 84: -#line 607 "perly.y" /* yacc.c:1646 */ +#line 619 "perly.y" /* yacc.c:1646 */ { (yyval.ival) = start_subparse(FALSE, CVf_ANON); SAVEFREESV(PL_compcv); } break; case 85: -#line 612 "perly.y" /* yacc.c:1646 */ +#line 624 "perly.y" /* yacc.c:1646 */ { (yyval.ival) = start_subparse(TRUE, 0); SAVEFREESV(PL_compcv); } break; case 88: -#line 623 "perly.y" /* yacc.c:1646 */ +#line 635 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 90: -#line 629 "perly.y" /* yacc.c:1646 */ +#line 641 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 91: -#line 631 "perly.y" /* yacc.c:1646 */ +#line 643 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 92: -#line 633 "perly.y" /* yacc.c:1646 */ +#line 645 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 93: -#line 638 "perly.y" /* yacc.c:1646 */ +#line 650 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 94: -#line 640 "perly.y" /* yacc.c:1646 */ +#line 652 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 95: -#line 651 "perly.y" /* yacc.c:1646 */ +#line 663 "perly.y" /* yacc.c:1646 */ { parser->in_my = 0; (yyval.opval) = NULL; } break; case 96: -#line 653 "perly.y" /* yacc.c:1646 */ +#line 665 "perly.y" /* yacc.c:1646 */ { parser->in_my = 0; (yyval.opval) = (ps[0].val.opval); } break; case 97: -#line 658 "perly.y" /* yacc.c:1646 */ +#line 670 "perly.y" /* yacc.c:1646 */ { (yyval.ival) = '@'; } break; case 98: -#line 660 "perly.y" /* yacc.c:1646 */ +#line 672 "perly.y" /* yacc.c:1646 */ { (yyval.ival) = '%'; } break; case 99: -#line 664 "perly.y" /* yacc.c:1646 */ +#line 676 "perly.y" /* yacc.c:1646 */ { I32 sigil = (ps[-2].val.ival); OP *var = (ps[-1].val.opval); @@ -844,25 +856,25 @@ case 2: break; case 100: -#line 683 "perly.y" /* yacc.c:1646 */ +#line 695 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 101: -#line 685 "perly.y" /* yacc.c:1646 */ +#line 697 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newOP(OP_NULL, 0); } break; case 102: -#line 687 "perly.y" /* yacc.c:1646 */ +#line 699 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 103: -#line 693 "perly.y" /* yacc.c:1646 */ +#line 705 "perly.y" /* yacc.c:1646 */ { OP *var = (ps[-1].val.opval); OP *defexpr = (ps[0].val.opval); @@ -927,25 +939,25 @@ case 2: break; case 104: -#line 758 "perly.y" /* yacc.c:1646 */ +#line 770 "perly.y" /* yacc.c:1646 */ { parser->in_my = KEY_sigvar; (yyval.opval) = (ps[0].val.opval); } break; case 105: -#line 760 "perly.y" /* yacc.c:1646 */ +#line 772 "perly.y" /* yacc.c:1646 */ { parser->in_my = KEY_sigvar; (yyval.opval) = (ps[0].val.opval); } break; case 106: -#line 766 "perly.y" /* yacc.c:1646 */ +#line 778 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[-1].val.opval); } break; case 107: -#line 768 "perly.y" /* yacc.c:1646 */ +#line 780 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_append_list(OP_LINESEQ, (ps[-2].val.opval), (ps[0].val.opval)); } @@ -953,25 +965,25 @@ case 2: break; case 108: -#line 772 "perly.y" /* yacc.c:1646 */ +#line 784 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 109: -#line 777 "perly.y" /* yacc.c:1646 */ +#line 789 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 110: -#line 779 "perly.y" /* yacc.c:1646 */ +#line 791 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 111: -#line 783 "perly.y" /* yacc.c:1646 */ +#line 795 "perly.y" /* yacc.c:1646 */ { ENTER; SAVEIV(parser->sig_elems); @@ -986,7 +998,7 @@ case 2: break; case 112: -#line 795 "perly.y" /* yacc.c:1646 */ +#line 807 "perly.y" /* yacc.c:1646 */ { OP *sigops = (ps[-1].val.opval); UNOP_AUX_item *aux; @@ -1025,37 +1037,37 @@ case 2: break; case 114: -#line 835 "perly.y" /* yacc.c:1646 */ +#line 847 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 115: -#line 840 "perly.y" /* yacc.c:1646 */ +#line 852 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[-2].val.opval), (ps[0].val.opval)); } break; case 116: -#line 842 "perly.y" /* yacc.c:1646 */ +#line 854 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOGOP((ps[-1].val.ival), 0, (ps[-2].val.opval), (ps[0].val.opval)); } break; case 117: -#line 844 "perly.y" /* yacc.c:1646 */ +#line 856 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOGOP(OP_DOR, 0, (ps[-2].val.opval), (ps[0].val.opval)); } break; case 119: -#line 850 "perly.y" /* yacc.c:1646 */ +#line 862 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[-1].val.opval); } break; case 120: -#line 852 "perly.y" /* yacc.c:1646 */ +#line 864 "perly.y" /* yacc.c:1646 */ { OP* term = (ps[0].val.opval); (yyval.opval) = op_append_elem(OP_LIST, (ps[-2].val.opval), term); @@ -1064,7 +1076,7 @@ case 2: break; case 122: -#line 861 "perly.y" /* yacc.c:1646 */ +#line 873 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_convert_list((ps[-2].val.ival), OPf_STACKED, op_prepend_elem(OP_LIST, newGVREF((ps[-2].val.ival),(ps[-1].val.opval)), (ps[0].val.opval)) ); } @@ -1072,7 +1084,7 @@ case 2: break; case 123: -#line 865 "perly.y" /* yacc.c:1646 */ +#line 877 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_convert_list((ps[-4].val.ival), OPf_STACKED, op_prepend_elem(OP_LIST, newGVREF((ps[-4].val.ival),(ps[-2].val.opval)), (ps[-1].val.opval)) ); } @@ -1080,7 +1092,7 @@ case 2: break; case 124: -#line 869 "perly.y" /* yacc.c:1646 */ +#line 881 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_convert_list(OP_ENTERSUB, OPf_STACKED, op_append_elem(OP_LIST, op_prepend_elem(OP_LIST, scalar((ps[-5].val.opval)), (ps[-1].val.opval)), @@ -1090,7 +1102,7 @@ case 2: break; case 125: -#line 875 "perly.y" /* yacc.c:1646 */ +#line 887 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_convert_list(OP_ENTERSUB, OPf_STACKED, op_append_elem(OP_LIST, scalar((ps[-2].val.opval)), newMETHOP(OP_METHOD, 0, (ps[0].val.opval)))); @@ -1099,7 +1111,7 @@ case 2: break; case 126: -#line 880 "perly.y" /* yacc.c:1646 */ +#line 892 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_convert_list(OP_ENTERSUB, OPf_STACKED, op_append_elem(OP_LIST, op_prepend_elem(OP_LIST, (ps[-1].val.opval), (ps[0].val.opval)), @@ -1109,7 +1121,7 @@ case 2: break; case 127: -#line 886 "perly.y" /* yacc.c:1646 */ +#line 898 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_convert_list(OP_ENTERSUB, OPf_STACKED, op_append_elem(OP_LIST, op_prepend_elem(OP_LIST, (ps[-3].val.opval), (ps[-1].val.opval)), @@ -1119,26 +1131,26 @@ case 2: break; case 128: -#line 892 "perly.y" /* yacc.c:1646 */ +#line 904 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_convert_list((ps[-1].val.ival), 0, (ps[0].val.opval)); } break; case 129: -#line 894 "perly.y" /* yacc.c:1646 */ +#line 906 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_convert_list((ps[-3].val.ival), 0, (ps[-1].val.opval)); } break; case 130: -#line 896 "perly.y" /* yacc.c:1646 */ +#line 908 "perly.y" /* yacc.c:1646 */ { SvREFCNT_inc_simple_void(PL_compcv); (yyval.opval) = newANONATTRSUB((ps[-1].val.ival), 0, NULL, (ps[0].val.opval)); } break; case 131: -#line 899 "perly.y" /* yacc.c:1646 */ +#line 911 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, op_append_elem(OP_LIST, op_prepend_elem(OP_LIST, (ps[-1].val.opval), (ps[0].val.opval)), (ps[-4].val.opval))); @@ -1147,20 +1159,20 @@ case 2: break; case 134: -#line 914 "perly.y" /* yacc.c:1646 */ +#line 926 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP(OP_GELEM, 0, (ps[-4].val.opval), scalar((ps[-2].val.opval))); } break; case 135: -#line 916 "perly.y" /* yacc.c:1646 */ +#line 928 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP(OP_AELEM, 0, oopsAV((ps[-3].val.opval)), scalar((ps[-1].val.opval))); } break; case 136: -#line 919 "perly.y" /* yacc.c:1646 */ +#line 931 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP(OP_AELEM, 0, ref(newAVREF((ps[-4].val.opval)),OP_RV2AV), scalar((ps[-1].val.opval))); @@ -1169,7 +1181,7 @@ case 2: break; case 137: -#line 924 "perly.y" /* yacc.c:1646 */ +#line 936 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP(OP_AELEM, 0, ref(newAVREF((ps[-3].val.opval)),OP_RV2AV), scalar((ps[-1].val.opval))); @@ -1178,14 +1190,14 @@ case 2: break; case 138: -#line 929 "perly.y" /* yacc.c:1646 */ +#line 941 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP(OP_HELEM, 0, oopsHV((ps[-4].val.opval)), jmaybe((ps[-2].val.opval))); } break; case 139: -#line 932 "perly.y" /* yacc.c:1646 */ +#line 944 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP(OP_HELEM, 0, ref(newHVREF((ps[-5].val.opval)),OP_RV2HV), jmaybe((ps[-2].val.opval))); } @@ -1193,7 +1205,7 @@ case 2: break; case 140: -#line 936 "perly.y" /* yacc.c:1646 */ +#line 948 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP(OP_HELEM, 0, ref(newHVREF((ps[-4].val.opval)),OP_RV2HV), jmaybe((ps[-2].val.opval))); } @@ -1201,14 +1213,14 @@ case 2: break; case 141: -#line 940 "perly.y" /* yacc.c:1646 */ +#line 952 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, newCVREF(0, scalar((ps[-3].val.opval)))); } break; case 142: -#line 943 "perly.y" /* yacc.c:1646 */ +#line 955 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, op_append_elem(OP_LIST, (ps[-1].val.opval), newCVREF(0, scalar((ps[-4].val.opval))))); } @@ -1216,7 +1228,7 @@ case 2: break; case 143: -#line 948 "perly.y" /* yacc.c:1646 */ +#line 960 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, op_append_elem(OP_LIST, (ps[-1].val.opval), newCVREF(0, scalar((ps[-3].val.opval))))); } @@ -1224,44 +1236,44 @@ case 2: break; case 144: -#line 952 "perly.y" /* yacc.c:1646 */ +#line 964 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, newCVREF(0, scalar((ps[-2].val.opval)))); } break; case 145: -#line 955 "perly.y" /* yacc.c:1646 */ +#line 967 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newSLICEOP(0, (ps[-1].val.opval), (ps[-4].val.opval)); } break; case 146: -#line 957 "perly.y" /* yacc.c:1646 */ +#line 969 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newSLICEOP(0, (ps[-1].val.opval), (ps[-3].val.opval)); } break; case 147: -#line 959 "perly.y" /* yacc.c:1646 */ +#line 971 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newSLICEOP(0, (ps[-1].val.opval), NULL); } break; case 148: -#line 964 "perly.y" /* yacc.c:1646 */ +#line 976 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newASSIGNOP(OPf_STACKED, (ps[-2].val.opval), (ps[-1].val.ival), (ps[0].val.opval)); } break; case 149: -#line 966 "perly.y" /* yacc.c:1646 */ +#line 978 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); } break; case 150: -#line 968 "perly.y" /* yacc.c:1646 */ +#line 980 "perly.y" /* yacc.c:1646 */ { if ((ps[-1].val.ival) != OP_REPEAT) scalar((ps[-2].val.opval)); (yyval.opval) = newBINOP((ps[-1].val.ival), 0, (ps[-2].val.opval), scalar((ps[0].val.opval))); @@ -1270,111 +1282,111 @@ case 2: break; case 151: -#line 973 "perly.y" /* yacc.c:1646 */ +#line 985 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); } break; case 152: -#line 975 "perly.y" /* yacc.c:1646 */ +#line 987 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); } break; case 153: -#line 977 "perly.y" /* yacc.c:1646 */ +#line 989 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); } break; case 154: -#line 979 "perly.y" /* yacc.c:1646 */ +#line 991 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); } break; case 155: -#line 981 "perly.y" /* yacc.c:1646 */ +#line 993 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); } break; case 156: -#line 983 "perly.y" /* yacc.c:1646 */ +#line 995 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); } break; case 157: -#line 985 "perly.y" /* yacc.c:1646 */ +#line 997 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newRANGE((ps[-1].val.ival), scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); } break; case 158: -#line 987 "perly.y" /* yacc.c:1646 */ +#line 999 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[-2].val.opval), (ps[0].val.opval)); } break; case 159: -#line 989 "perly.y" /* yacc.c:1646 */ +#line 1001 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOGOP(OP_OR, 0, (ps[-2].val.opval), (ps[0].val.opval)); } break; case 160: -#line 991 "perly.y" /* yacc.c:1646 */ +#line 1003 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOGOP(OP_DOR, 0, (ps[-2].val.opval), (ps[0].val.opval)); } break; case 161: -#line 993 "perly.y" /* yacc.c:1646 */ +#line 1005 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = bind_match((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); } break; case 162: -#line 998 "perly.y" /* yacc.c:1646 */ +#line 1010 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_NEGATE, 0, scalar((ps[0].val.opval))); } break; case 163: -#line 1000 "perly.y" /* yacc.c:1646 */ +#line 1012 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 164: -#line 1003 "perly.y" /* yacc.c:1646 */ +#line 1015 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_NOT, 0, scalar((ps[0].val.opval))); } break; case 165: -#line 1005 "perly.y" /* yacc.c:1646 */ +#line 1017 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, scalar((ps[0].val.opval))); } break; case 166: -#line 1007 "perly.y" /* yacc.c:1646 */ +#line 1019 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_POSTINC, 0, op_lvalue(scalar((ps[-1].val.opval)), OP_POSTINC)); } break; case 167: -#line 1010 "perly.y" /* yacc.c:1646 */ +#line 1022 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_POSTDEC, 0, op_lvalue(scalar((ps[-1].val.opval)), OP_POSTDEC));} break; case 168: -#line 1013 "perly.y" /* yacc.c:1646 */ +#line 1025 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_convert_list(OP_JOIN, 0, op_append_elem( OP_LIST, @@ -1389,52 +1401,52 @@ case 2: break; case 169: -#line 1024 "perly.y" /* yacc.c:1646 */ +#line 1036 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_PREINC, 0, op_lvalue(scalar((ps[0].val.opval)), OP_PREINC)); } break; case 170: -#line 1027 "perly.y" /* yacc.c:1646 */ +#line 1039 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_PREDEC, 0, op_lvalue(scalar((ps[0].val.opval)), OP_PREDEC)); } break; case 171: -#line 1034 "perly.y" /* yacc.c:1646 */ +#line 1046 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newANONLIST((ps[-1].val.opval)); } break; case 172: -#line 1036 "perly.y" /* yacc.c:1646 */ +#line 1048 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newANONLIST(NULL);} break; case 173: -#line 1038 "perly.y" /* yacc.c:1646 */ +#line 1050 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newANONHASH((ps[-2].val.opval)); } break; case 174: -#line 1040 "perly.y" /* yacc.c:1646 */ +#line 1052 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newANONHASH(NULL); } break; case 175: -#line 1042 "perly.y" /* yacc.c:1646 */ +#line 1054 "perly.y" /* yacc.c:1646 */ { SvREFCNT_inc_simple_void(PL_compcv); (yyval.opval) = newANONATTRSUB((ps[-3].val.ival), (ps[-2].val.opval), (ps[-1].val.opval), (ps[0].val.opval)); } break; case 176: -#line 1045 "perly.y" /* yacc.c:1646 */ +#line 1057 "perly.y" /* yacc.c:1646 */ { OP *body; if (parser->copline > (line_t)(ps[-2].val.ival)) @@ -1448,103 +1460,103 @@ case 2: break; case 177: -#line 1059 "perly.y" /* yacc.c:1646 */ +#line 1071 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = dofile((ps[0].val.opval), (ps[-1].val.ival));} break; case 178: -#line 1061 "perly.y" /* yacc.c:1646 */ +#line 1073 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_NULL, OPf_SPECIAL, op_scope((ps[0].val.opval)));} break; case 183: -#line 1069 "perly.y" /* yacc.c:1646 */ +#line 1081 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newCONDOP(0, (ps[-4].val.opval), (ps[-2].val.opval), (ps[0].val.opval)); } break; case 184: -#line 1071 "perly.y" /* yacc.c:1646 */ +#line 1083 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_REFGEN, 0, (ps[0].val.opval)); } break; case 185: -#line 1073 "perly.y" /* yacc.c:1646 */ +#line 1085 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_REFGEN, 0, localize((ps[0].val.opval),1)); } break; case 186: -#line 1075 "perly.y" /* yacc.c:1646 */ +#line 1087 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 187: -#line 1077 "perly.y" /* yacc.c:1646 */ +#line 1089 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = localize((ps[0].val.opval),0); } break; case 188: -#line 1079 "perly.y" /* yacc.c:1646 */ +#line 1091 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = sawparens((ps[-1].val.opval)); } break; case 189: -#line 1081 "perly.y" /* yacc.c:1646 */ +#line 1093 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 190: -#line 1083 "perly.y" /* yacc.c:1646 */ +#line 1095 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = sawparens(newNULLLIST()); } break; case 191: -#line 1085 "perly.y" /* yacc.c:1646 */ +#line 1097 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 192: -#line 1087 "perly.y" /* yacc.c:1646 */ +#line 1099 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 193: -#line 1089 "perly.y" /* yacc.c:1646 */ +#line 1101 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 194: -#line 1091 "perly.y" /* yacc.c:1646 */ +#line 1103 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 195: -#line 1093 "perly.y" /* yacc.c:1646 */ +#line 1105 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_AV2ARYLEN, 0, ref((ps[0].val.opval), OP_AV2ARYLEN));} break; case 196: -#line 1095 "perly.y" /* yacc.c:1646 */ +#line 1107 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 197: -#line 1097 "perly.y" /* yacc.c:1646 */ +#line 1109 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_prepend_elem(OP_ASLICE, newOP(OP_PUSHMARK, 0), newLISTOP(OP_ASLICE, 0, @@ -1558,7 +1570,7 @@ case 2: break; case 198: -#line 1107 "perly.y" /* yacc.c:1646 */ +#line 1119 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_prepend_elem(OP_KVASLICE, newOP(OP_PUSHMARK, 0), newLISTOP(OP_KVASLICE, 0, @@ -1572,7 +1584,7 @@ case 2: break; case 199: -#line 1117 "perly.y" /* yacc.c:1646 */ +#line 1129 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_prepend_elem(OP_HSLICE, newOP(OP_PUSHMARK, 0), newLISTOP(OP_HSLICE, 0, @@ -1586,7 +1598,7 @@ case 2: break; case 200: -#line 1127 "perly.y" /* yacc.c:1646 */ +#line 1139 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_prepend_elem(OP_KVHSLICE, newOP(OP_PUSHMARK, 0), newLISTOP(OP_KVHSLICE, 0, @@ -1600,26 +1612,26 @@ case 2: break; case 201: -#line 1137 "perly.y" /* yacc.c:1646 */ +#line 1149 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 202: -#line 1139 "perly.y" /* yacc.c:1646 */ +#line 1151 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, 0, scalar((ps[0].val.opval))); } break; case 203: -#line 1141 "perly.y" /* yacc.c:1646 */ +#line 1153 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar((ps[-2].val.opval))); } break; case 204: -#line 1144 "perly.y" /* yacc.c:1646 */ +#line 1156 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, op_append_elem(OP_LIST, (ps[-1].val.opval), scalar((ps[-3].val.opval)))); @@ -1628,7 +1640,7 @@ case 2: break; case 205: -#line 1149 "perly.y" /* yacc.c:1646 */ +#line 1161 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, op_append_elem(OP_LIST, (ps[0].val.opval), scalar((ps[-1].val.opval)))); } @@ -1636,130 +1648,130 @@ case 2: break; case 206: -#line 1153 "perly.y" /* yacc.c:1646 */ +#line 1165 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newSVREF((ps[-3].val.opval)); } break; case 207: -#line 1155 "perly.y" /* yacc.c:1646 */ +#line 1167 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newAVREF((ps[-3].val.opval)); } break; case 208: -#line 1157 "perly.y" /* yacc.c:1646 */ +#line 1169 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newHVREF((ps[-3].val.opval)); } break; case 209: -#line 1159 "perly.y" /* yacc.c:1646 */ +#line 1171 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, 0, scalar(newCVREF((ps[-1].val.ival),(ps[-3].val.opval)))); } break; case 210: -#line 1162 "perly.y" /* yacc.c:1646 */ +#line 1174 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newGVREF(0,(ps[-3].val.opval)); } break; case 211: -#line 1164 "perly.y" /* yacc.c:1646 */ +#line 1176 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newOP((ps[0].val.ival), OPf_SPECIAL); PL_hints |= HINT_BLOCK_SCOPE; } break; case 212: -#line 1167 "perly.y" /* yacc.c:1646 */ +#line 1179 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOOPEX((ps[-1].val.ival),(ps[0].val.opval)); } break; case 213: -#line 1169 "perly.y" /* yacc.c:1646 */ +#line 1181 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_NOT, 0, scalar((ps[0].val.opval))); } break; case 214: -#line 1171 "perly.y" /* yacc.c:1646 */ +#line 1183 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newOP((ps[0].val.ival), 0); } break; case 215: -#line 1173 "perly.y" /* yacc.c:1646 */ +#line 1185 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, (ps[0].val.opval)); } break; case 216: -#line 1175 "perly.y" /* yacc.c:1646 */ +#line 1187 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, (ps[0].val.opval)); } break; case 217: -#line 1177 "perly.y" /* yacc.c:1646 */ +#line 1189 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newOP(OP_REQUIRE, (ps[0].val.ival) ? OPf_SPECIAL : 0); } break; case 218: -#line 1179 "perly.y" /* yacc.c:1646 */ +#line 1191 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_REQUIRE, (ps[-1].val.ival) ? OPf_SPECIAL : 0, (ps[0].val.opval)); } break; case 219: -#line 1181 "perly.y" /* yacc.c:1646 */ +#line 1193 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar((ps[0].val.opval))); } break; case 220: -#line 1183 "perly.y" /* yacc.c:1646 */ +#line 1195 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, op_append_elem(OP_LIST, (ps[0].val.opval), scalar((ps[-1].val.opval)))); } break; case 221: -#line 1186 "perly.y" /* yacc.c:1646 */ +#line 1198 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newOP((ps[0].val.ival), 0); } break; case 222: -#line 1188 "perly.y" /* yacc.c:1646 */ +#line 1200 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newOP((ps[-2].val.ival), 0);} break; case 223: -#line 1190 "perly.y" /* yacc.c:1646 */ +#line 1202 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 224: -#line 1192 "perly.y" /* yacc.c:1646 */ +#line 1204 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[-2].val.opval); } break; case 225: -#line 1194 "perly.y" /* yacc.c:1646 */ +#line 1206 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar((ps[0].val.opval))); } break; case 226: -#line 1196 "perly.y" /* yacc.c:1646 */ +#line 1208 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = ((ps[-2].val.ival) == OP_NOT) ? newUNOP((ps[-2].val.ival), 0, newSVOP(OP_CONST, 0, newSViv(0))) : newOP((ps[-2].val.ival), OPf_SPECIAL); } @@ -1767,13 +1779,13 @@ case 2: break; case 227: -#line 1200 "perly.y" /* yacc.c:1646 */ +#line 1212 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP((ps[-3].val.ival), 0, (ps[-1].val.opval)); } break; case 228: -#line 1202 "perly.y" /* yacc.c:1646 */ +#line 1214 "perly.y" /* yacc.c:1646 */ { if ( (ps[0].val.opval)->op_type != OP_TRANS && (ps[0].val.opval)->op_type != OP_TRANSR @@ -1788,115 +1800,115 @@ case 2: break; case 229: -#line 1213 "perly.y" /* yacc.c:1646 */ +#line 1225 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = pmruntime((ps[-5].val.opval), (ps[-2].val.opval), (ps[-1].val.opval), 1, (ps[-4].val.ival)); } break; case 233: -#line 1221 "perly.y" /* yacc.c:1646 */ +#line 1233 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = my_attrs((ps[-1].val.opval),(ps[0].val.opval)); } break; case 234: -#line 1223 "perly.y" /* yacc.c:1646 */ +#line 1235 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = localize((ps[0].val.opval),1); } break; case 235: -#line 1225 "perly.y" /* yacc.c:1646 */ +#line 1237 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_REFGEN, 0, my_attrs((ps[-1].val.opval),(ps[0].val.opval))); } break; case 236: -#line 1230 "perly.y" /* yacc.c:1646 */ +#line 1242 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = sawparens((ps[-1].val.opval)); } break; case 237: -#line 1232 "perly.y" /* yacc.c:1646 */ +#line 1244 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = sawparens(newNULLLIST()); } break; case 238: -#line 1235 "perly.y" /* yacc.c:1646 */ +#line 1247 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 239: -#line 1237 "perly.y" /* yacc.c:1646 */ +#line 1249 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 240: -#line 1239 "perly.y" /* yacc.c:1646 */ +#line 1251 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 241: -#line 1244 "perly.y" /* yacc.c:1646 */ +#line 1256 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 242: -#line 1246 "perly.y" /* yacc.c:1646 */ +#line 1258 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 243: -#line 1250 "perly.y" /* yacc.c:1646 */ +#line 1262 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 244: -#line 1252 "perly.y" /* yacc.c:1646 */ +#line 1264 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 245: -#line 1256 "perly.y" /* yacc.c:1646 */ +#line 1268 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; case 246: -#line 1258 "perly.y" /* yacc.c:1646 */ +#line 1270 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 247: -#line 1264 "perly.y" /* yacc.c:1646 */ +#line 1276 "perly.y" /* yacc.c:1646 */ { parser->in_my = 0; (yyval.opval) = my((ps[0].val.opval)); } break; case 255: -#line 1281 "perly.y" /* yacc.c:1646 */ +#line 1293 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newCVREF((ps[-1].val.ival),(ps[0].val.opval)); } break; case 256: -#line 1285 "perly.y" /* yacc.c:1646 */ +#line 1297 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newSVREF((ps[0].val.opval)); } break; case 257: -#line 1289 "perly.y" /* yacc.c:1646 */ +#line 1301 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newAVREF((ps[0].val.opval)); if ((yyval.opval)) (yyval.opval)->op_private |= (ps[-1].val.ival); } @@ -1904,7 +1916,7 @@ case 2: break; case 258: -#line 1295 "perly.y" /* yacc.c:1646 */ +#line 1307 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newHVREF((ps[0].val.opval)); if ((yyval.opval)) (yyval.opval)->op_private |= (ps[-1].val.ival); } @@ -1912,61 +1924,61 @@ case 2: break; case 259: -#line 1301 "perly.y" /* yacc.c:1646 */ +#line 1313 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newAVREF((ps[0].val.opval)); } break; case 260: -#line 1303 "perly.y" /* yacc.c:1646 */ +#line 1315 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newAVREF((ps[-3].val.opval)); } break; case 261: -#line 1307 "perly.y" /* yacc.c:1646 */ +#line 1319 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newGVREF(0,(ps[0].val.opval)); } break; case 263: -#line 1312 "perly.y" /* yacc.c:1646 */ +#line 1324 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newAVREF((ps[-2].val.opval)); } break; case 265: -#line 1317 "perly.y" /* yacc.c:1646 */ +#line 1329 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newHVREF((ps[-2].val.opval)); } break; case 267: -#line 1322 "perly.y" /* yacc.c:1646 */ +#line 1334 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newGVREF(0,(ps[-2].val.opval)); } break; case 268: -#line 1327 "perly.y" /* yacc.c:1646 */ +#line 1339 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = scalar((ps[0].val.opval)); } break; case 269: -#line 1329 "perly.y" /* yacc.c:1646 */ +#line 1341 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = scalar((ps[0].val.opval)); } break; case 270: -#line 1331 "perly.y" /* yacc.c:1646 */ +#line 1343 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_scope((ps[0].val.opval)); } break; case 271: -#line 1334 "perly.y" /* yacc.c:1646 */ +#line 1346 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; @@ -1977,6 +1989,6 @@ case 2: /* Generated from: - * f62d35e9a10a10071f1ac20676ddc12abcffbef44a24ef694c36201e994d0900 perly.y + * 1d0c087affbf85a8f1482eb4d34eefd435666c6d9e1cb4d7f9d1aeb62b37e907 perly.y * b6fae5748f9bef6db4740aa5e122b84ac5181852d42474d0ecad621fa4253306 regen_perly.pl * ex: set ro: */ diff --git a/perly.h b/perly.h index 4ac8572..02561f7 100644 --- a/perly.h +++ b/perly.h @@ -180,6 +180,6 @@ int yyparse (void); /* Generated from: - * f62d35e9a10a10071f1ac20676ddc12abcffbef44a24ef694c36201e994d0900 perly.y + * 1d0c087affbf85a8f1482eb4d34eefd435666c6d9e1cb4d7f9d1aeb62b37e907 perly.y * b6fae5748f9bef6db4740aa5e122b84ac5181852d42474d0ecad621fa4253306 regen_perly.pl * ex: set ro: */ diff --git a/perly.tab b/perly.tab index cb73d61..001de77 100644 --- a/perly.tab +++ b/perly.tab @@ -73,30 +73,30 @@ static const yytype_uint16 yyrline[] = 165, 164, 178, 177, 190, 198, 206, 210, 218, 224, 225, 235, 236, 245, 249, 253, 257, 264, 266, 277, 276, 310, 309, 348, 356, 355, 364, 370, 376, 381, - 383, 390, 398, 400, 397, 417, 422, 429, 428, 443, - 451, 457, 464, 463, 478, 482, 487, 495, 513, 514, - 519, 521, 523, 525, 527, 529, 531, 534, 540, 541, - 546, 557, 558, 564, 570, 571, 576, 579, 583, 588, - 592, 596, 597, 601, 607, 612, 617, 618, 623, 624, - 629, 630, 632, 637, 639, 651, 652, 657, 659, 663, - 683, 684, 686, 692, 757, 759, 765, 767, 771, 777, - 778, 783, 782, 834, 835, 839, 841, 843, 845, 849, - 851, 856, 860, 864, 868, 874, 879, 885, 891, 893, - 896, 895, 906, 907, 911, 915, 918, 923, 928, 931, - 935, 939, 942, 947, 951, 954, 956, 958, 963, 965, - 967, 972, 974, 976, 978, 980, 982, 984, 986, 988, - 990, 992, 997, 999, 1002, 1004, 1006, 1009, 1012, 1023, - 1026, 1033, 1035, 1037, 1039, 1041, 1044, 1058, 1060, 1064, - 1065, 1066, 1067, 1068, 1070, 1072, 1074, 1076, 1078, 1080, - 1082, 1084, 1086, 1088, 1090, 1092, 1094, 1096, 1106, 1116, - 1126, 1136, 1138, 1140, 1143, 1148, 1152, 1154, 1156, 1158, - 1161, 1163, 1166, 1168, 1170, 1172, 1174, 1176, 1178, 1180, - 1182, 1185, 1187, 1189, 1191, 1193, 1195, 1199, 1202, 1201, - 1214, 1215, 1216, 1220, 1222, 1224, 1229, 1231, 1234, 1236, - 1238, 1243, 1245, 1250, 1251, 1256, 1257, 1263, 1267, 1268, - 1269, 1272, 1273, 1276, 1277, 1280, 1284, 1288, 1294, 1300, - 1302, 1306, 1310, 1311, 1315, 1316, 1320, 1321, 1326, 1328, - 1330, 1333 + 389, 396, 404, 406, 403, 423, 428, 435, 434, 449, + 457, 463, 470, 469, 484, 488, 493, 501, 519, 520, + 525, 527, 529, 531, 533, 535, 537, 540, 552, 553, + 558, 569, 570, 576, 582, 583, 588, 591, 595, 600, + 604, 608, 609, 613, 619, 624, 629, 630, 635, 636, + 641, 642, 644, 649, 651, 663, 664, 669, 671, 675, + 695, 696, 698, 704, 769, 771, 777, 779, 783, 789, + 790, 795, 794, 846, 847, 851, 853, 855, 857, 861, + 863, 868, 872, 876, 880, 886, 891, 897, 903, 905, + 908, 907, 918, 919, 923, 927, 930, 935, 940, 943, + 947, 951, 954, 959, 963, 966, 968, 970, 975, 977, + 979, 984, 986, 988, 990, 992, 994, 996, 998, 1000, + 1002, 1004, 1009, 1011, 1014, 1016, 1018, 1021, 1024, 1035, + 1038, 1045, 1047, 1049, 1051, 1053, 1056, 1070, 1072, 1076, + 1077, 1078, 1079, 1080, 1082, 1084, 1086, 1088, 1090, 1092, + 1094, 1096, 1098, 1100, 1102, 1104, 1106, 1108, 1118, 1128, + 1138, 1148, 1150, 1152, 1155, 1160, 1164, 1166, 1168, 1170, + 1173, 1175, 1178, 1180, 1182, 1184, 1186, 1188, 1190, 1192, + 1194, 1197, 1199, 1201, 1203, 1205, 1207, 1211, 1214, 1213, + 1226, 1227, 1228, 1232, 1234, 1236, 1241, 1243, 1246, 1248, + 1250, 1255, 1257, 1262, 1263, 1268, 1269, 1275, 1279, 1280, + 1281, 1284, 1285, 1288, 1289, 1292, 1296, 1300, 1306, 1312, + 1314, 1318, 1322, 1323, 1327, 1328, 1332, 1333, 1338, 1340, + 1342, 1345 }; #endif @@ -1103,6 +1103,6 @@ static const toketypes yy_type_tab[] = }; /* Generated from: - * f62d35e9a10a10071f1ac20676ddc12abcffbef44a24ef694c36201e994d0900 perly.y + * 1d0c087affbf85a8f1482eb4d34eefd435666c6d9e1cb4d7f9d1aeb62b37e907 perly.y * b6fae5748f9bef6db4740aa5e122b84ac5181852d42474d0ecad621fa4253306 regen_perly.pl * ex: set ro: */ diff --git a/perly.y b/perly.y index 8191d82..4ef8478 100644 --- a/perly.y +++ b/perly.y @@ -379,7 +379,13 @@ barestmt: PLUGSTMT parser->copline = (line_t)$1; } | WHERESO '(' remember mexpr ')' mblock - { $$ = block_end($3, newWHERESOOP($4, op_scope($6))); } + { + OP *cond = $4; + if ($1) + cond = newBINOP(OP_SMARTMATCH, 0, newDEFSVOP(), + scalar(cond)); + $$ = block_end($3, newWHERESOOP(cond, op_scope($6))); + } | WHILE '(' remember texpr ')' mintro mblock cont { $$ = block_end($3, @@ -532,7 +538,13 @@ sideff : error { $$ = newFOROP(0, NULL, $3, $1, NULL); parser->copline = (line_t)$2; } | expr WHERESO expr - { $$ = newWHERESOOP($3, op_scope($1)); } + { + OP *cond = $3; + if ($2) + cond = newBINOP(OP_SMARTMATCH, 0, newDEFSVOP(), + scalar(cond)); + $$ = newWHERESOOP(cond, op_scope($1)); + } ; /* else and elsif blocks */ diff --git a/pod/perldiag.pod b/pod/perldiag.pod index f5e678c..2ce6668 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -824,7 +824,8 @@ but then $foo no longer contains a glob. =item Can't "continue" outside a whereso block -(F) You called C, but you're not inside a C block. +(F) You called C, but you're not inside a C or +C block. =item Can't create pipe mailbox @@ -1078,13 +1079,14 @@ L. =item Can't leave "whereso" outside a loop block -(F) Control reached the end of a C block that isn't inside any -loop (including a C block). An implicit C occurs here, -which requires a loop to jump to. You probably wanted the C to be -inside a C block. Note that you won't get this error if the match -controlling the C fails, or if you use an explicit C to -avoid reaching the end of the block. But if you rely on not reaching the -implicit C then you probably didn't want C, but rather C. +(F) Control reached the end of a C or C block that +isn't inside any loop (including a C block). An implicit C +occurs here, which requires a loop to jump to. You probably wanted the +C or C to be inside a C block. Note that you +won't get this error if the match controlling the C or C +fails, or if you use an explicit C to avoid reaching the end +of the block. But if you rely on not reaching the implicit C +then you probably didn't want C or C, but rather C. =item Can't linearize anonymous symbol table @@ -7414,6 +7416,12 @@ but in actual fact, you got So put in parentheses to say what you really mean. +=item whereis is experimental + +(S experimental::smartmatch) C is experimental, and its behavior +may change or it may even be removed in any future release of perl. +See the explanation under L. + =item whereso is experimental (S experimental::smartmatch) C is experimental, and its behavior diff --git a/pod/perlexperiment.pod b/pod/perlexperiment.pod index f750fd2..98b6b1a 100644 --- a/pod/perlexperiment.pod +++ b/pod/perlexperiment.pod @@ -30,8 +30,7 @@ L<[perl #119317]|https://rt.perl.org/rt3/Ticket/Display.html?id=119317>. For historical reasons, the single experiment covers both the smart match operator (C<~~>) and the switch-related compound statements -(C/C), which apart from the shared warning category are now -unrelated in behaviour. +(C/C/C). =item Pluggable keywords diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod index c304c03..c0536e0 100644 --- a/pod/perlfunc.pod +++ b/pod/perlfunc.pod @@ -421,8 +421,8 @@ L|/time>, L|/times> C, C, C, C, C, C, C<__DATA__>, C, C, C, C, C, C<__END__>, C, C, C, C, C, C, C, C, C, -C, C, C, C, C, C, C, C, -C, C, C +C, C, C, C, C, C, C, +C, C, C, C, C =back @@ -1318,7 +1318,8 @@ using an empty one, logically enough, so L|/next LABEL> goes directly back to check the condition at the top of the loop. When there is no BLOCK, L|/continue BLOCK> is a function -that exits the current C block, avoiding the implicit C +that exits the current C or C block, +avoiding the implicit C that happens when execution reaches the end of such a block. In Perl 5.14 and earlier, this form of L|/continue BLOCK> was only available when the @@ -10085,6 +10086,8 @@ Statements">. =item given +=item whereis + =item whereso These flow-control keywords related to the experimental switch feature are diff --git a/pod/perlsyn.pod b/pod/perlsyn.pod index ae7bb03..7d41ecc 100644 --- a/pod/perlsyn.pod +++ b/pod/perlsyn.pod @@ -118,7 +118,7 @@ as the last item in a statement. =head2 Statement Modifiers X X X X X -X X X X +X X X X X Any simple statement may optionally be followed by a I modifier, just before the terminating semicolon (or block ending). The possible @@ -130,6 +130,7 @@ modifiers are: until EXPR for LIST foreach LIST + whereis EXPR whereso EXPR The C following the modifier is referred to as the "condition". @@ -211,12 +212,13 @@ it. Future versions of perl might do something different from the version of perl you try it out on. Here be dragons. X -The C modifier is an experimental feature that first appeared -with this spelling in Perl 5.28. -To use it, you should include a C -declaration, or a declaration that implies it. It behaves like the full -C statement with block, described in L below. -It executes the statement only if the I is true. If the statement +The C and C modifiers are an experimental feature +that first appeared with this spelling in Perl 5.28. To use them, you +should include a C declaration, or a declaration +that implies it. They behave like the full C or C +statement with block, described in L below. +They executes the statement only if the I is true for C, +or C<$_> smartmatches the I for C. If the statement executes, control then implicitly jumps to the end of the dynamically enclosing loop (usually a C block). @@ -246,6 +248,7 @@ The following compound statements may be used to control flow: given (EXPR) BLOCK + whereis (EXPR) BLOCK whereso (EXPR) BLOCK LABEL while (EXPR) BLOCK @@ -267,7 +270,7 @@ The following compound statements may be used to control flow: PHASE BLOCK -The experimental C and C statements are I, C, and C statements are I; see L below for how to do so, and the attendant caveats. @@ -606,7 +609,7 @@ described immediately below remains experimental. =head2 Switch Statements -X X X X +X X X X X C, C, and related keywords make up an experimental feature that first appeared in Perl 5.10, but behaved quite differently from @@ -620,18 +623,19 @@ example: use v5.14; -Under the "switch" feature, Perl gains the experimental keywords C -and C. Starting from Perl 5.16, one can +Under the "switch" feature, Perl gains the experimental keywords C, +C, and C. Starting from Perl 5.16, one can prefix the switch keywords with C to access the feature without a C statement. The "switch" feature is considered highly experimental; it is subject -to change with little notice. Uses of the C and C keywords -will by default warn about their experimental status. Due to historical -links between the two features, these warnings are in the same category -as warnings about the C<~~> (smartmatch) operator being experimental. +to change with little notice. Uses of the C, C, and +C keywords will by default warn about their experimental status. +These warnings are in the same category as warnings about the C<~~> +(smartmatch) operator being experimental. -The keywords C and C are analogous to C and C +The keywords C and C or C +are analogous to C and C in C. They're meant to be used together, but can actually be used independently and mixed with other kinds of compound statement. @@ -649,6 +653,14 @@ following statement. If the argument was true, it executes the block, then implicitly performs a C, jumping to the end of the closest dynamically enclosing C block or other kind of loop. +C evaluates its argument and uses it as a smartmatch object, +checking whether C<$_> matches it. If C<$_> did not match then it does +not execute its block, and proceeds to the following statement. If C<$_> +did match, it executes the block, then implicitly performs a C, +jumping to the end of the closest dynamically enclosing C block +or other kind of loop. This is exactly like C, except for the +implicit use of smartmatch. + Putting this together, the code in the previous section could be rewritten as @@ -671,7 +683,7 @@ less punctuation as $nothing = 1; } -You can use the C keyword to exit a C +You can use the C keyword to exit a C or C block, proceeding to the following statement. This is most commonly done last thing inside the block, to override the implicit C. For example @@ -695,7 +707,7 @@ An empty list as soon as an explicit C or C is encountered. =item * The value of the last evaluated expression of the successful -C clause, if there happens to be one. +C or C clause, if there happens to be one. =item * @@ -706,12 +718,13 @@ condition is true. In both last cases, the last expression is evaluated in the context that was applied to the C block. -Note that, unlike C and C, failed C statements always +Note that, unlike C and C, +failed C/C statements always evaluate to an empty list. -On versions of Perl preceding Perl 5.28, C and C behave -quite differently from their present behaviour. If your code needs to -run on older versions, avoid C and C. +On versions of Perl preceding Perl 5.28, C and the related keywords +behave quite differently from their present behaviour. If your code needs +to run on older versions, avoid C, C, and C. =head2 Goto X diff --git a/regen/keywords.pl b/regen/keywords.pl index 6bebf7d..b794a6b 100755 --- a/regen/keywords.pl +++ b/regen/keywords.pl @@ -39,6 +39,7 @@ my %feature_kw = ( state => 'state', say => 'say', given => 'switch', + whereis => 'switch', whereso => 'switch', # continue is already a keyword evalbytes => 'evalbytes', @@ -352,6 +353,7 @@ __END__ -waitpid -wantarray -warn ++whereis +whereso +while -write diff --git a/t/op/coreamp.t b/t/op/coreamp.t index 52e2fd5..fa11bea 100644 --- a/t/op/coreamp.t +++ b/t/op/coreamp.t @@ -1156,7 +1156,8 @@ like $@, qr'^Undefined format "STDOUT" called', e)|e(?:ls(?:if|e)|val|q)|g(?:[et]|iven|oto |rep)|u(?:n(?:less|til)|se)|l(?:(?:as)?t|ocal|e)|re (?:quire|turn|do)|__(?:DATA|END)__|for(?:each|mat)?|(?: - AUTOLOA|EN)D|n(?:e(?:xt)?|o)|C(?:HECK|ORE)|wh(?:ile|ereso) + AUTOLOA|EN)D|n(?:e(?:xt)?|o)|C(?:HECK|ORE) + |wh(?:ile|ere(?:is|so)) |(?:ou?|t)r|m(?:ap|y)?|UNITCHECK|q[qrwx]?|x(?:or)?|DEST ROY|BEGIN|INIT|and|cmp|if|y)\z/x; $tests ++; diff --git a/t/op/coresubs.t b/t/op/coresubs.t index 38c6bc4..6946496 100644 --- a/t/op/coresubs.t +++ b/t/op/coresubs.t @@ -20,7 +20,7 @@ my %unsupported = map +($_=>1), qw ( format ge given goto grep gt if last le local lt m map my ne next no or our package print printf q qq qr qw qx redo require return s say sort state sub tr unless until use - whereso while x xor y + whereis whereso while x xor y ); my %args_for = ( dbmopen => '%1,$2,$3', diff --git a/t/op/cproto.t b/t/op/cproto.t index c0951b9..11cd9ad 100644 --- a/t/op/cproto.t +++ b/t/op/cproto.t @@ -7,7 +7,7 @@ BEGIN { set_up_inc('../lib'); } -plan tests => 252; +plan tests => 253; while () { chomp; @@ -276,6 +276,7 @@ wait () waitpid ($$) wantarray () warn (@) +whereis undef whereso undef while undef write (;*) diff --git a/t/op/whereis.t b/t/op/whereis.t new file mode 100644 index 0000000..522e7d8 --- /dev/null +++ b/t/op/whereis.t @@ -0,0 +1,78 @@ +#!./perl + +BEGIN { + chdir 't' if -d 't'; + require './test.pl'; + set_up_inc('../lib'); +} +use strict; +use warnings; +no warnings qw(uninitialized experimental::smartmatch); + +plan tests => 19; + +foreach(3) { + CORE::whereis(qr/\A3\z/) { + pass "CORE::whereis without feature flag"; + } +} + +use feature 'switch'; + +foreach(3) { + CORE::whereis(qr/\A3\z/) { + pass "CORE::whereis with feature flag"; + } +} + +foreach(3) { + whereis(qr/\A3\z/) { + pass "whereis with feature flag"; + } +} + +package MatchAbc { use overload "~~" => sub { $_[1] eq "abc" }, fallback => 1; } +my $matchabc = bless({}, "MatchAbc"); +my $regexpabc = qr/\Aabc\z/; + +foreach("abc") { + my $x = "foo"; + is($x, "foo", "whereis lexical scope not started yet"); + whereis(my $x = $matchabc) { + is($x, $matchabc, "whereis lexical scope starts"); + } + is($x, "foo", "whereis lexical scope ends"); +} + +foreach my $matcher (undef, 0, 1, [], {}, sub { 1 }) { + my $res = eval { + my $r; + foreach("abc") { + whereis($matcher) { + $r = 1; + } + $r = 0; + } + $r; + }; + like $@, qr/\ACannot smart match without a matcher object /; +} + +foreach my $matcher ($matchabc, $regexpabc) { + foreach my $matchee (qw(abc xyz)) { + my $res = eval { + my $r; + foreach($matchee) { + whereis($matcher) { + $r = 1; + } + $r = 0; + } + $r; + }; + is $@, ""; + is !!$res, $matchee eq "abc"; + } +} + +1; diff --git a/toke.c b/toke.c index fa72938..e36d8a1 100644 --- a/toke.c +++ b/toke.c @@ -8844,13 +8844,15 @@ Perl_yylex(pTHX) case KEY_vec: LOP(OP_VEC,XTERM); + case KEY_whereis: case KEY_whereso: if (!PL_lex_allbrackets && PL_lex_fakeeof >= LEX_FAKEEOF_NONEXPR) return REPORT(0); - pl_yylval.ival = CopLINE(PL_curcop); + pl_yylval.ival = tmp == KEY_whereis; + /* diag_listed_as: whereso is experimental */ Perl_ck_warner_d(aTHX_ packWARN(WARN_EXPERIMENTAL__SMARTMATCH), - "whereso is experimental"); + "%" UTF8f " is experimental", UTF8fARG(UTF, len, PL_tokenbuf)); OPERATOR(WHERESO); case KEY_while: -- 1.8.3.1