diff options
67 files changed, 5146 insertions, 3388 deletions
@@ -5672,7 +5672,6 @@ t/op/fork.t See if fork works t/op/fresh_perl_utf8.t UTF8 tests for pads and gvs t/op/getpid.t See if $$ and getppid work with threads t/op/getppid.t See if getppid works -t/op/given.t See if given works t/op/glob.t See if <*> works t/op/gmagic.t See if GMAGIC works t/op/goto.t See if goto works @@ -5814,8 +5813,6 @@ 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) t/op/yadayada.t See if ... works @@ -721,9 +721,10 @@ struct block_loop { -/* whereso context */ -struct block_whereso { +/* given/when context */ +struct block_givwhen { OP *leave_op; + SV *defsv_save; /* the original $_ */ }; @@ -747,7 +748,7 @@ struct block { struct block_format blku_format; struct block_eval blku_eval; struct block_loop blku_loop; - struct block_whereso blku_whereso; + struct block_givwhen blku_givwhen; } blk_u; }; #define blk_oldsp cx_u.cx_blk.blku_oldsp @@ -763,7 +764,7 @@ struct block { #define blk_format cx_u.cx_blk.blk_u.blku_format #define blk_eval cx_u.cx_blk.blk_u.blku_eval #define blk_loop cx_u.cx_blk.blk_u.blku_loop -#define blk_whereso cx_u.cx_blk.blk_u.blku_whereso +#define blk_givwhen cx_u.cx_blk.blk_u.blku_givwhen #define CX_DEBUG(cx, action) \ DEBUG_l( \ @@ -856,11 +857,16 @@ struct context { and a static array of context names in pp_ctl.c */ #define CXTYPEMASK 0xf #define CXt_NULL 0 /* currently only used for sort BLOCK */ -#define CXt_WHERESO 1 +#define CXt_WHEN 1 #define CXt_BLOCK 2 -/* be careful of the ordering of these six. Macros like CxTYPE_is_LOOP, +/* When micro-optimising :-) keep GIVEN next to the LOOPs, as these 5 share a + jump table in pp_ctl.c + The first 4 don't have a 'case' in at least one switch statement in pp_ctl.c +*/ +#define CXt_GIVEN 3 + +/* be careful of the ordering of these five. Macros like CxTYPE_is_LOOP, * CxFOREACH compare ranges */ -#define CXt_LOOP_GIVEN 3 /* given (...) { ...; } */ #define CXt_LOOP_ARY 4 /* for (@ary) { ...; } */ #define CXt_LOOP_LAZYSV 5 /* for ('a'..'z') { ...; } */ #define CXt_LOOP_LAZYIV 6 /* for (1..9) { ...; } */ @@ -886,6 +892,8 @@ struct context { /* private flags for CXt_LOOP */ +/* this is only set in conjunction with CXp_FOR_GV */ +#define CXp_FOR_DEF 0x10 /* foreach using $_ */ /* these 3 are mutually exclusive */ #define CXp_FOR_LVREF 0x20 /* foreach using \$var */ #define CXp_FOR_GV 0x40 /* foreach using package var */ @@ -897,7 +905,7 @@ struct context { #define CXp_ONCE 0x10 /* What was sbu_once in struct subst */ #define CxTYPE(c) ((c)->cx_type & CXTYPEMASK) -#define CxTYPE_is_LOOP(c) ( CxTYPE(cx) >= CXt_LOOP_GIVEN \ +#define CxTYPE_is_LOOP(c) ( CxTYPE(cx) >= CXt_LOOP_ARY \ && CxTYPE(cx) <= CXt_LOOP_PLAIN) #define CxMULTICALL(c) ((c)->cx_type & CXp_MULTICALL) #define CxREALEVAL(c) (((c)->cx_type & (CXTYPEMASK|CXp_REAL)) \ @@ -1200,7 +1200,6 @@ S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o) case OP_ENTERITER: case OP_ENTERLOOP: - case OP_ENTERGIVEN: S_opdump_indent(aTHX_ o, level, bar, file, "REDO"); S_opdump_link(aTHX_ cLOOPo->op_redoop, file); S_opdump_indent(aTHX_ o, level, bar, file, "NEXT"); @@ -1222,7 +1221,8 @@ S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o) case OP_DORASSIGN: case OP_ANDASSIGN: case OP_ARGDEFELEM: - case OP_ENTERWHERESO: + case OP_ENTERGIVEN: + case OP_ENTERWHEN: case OP_ENTERTRY: case OP_ONCE: S_opdump_indent(aTHX_ o, level, bar, file, "OTHER"); @@ -1129,7 +1129,7 @@ Apd |CV* |newCONSTSUB_flags|NULLOK HV* stash \ |U32 flags|NULLOK SV* sv Ap |void |newFORM |I32 floor|NULLOK OP* o|NULLOK OP* block ApdR |OP* |newFOROP |I32 flags|NULLOK OP* sv|NN OP* expr|NULLOK OP* block|NULLOK OP* cont -ApdR |OP* |newGIVENOP |NN OP* topic|NN OP* block|PADOFFSET defsv_off +ApdR |OP* |newGIVENOP |NN OP* cond|NN OP* block|PADOFFSET defsv_off ApdR |OP* |newLOGOP |I32 optype|I32 flags|NN OP *first|NN OP *other pM |LOGOP* |alloc_LOGOP |I32 type|NULLOK OP *first|NULLOK OP *other ApdR |OP* |newLOOPEX |I32 type|NN OP* label @@ -1198,7 +1198,7 @@ ApdR |SV* |newSV_type |const svtype type ApdR |OP* |newUNOP |I32 type|I32 flags|NULLOK OP* first ApdR |OP* |newUNOP_AUX |I32 type|I32 flags|NULLOK OP* first \ |NULLOK UNOP_AUX_item *aux -ApdR |OP* |newWHERESOOP |NN OP* cond|NN OP* block +ApdR |OP* |newWHENOP |NULLOK OP* cond|NN OP* block ApdR |OP* |newWHILEOP |I32 flags|I32 debuggable|NULLOK LOOP* loop \ |NULLOK OP* expr|NULLOK OP* block|NULLOK OP* cont \ |I32 has_my @@ -2172,6 +2172,11 @@ s |void |no_bareword_allowed|NN OP *o sR |OP* |no_fh_allowed|NN OP *o sR |OP* |too_few_arguments_pv|NN OP *o|NN const char* name|U32 flags s |OP* |too_many_arguments_pv|NN OP *o|NN const char* name|U32 flags +s |bool |looks_like_bool|NN const OP* o +s |OP* |newGIVWHENOP |NULLOK OP* cond|NN OP *block \ + |I32 enter_opcode|I32 leave_opcode \ + |PADOFFSET entertarg +s |OP* |ref_array_or_hash|NULLOK OP* cond s |bool |process_special_blocks |I32 floor \ |NN const char *const fullname\ |NN GV *const gv|NN CV *const cv @@ -2259,10 +2264,11 @@ sR |OP* |dofindlabel |NN OP *o|NN const char *label|STRLEN len \ s |MAGIC *|doparseform |NN SV *sv snR |bool |num_overflow |NV value|I32 fldsize|I32 frcsize sR |I32 |dopoptoeval |I32 startingblock +sR |I32 |dopoptogivenfor|I32 startingblock sR |I32 |dopoptolabel |NN const char *label|STRLEN len|U32 flags sR |I32 |dopoptoloop |I32 startingblock sR |I32 |dopoptosub_at |NN const PERL_CONTEXT* cxstk|I32 startingblock -sR |I32 |dopoptowhereso |I32 startingblock +sR |I32 |dopoptowhen |I32 startingblock s |void |save_lines |NULLOK AV *array|NN SV *sv s |bool |doeval_compile |U8 gimme \ |NULLOK CV* outside|U32 seq|NULLOK HV* hh @@ -2272,6 +2278,11 @@ sR |PerlIO *|doopen_pm |NN SV *name #endif iRn |bool |path_is_searchable|NN const char *name sR |I32 |run_user_filter|int idx|NN SV *buf_sv|int maxlen +sR |PMOP* |make_matcher |NN REGEXP* re +sR |bool |matcher_matches_sv|NN PMOP* matcher|NN SV* sv +s |void |destroy_matcher|NN PMOP* matcher +s |OP* |do_smartmatch |NULLOK HV* seen_this \ + |NULLOK HV* seen_other|const bool copied #endif #if defined(PERL_IN_PP_HOT_C) @@ -3190,10 +3201,11 @@ AiM |void |cx_popeval |NN PERL_CONTEXT *cx AiM |void |cx_pushloop_plain|NN PERL_CONTEXT *cx AiM |void |cx_pushloop_for |NN PERL_CONTEXT *cx \ |NN void *itervarp|NULLOK SV *itersave -AiM |void |cx_pushloop_given |NN PERL_CONTEXT *cx|NULLOK SV *orig_defsv AiM |void |cx_poploop |NN PERL_CONTEXT *cx -AiM |void |cx_pushwhereso |NN PERL_CONTEXT *cx -AiM |void |cx_popwhereso |NN PERL_CONTEXT *cx +AiM |void |cx_pushwhen |NN PERL_CONTEXT *cx +AiM |void |cx_popwhen |NN PERL_CONTEXT *cx +AiM |void |cx_pushgiven |NN PERL_CONTEXT *cx|NULLOK SV *orig_defsv +AiM |void |cx_popgiven |NN PERL_CONTEXT *cx #endif #ifdef USE_DTRACE @@ -422,7 +422,7 @@ #define newSVuv(a) Perl_newSVuv(aTHX_ a) #define newUNOP(a,b,c) Perl_newUNOP(aTHX_ a,b,c) #define newUNOP_AUX(a,b,c,d) Perl_newUNOP_AUX(aTHX_ a,b,c,d) -#define newWHERESOOP(a,b) Perl_newWHERESOOP(aTHX_ a,b) +#define newWHENOP(a,b) Perl_newWHENOP(aTHX_ a,b) #define newWHILEOP(a,b,c,d,e,f,g) Perl_newWHILEOP(aTHX_ a,b,c,d,e,f,g) #define newXS(a,b,c) Perl_newXS(aTHX_ a,b,c) #define newXS_flags(a,b,c,d,e) Perl_newXS_flags(aTHX_ a,b,c,d,e) @@ -785,19 +785,20 @@ #define cx_popblock(a) S_cx_popblock(aTHX_ a) #define cx_popeval(a) S_cx_popeval(aTHX_ a) #define cx_popformat(a) S_cx_popformat(aTHX_ a) +#define cx_popgiven(a) S_cx_popgiven(aTHX_ a) #define cx_poploop(a) S_cx_poploop(aTHX_ a) #define cx_popsub(a) S_cx_popsub(aTHX_ a) #define cx_popsub_args(a) S_cx_popsub_args(aTHX_ a) #define cx_popsub_common(a) S_cx_popsub_common(aTHX_ a) -#define cx_popwhereso(a) S_cx_popwhereso(aTHX_ a) +#define cx_popwhen(a) S_cx_popwhen(aTHX_ a) #define cx_pushblock(a,b,c,d) S_cx_pushblock(aTHX_ a,b,c,d) #define cx_pusheval(a,b,c) S_cx_pusheval(aTHX_ a,b,c) #define cx_pushformat(a,b,c,d) S_cx_pushformat(aTHX_ a,b,c,d) +#define cx_pushgiven(a,b) S_cx_pushgiven(aTHX_ a,b) #define cx_pushloop_for(a,b,c) S_cx_pushloop_for(aTHX_ a,b,c) -#define cx_pushloop_given(a,b) S_cx_pushloop_given(aTHX_ a,b) #define cx_pushloop_plain(a) S_cx_pushloop_plain(aTHX_ a) #define cx_pushsub(a,b,c,d) S_cx_pushsub(aTHX_ a,b,c,d) -#define cx_pushwhereso(a) S_cx_pushwhereso(aTHX_ a) +#define cx_pushwhen(a) S_cx_pushwhen(aTHX_ a) #define cx_topblock(a) S_cx_topblock(aTHX_ a) #endif #if defined(DEBUGGING) @@ -1199,6 +1200,7 @@ #define ck_sassign(a) Perl_ck_sassign(aTHX_ a) #define ck_select(a) Perl_ck_select(aTHX_ a) #define ck_shift(a) Perl_ck_shift(aTHX_ a) +#define ck_smartmatch(a) Perl_ck_smartmatch(aTHX_ a) #define ck_sort(a) Perl_ck_sort(aTHX_ a) #define ck_spair(a) Perl_ck_spair(aTHX_ a) #define ck_split(a) Perl_ck_split(aTHX_ a) @@ -1669,9 +1671,11 @@ #define inplace_aassign(a) S_inplace_aassign(aTHX_ a) #define is_handle_constructor S_is_handle_constructor #define listkids(a) S_listkids(aTHX_ a) +#define looks_like_bool(a) S_looks_like_bool(aTHX_ a) #define modkids(a,b) S_modkids(aTHX_ a,b) #define move_proto_attr(a,b,c,d) S_move_proto_attr(aTHX_ a,b,c,d) #define my_kid(a,b,c) S_my_kid(aTHX_ a,b,c) +#define newGIVWHENOP(a,b,c,d,e) S_newGIVWHENOP(aTHX_ a,b,c,d,e) #define newMETHOP_internal(a,b,c,d) S_newMETHOP_internal(aTHX_ a,b,c,d) #define new_logop(a,b,c,d) S_new_logop(aTHX_ a,b,c,d) #define no_bareword_allowed(a) S_no_bareword_allowed(aTHX_ a) @@ -1681,6 +1685,7 @@ #define optimize_op(a) S_optimize_op(aTHX_ a) #define pmtrans(a,b,c) S_pmtrans(aTHX_ a,b,c) #define process_special_blocks(a,b,c,d) S_process_special_blocks(aTHX_ a,b,c,d) +#define ref_array_or_hash(a) S_ref_array_or_hash(aTHX_ a) #define refkids(a,b) S_refkids(aTHX_ a,b) #define scalar_mod_type S_scalar_mod_type #define scalarboolean(a) S_scalarboolean(aTHX_ a) @@ -1730,15 +1735,20 @@ # endif # if defined(PERL_IN_PP_CTL_C) #define check_type_and_open(a) S_check_type_and_open(aTHX_ a) +#define destroy_matcher(a) S_destroy_matcher(aTHX_ a) +#define do_smartmatch(a,b,c) S_do_smartmatch(aTHX_ a,b,c) #define docatch(a) S_docatch(aTHX_ a) #define doeval_compile(a,b,c,d) S_doeval_compile(aTHX_ a,b,c,d) #define dofindlabel(a,b,c,d,e,f) S_dofindlabel(aTHX_ a,b,c,d,e,f) #define doparseform(a) S_doparseform(aTHX_ a) #define dopoptoeval(a) S_dopoptoeval(aTHX_ a) +#define dopoptogivenfor(a) S_dopoptogivenfor(aTHX_ a) #define dopoptolabel(a,b,c) S_dopoptolabel(aTHX_ a,b,c) #define dopoptoloop(a) S_dopoptoloop(aTHX_ a) #define dopoptosub_at(a,b) S_dopoptosub_at(aTHX_ a,b) -#define dopoptowhereso(a) S_dopoptowhereso(aTHX_ a) +#define dopoptowhen(a) S_dopoptowhen(aTHX_ a) +#define make_matcher(a) S_make_matcher(aTHX_ a) +#define matcher_matches_sv(a,b) S_matcher_matches_sv(aTHX_ a,b) #define num_overflow S_num_overflow #define path_is_searchable S_path_is_searchable #define run_user_filter(a,b,c) S_run_user_filter(aTHX_ a,b,c) diff --git a/ext/B/B.pm b/ext/B/B.pm index 86d24a5328..ce061e4910 100644 --- a/ext/B/B.pm +++ b/ext/B/B.pm @@ -20,7 +20,7 @@ sub import { # walkoptree comes from B.xs BEGIN { - $B::VERSION = '1.73'; + $B::VERSION = '1.74'; @B::EXPORT_OK = (); # Our BOOT code needs $VERSION set, and will append to @EXPORT_OK. diff --git a/ext/B/t/f_map.t b/ext/B/t/f_map.t index 893d010459..221f2926e2 100644 --- a/ext/B/t/f_map.t +++ b/ext/B/t/f_map.t @@ -165,7 +165,7 @@ checkOptree(note => q{}, # c <1> rv2av[t6] sKRM/1 # d <#> gv[*_] s # e <1> rv2gv sKRM/1 -# f <{> enteriter(next->q last->t redo->g) KS +# f <{> enteriter(next->q last->t redo->g) KS/DEF # r <0> iter s # s <|> and(other->g) K/1 # g <;> nextstate(main 475 (eval 10):1) v:{ @@ -198,7 +198,7 @@ EOT_EOT # c <1> rv2av[t3] sKRM/1 # d <$> gv(*_) s # e <1> rv2gv sKRM/1 -# f <{> enteriter(next->q last->t redo->g) KS +# f <{> enteriter(next->q last->t redo->g) KS/DEF # r <0> iter s # s <|> and(other->g) K/1 # g <;> nextstate(main 559 (eval 15):1) v:{ diff --git a/ext/B/t/optree_samples.t b/ext/B/t/optree_samples.t index a791889618..15b5799ce0 100644 --- a/ext/B/t/optree_samples.t +++ b/ext/B/t/optree_samples.t @@ -240,7 +240,7 @@ checkOptree ( name => '-exec sub { foreach (1..10) {print "foo $_"} }', # 3 <$> const[IV 1] s # 4 <$> const[IV 10] s # 5 <#> gv[*_] s -# 6 <{> enteriter(next->c last->f redo->7) KS +# 6 <{> enteriter(next->c last->f redo->7) KS/DEF # d <0> iter s # e <|> and(other->7) K/1 # 7 <;> nextstate(main 1659 optree_samples.t:234) v:>,<,% @@ -258,7 +258,7 @@ EOT_EOT # 3 <$> const(IV 1) s # 4 <$> const(IV 10) s # 5 <$> gv(*_) s -# 6 <{> enteriter(next->c last->f redo->7) KS +# 6 <{> enteriter(next->c last->f redo->7) KS/DEF # d <0> iter s # e <|> and(other->7) K/1 # 7 <;> nextstate(main 443 optree_samples.t:182) v:>,<,% @@ -281,7 +281,7 @@ checkOptree ( name => '-basic sub { print "foo $_" foreach (1..10) }', # - <@> lineseq KP ->f # 1 <;> nextstate(main 445 optree.t:167) v:>,<,% ->2 # e <2> leaveloop K/2 ->f -# 6 <{> enteriter(next->b last->e redo->7) KS ->c +# 6 <{> enteriter(next->b last->e redo->7) KS/DEF ->c # - <0> ex-pushmark s ->2 # - <1> ex-list lK ->5 # 2 <0> pushmark s ->3 @@ -305,7 +305,7 @@ EOT_EOT # - <@> lineseq KP ->f # 1 <;> nextstate(main 446 optree_samples.t:192) v:>,<,% ->2 # e <2> leaveloop K/2 ->f -# 6 <{> enteriter(next->b last->e redo->7) KS ->c +# 6 <{> enteriter(next->b last->e redo->7) KS/DEF ->c # - <0> ex-pushmark s ->2 # - <1> ex-list lK ->5 # 2 <0> pushmark s ->3 @@ -337,7 +337,7 @@ checkOptree ( name => '-exec -e foreach (1..10) {print qq{foo $_}}', # 4 <$> const[IV 1] s # 5 <$> const[IV 10] s # 6 <#> gv[*_] s -# 7 <{> enteriter(next->d last->g redo->8) vKS +# 7 <{> enteriter(next->d last->g redo->8) vKS/DEF # e <0> iter s # f <|> and(other->8) vK/1 # 8 <;> nextstate(main 1 -e:1) v:>,<,% @@ -356,7 +356,7 @@ EOT_EOT # 4 <$> const(IV 1) s # 5 <$> const(IV 10) s # 6 <$> gv(*_) s -# 7 <{> enteriter(next->d last->g redo->8) vKS +# 7 <{> enteriter(next->d last->g redo->8) vKS/DEF # e <0> iter s # f <|> and(other->8) vK/1 # 8 <;> nextstate(main 1 -e:1) v:>,<,% @@ -380,7 +380,7 @@ checkOptree ( name => '-exec sub { print "foo $_" foreach (1..10) }', # 3 <$> const[IV 1] s # 4 <$> const[IV 10] s # 5 <#> gv[*_] s -# 6 <{> enteriter(next->b last->e redo->7) KS +# 6 <{> enteriter(next->b last->e redo->7) KS/DEF # c <0> iter s # d <|> and(other->7) K/1 # 7 <0> pushmark s @@ -397,7 +397,7 @@ EOT_EOT # 3 <$> const(IV 1) s # 4 <$> const(IV 10) s # 5 <$> gv(*_) s -# 6 <{> enteriter(next->b last->e redo->7) KS +# 6 <{> enteriter(next->b last->e redo->7) KS/DEF # c <0> iter s # d <|> and(other->7) K/1 # 7 <0> pushmark s @@ -517,7 +517,7 @@ checkOptree ( name => '%h=(); for $_(@a){$h{getkey($_)} = $_}', # a <1> rv2av[t6] sKRM/1 # b <#> gv[*_] s # c <1> rv2gv sKRM/1 -# d <{> enteriter(next->o last->r redo->e) KS +# d <{> enteriter(next->o last->r redo->e) KS/DEF # p <0> iter s # q <|> and(other->e) K/1 # e <;> nextstate(main 505 (eval 24):1) v:{ @@ -547,7 +547,7 @@ EOT_EOT # a <1> rv2av[t3] sKRM/1 # b <$> gv(*_) s # c <1> rv2gv sKRM/1 -# d <{> enteriter(next->o last->r redo->e) KS +# d <{> enteriter(next->o last->r redo->e) KS/DEF # p <0> iter s # q <|> and(other->e) K/1 # e <;> nextstate(main 505 (eval 24):1) v:{ diff --git a/ext/Opcode/Opcode.pm b/ext/Opcode/Opcode.pm index e8f429e113..9d97ef1540 100644 --- a/ext/Opcode/Opcode.pm +++ b/ext/Opcode/Opcode.pm @@ -6,7 +6,7 @@ use strict; our($VERSION, @ISA, @EXPORT_OK); -$VERSION = "1.42"; +$VERSION = "1.43"; use Carp; use Exporter (); @@ -426,9 +426,9 @@ These are a hotchpotch of opcodes still waiting to be considered entertry leavetry -- can be used to 'hide' fatal errors - entergiven - enterwhereso leavewhereso - continue + entergiven leavegiven + enterwhen leavewhen + break continue smartmatch custom -- where should this go diff --git a/ext/Pod-Functions/Functions_pm.PL b/ext/Pod-Functions/Functions_pm.PL index bd0e3dad80..04b1a90e3c 100644 --- a/ext/Pod-Functions/Functions_pm.PL +++ b/ext/Pod-Functions/Functions_pm.PL @@ -207,7 +207,7 @@ L<perlfunc/"Perl Functions by Category"> section. =cut -our $VERSION = '1.12'; +our $VERSION = '1.13'; require Exporter; diff --git a/ext/Pod-Functions/t/Functions.t b/ext/Pod-Functions/t/Functions.t index 23301142ba..2beccc1ac6 100644 --- a/ext/Pod-Functions/t/Functions.t +++ b/ext/Pod-Functions/t/Functions.t @@ -113,7 +113,7 @@ Functions for filehandles, files, or directories: select, stat, symlink, sysopen, umask, unlink, utime Keywords related to the control flow of your Perl program: - __FILE__, __LINE__, __PACKAGE__, __SUB__, caller, + __FILE__, __LINE__, __PACKAGE__, __SUB__, break, caller, continue, die, do, dump, eval, evalbytes, exit, goto, last, next, redo, return, sub, wantarray @@ -521,7 +521,7 @@ S_maybe_add_coresub(pTHX_ HV * const stash, GV *gv, no support for funcs that do not parse like funcs */ case KEY___DATA__: case KEY___END__: case KEY_and: case KEY_AUTOLOAD: case KEY_BEGIN : case KEY_CHECK : case KEY_cmp: - case KEY_DESTROY: + case KEY_default : case KEY_DESTROY: case KEY_do : case KEY_dump : case KEY_else : case KEY_elsif : case KEY_END : case KEY_eq : case KEY_eval : case KEY_for : case KEY_foreach: case KEY_format: case KEY_ge : @@ -535,8 +535,7 @@ 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_whereis: case KEY_whereso: case KEY_while: + case KEY_until: case KEY_use : case KEY_when : case KEY_while : case KEY_x : case KEY_xor : case KEY_y : return NULL; case KEY_chdir: @@ -1813,17 +1813,6 @@ S_cx_pushloop_for(pTHX_ PERL_CONTEXT *cx, void *itervarp, SV* itersave) } -PERL_STATIC_INLINE void -S_cx_pushloop_given(pTHX_ PERL_CONTEXT *cx, SV *orig_defsv) -{ - PERL_ARGS_ASSERT_CX_PUSHLOOP_GIVEN; - - cx->blk_loop.my_op = cLOOP; - cx->blk_loop.itervar_u.gv = PL_defgv; - cx->blk_loop.itersave = orig_defsv; -} - - /* pop all loop types, including plain */ PERL_STATIC_INLINE void @@ -1860,19 +1849,19 @@ S_cx_poploop(pTHX_ PERL_CONTEXT *cx) PERL_STATIC_INLINE void -S_cx_pushwhereso(pTHX_ PERL_CONTEXT *cx) +S_cx_pushwhen(pTHX_ PERL_CONTEXT *cx) { - PERL_ARGS_ASSERT_CX_PUSHWHERESO; + PERL_ARGS_ASSERT_CX_PUSHWHEN; - cx->blk_whereso.leave_op = cLOGOP->op_other; + cx->blk_givwhen.leave_op = cLOGOP->op_other; } PERL_STATIC_INLINE void -S_cx_popwhereso(pTHX_ PERL_CONTEXT *cx) +S_cx_popwhen(pTHX_ PERL_CONTEXT *cx) { - PERL_ARGS_ASSERT_CX_POPWHERESO; - assert(CxTYPE(cx) == CXt_WHERESO); + PERL_ARGS_ASSERT_CX_POPWHEN; + assert(CxTYPE(cx) == CXt_WHEN); PERL_UNUSED_ARG(cx); PERL_UNUSED_CONTEXT; @@ -1880,6 +1869,30 @@ S_cx_popwhereso(pTHX_ PERL_CONTEXT *cx) } +PERL_STATIC_INLINE void +S_cx_pushgiven(pTHX_ PERL_CONTEXT *cx, SV *orig_defsv) +{ + PERL_ARGS_ASSERT_CX_PUSHGIVEN; + + cx->blk_givwhen.leave_op = cLOGOP->op_other; + cx->blk_givwhen.defsv_save = orig_defsv; +} + + +PERL_STATIC_INLINE void +S_cx_popgiven(pTHX_ PERL_CONTEXT *cx) +{ + SV *sv; + + PERL_ARGS_ASSERT_CX_POPGIVEN; + assert(CxTYPE(cx) == CXt_GIVEN); + + sv = GvSV(PL_defgv); + GvSV(PL_defgv) = cx->blk_givwhen.defsv_save; + cx->blk_givwhen.defsv_save = NULL; + SvREFCNT_dec(sv); +} + /* ------------------ util.h ------------------------------------------- */ /* diff --git a/keywords.c b/keywords.c index 23e6145ec0..9fa30e616a 100644 --- a/keywords.c +++ b/keywords.c @@ -488,7 +488,7 @@ Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords) goto unknown; } - case 4: /* 39 tokens of length 4 */ + case 4: /* 40 tokens of length 4 */ switch (name[0]) { case 'I': @@ -908,38 +908,49 @@ Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords) } case 'w': - if (name[1] == 'a') + switch (name[1]) { - switch (name[2]) - { - case 'i': - if (name[3] == 't') - { /* wait */ - return -KEY_wait; - } + case 'a': + switch (name[2]) + { + case 'i': + if (name[3] == 't') + { /* wait */ + return -KEY_wait; + } - goto unknown; + goto unknown; - case 'r': - if (name[3] == 'n') - { /* warn */ - return -KEY_warn; - } + case 'r': + if (name[3] == 'n') + { /* warn */ + return -KEY_warn; + } - goto unknown; + goto unknown; - default: - goto unknown; - } - } + default: + goto unknown; + } - goto unknown; + case 'h': + if (name[2] == 'e' && + name[3] == 'n') + { /* when */ + return (all_keywords || FEATURE_SWITCH_IS_ENABLED ? KEY_when : 0); + } + + goto unknown; + + default: + goto unknown; + } default: goto unknown; } - case 5: /* 38 tokens of length 5 */ + case 5: /* 39 tokens of length 5 */ switch (name[0]) { case 'B': @@ -992,15 +1003,31 @@ Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords) } case 'b': - if (name[1] == 'l' && - name[2] == 'e' && - name[3] == 's' && - name[4] == 's') - { /* bless */ - return -KEY_bless; - } + switch (name[1]) + { + case 'l': + if (name[2] == 'e' && + name[3] == 's' && + name[4] == 's') + { /* bless */ + return -KEY_bless; + } - goto unknown; + goto unknown; + + case 'r': + if (name[2] == 'e' && + name[3] == 'a' && + name[4] == 'k') + { /* break */ + return (all_keywords || FEATURE_SWITCH_IS_ENABLED ? -KEY_break : 0); + } + + goto unknown; + + default: + goto unknown; + } case 'c': switch (name[1]) @@ -1876,7 +1903,7 @@ Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords) goto unknown; } - case 7: /* 31 tokens of length 7 */ + case 7: /* 30 tokens of length 7 */ switch (name[0]) { case 'D': @@ -1968,13 +1995,33 @@ Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords) goto unknown; case 'e': - if (name[2] == 'f' && - name[3] == 'i' && - name[4] == 'n' && - name[5] == 'e' && - name[6] == 'd') - { /* defined */ - return KEY_defined; + if (name[2] == 'f') + { + switch (name[3]) + { + case 'a': + if (name[4] == 'u' && + name[5] == 'l' && + name[6] == 't') + { /* default */ + return (all_keywords || FEATURE_SWITCH_IS_ENABLED ? KEY_default : 0); + } + + goto unknown; + + case 'i': + if (name[4] == 'n' && + name[5] == 'e' && + name[6] == 'd') + { /* defined */ + return KEY_defined; + } + + goto unknown; + + default: + goto unknown; + } } goto unknown; @@ -2282,54 +2329,18 @@ Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords) } case 'w': - switch (name[1]) - { - case 'a': - if (name[2] == 'i' && - name[3] == 't' && - name[4] == 'p' && - name[5] == 'i' && - name[6] == 'd') - { /* waitpid */ - return -KEY_waitpid; - } - - goto unknown; - - case 'h': - if (name[2] == 'e' && - name[3] == 'r' && - 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; - - default: - goto unknown; + if (name[1] == 'a' && + name[2] == 'i' && + name[3] == 't' && + name[4] == 'p' && + name[5] == 'i' && + name[6] == 'd') + { /* waitpid */ + return -KEY_waitpid; } + goto unknown; + default: goto unknown; } @@ -3426,5 +3437,5 @@ unknown: } /* Generated from: - * b2741ab99701d1c72b58afb96a9f210532b6f6ce81aacdf5188a4871c16ee239 regen/keywords.pl + * db0472e0ad4f44bd0816cad799d63b60d1bbd7e11cef40ea15bf0d00f69669f6 regen/keywords.pl * ex: set ro: */ diff --git a/keywords.h b/keywords.h index d65879a014..2b1d598a4e 100644 --- a/keywords.h +++ b/keywords.h @@ -35,239 +35,240 @@ #define KEY_bind 19 #define KEY_binmode 20 #define KEY_bless 21 -#define KEY_caller 22 -#define KEY_chdir 23 -#define KEY_chmod 24 -#define KEY_chomp 25 -#define KEY_chop 26 -#define KEY_chown 27 -#define KEY_chr 28 -#define KEY_chroot 29 -#define KEY_close 30 -#define KEY_closedir 31 -#define KEY_cmp 32 -#define KEY_connect 33 -#define KEY_continue 34 -#define KEY_cos 35 -#define KEY_crypt 36 -#define KEY_dbmclose 37 -#define KEY_dbmopen 38 -#define KEY_defined 39 -#define KEY_delete 40 -#define KEY_die 41 -#define KEY_do 42 -#define KEY_dump 43 -#define KEY_each 44 -#define KEY_else 45 -#define KEY_elsif 46 -#define KEY_endgrent 47 -#define KEY_endhostent 48 -#define KEY_endnetent 49 -#define KEY_endprotoent 50 -#define KEY_endpwent 51 -#define KEY_endservent 52 -#define KEY_eof 53 -#define KEY_eq 54 -#define KEY_eval 55 -#define KEY_evalbytes 56 -#define KEY_exec 57 -#define KEY_exists 58 -#define KEY_exit 59 -#define KEY_exp 60 -#define KEY_fc 61 -#define KEY_fcntl 62 -#define KEY_fileno 63 -#define KEY_flock 64 -#define KEY_for 65 -#define KEY_foreach 66 -#define KEY_fork 67 -#define KEY_format 68 -#define KEY_formline 69 -#define KEY_ge 70 -#define KEY_getc 71 -#define KEY_getgrent 72 -#define KEY_getgrgid 73 -#define KEY_getgrnam 74 -#define KEY_gethostbyaddr 75 -#define KEY_gethostbyname 76 -#define KEY_gethostent 77 -#define KEY_getlogin 78 -#define KEY_getnetbyaddr 79 -#define KEY_getnetbyname 80 -#define KEY_getnetent 81 -#define KEY_getpeername 82 -#define KEY_getpgrp 83 -#define KEY_getppid 84 -#define KEY_getpriority 85 -#define KEY_getprotobyname 86 -#define KEY_getprotobynumber 87 -#define KEY_getprotoent 88 -#define KEY_getpwent 89 -#define KEY_getpwnam 90 -#define KEY_getpwuid 91 -#define KEY_getservbyname 92 -#define KEY_getservbyport 93 -#define KEY_getservent 94 -#define KEY_getsockname 95 -#define KEY_getsockopt 96 -#define KEY_given 97 -#define KEY_glob 98 -#define KEY_gmtime 99 -#define KEY_goto 100 -#define KEY_grep 101 -#define KEY_gt 102 -#define KEY_hex 103 -#define KEY_if 104 -#define KEY_index 105 -#define KEY_int 106 -#define KEY_ioctl 107 -#define KEY_join 108 -#define KEY_keys 109 -#define KEY_kill 110 -#define KEY_last 111 -#define KEY_lc 112 -#define KEY_lcfirst 113 -#define KEY_le 114 -#define KEY_length 115 -#define KEY_link 116 -#define KEY_listen 117 -#define KEY_local 118 -#define KEY_localtime 119 -#define KEY_lock 120 -#define KEY_log 121 -#define KEY_lstat 122 -#define KEY_lt 123 -#define KEY_m 124 -#define KEY_map 125 -#define KEY_mkdir 126 -#define KEY_msgctl 127 -#define KEY_msgget 128 -#define KEY_msgrcv 129 -#define KEY_msgsnd 130 -#define KEY_my 131 -#define KEY_ne 132 -#define KEY_next 133 -#define KEY_no 134 -#define KEY_not 135 -#define KEY_oct 136 -#define KEY_open 137 -#define KEY_opendir 138 -#define KEY_or 139 -#define KEY_ord 140 -#define KEY_our 141 -#define KEY_pack 142 -#define KEY_package 143 -#define KEY_pipe 144 -#define KEY_pop 145 -#define KEY_pos 146 -#define KEY_print 147 -#define KEY_printf 148 -#define KEY_prototype 149 -#define KEY_push 150 -#define KEY_q 151 -#define KEY_qq 152 -#define KEY_qr 153 -#define KEY_quotemeta 154 -#define KEY_qw 155 -#define KEY_qx 156 -#define KEY_rand 157 -#define KEY_read 158 -#define KEY_readdir 159 -#define KEY_readline 160 -#define KEY_readlink 161 -#define KEY_readpipe 162 -#define KEY_recv 163 -#define KEY_redo 164 -#define KEY_ref 165 -#define KEY_rename 166 -#define KEY_require 167 -#define KEY_reset 168 -#define KEY_return 169 -#define KEY_reverse 170 -#define KEY_rewinddir 171 -#define KEY_rindex 172 -#define KEY_rmdir 173 -#define KEY_s 174 -#define KEY_say 175 -#define KEY_scalar 176 -#define KEY_seek 177 -#define KEY_seekdir 178 -#define KEY_select 179 -#define KEY_semctl 180 -#define KEY_semget 181 -#define KEY_semop 182 -#define KEY_send 183 -#define KEY_setgrent 184 -#define KEY_sethostent 185 -#define KEY_setnetent 186 -#define KEY_setpgrp 187 -#define KEY_setpriority 188 -#define KEY_setprotoent 189 -#define KEY_setpwent 190 -#define KEY_setservent 191 -#define KEY_setsockopt 192 -#define KEY_shift 193 -#define KEY_shmctl 194 -#define KEY_shmget 195 -#define KEY_shmread 196 -#define KEY_shmwrite 197 -#define KEY_shutdown 198 -#define KEY_sin 199 -#define KEY_sleep 200 -#define KEY_socket 201 -#define KEY_socketpair 202 -#define KEY_sort 203 -#define KEY_splice 204 -#define KEY_split 205 -#define KEY_sprintf 206 -#define KEY_sqrt 207 -#define KEY_srand 208 -#define KEY_stat 209 -#define KEY_state 210 -#define KEY_study 211 -#define KEY_sub 212 -#define KEY_substr 213 -#define KEY_symlink 214 -#define KEY_syscall 215 -#define KEY_sysopen 216 -#define KEY_sysread 217 -#define KEY_sysseek 218 -#define KEY_system 219 -#define KEY_syswrite 220 -#define KEY_tell 221 -#define KEY_telldir 222 -#define KEY_tie 223 -#define KEY_tied 224 -#define KEY_time 225 -#define KEY_times 226 -#define KEY_tr 227 -#define KEY_truncate 228 -#define KEY_uc 229 -#define KEY_ucfirst 230 -#define KEY_umask 231 -#define KEY_undef 232 -#define KEY_unless 233 -#define KEY_unlink 234 -#define KEY_unpack 235 -#define KEY_unshift 236 -#define KEY_untie 237 -#define KEY_until 238 -#define KEY_use 239 -#define KEY_utime 240 -#define KEY_values 241 -#define KEY_vec 242 -#define KEY_wait 243 -#define KEY_waitpid 244 -#define KEY_wantarray 245 -#define KEY_warn 246 -#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 +#define KEY_break 22 +#define KEY_caller 23 +#define KEY_chdir 24 +#define KEY_chmod 25 +#define KEY_chomp 26 +#define KEY_chop 27 +#define KEY_chown 28 +#define KEY_chr 29 +#define KEY_chroot 30 +#define KEY_close 31 +#define KEY_closedir 32 +#define KEY_cmp 33 +#define KEY_connect 34 +#define KEY_continue 35 +#define KEY_cos 36 +#define KEY_crypt 37 +#define KEY_dbmclose 38 +#define KEY_dbmopen 39 +#define KEY_default 40 +#define KEY_defined 41 +#define KEY_delete 42 +#define KEY_die 43 +#define KEY_do 44 +#define KEY_dump 45 +#define KEY_each 46 +#define KEY_else 47 +#define KEY_elsif 48 +#define KEY_endgrent 49 +#define KEY_endhostent 50 +#define KEY_endnetent 51 +#define KEY_endprotoent 52 +#define KEY_endpwent 53 +#define KEY_endservent 54 +#define KEY_eof 55 +#define KEY_eq 56 +#define KEY_eval 57 +#define KEY_evalbytes 58 +#define KEY_exec 59 +#define KEY_exists 60 +#define KEY_exit 61 +#define KEY_exp 62 +#define KEY_fc 63 +#define KEY_fcntl 64 +#define KEY_fileno 65 +#define KEY_flock 66 +#define KEY_for 67 +#define KEY_foreach 68 +#define KEY_fork 69 +#define KEY_format 70 +#define KEY_formline 71 +#define KEY_ge 72 +#define KEY_getc 73 +#define KEY_getgrent 74 +#define KEY_getgrgid 75 +#define KEY_getgrnam 76 +#define KEY_gethostbyaddr 77 +#define KEY_gethostbyname 78 +#define KEY_gethostent 79 +#define KEY_getlogin 80 +#define KEY_getnetbyaddr 81 +#define KEY_getnetbyname 82 +#define KEY_getnetent 83 +#define KEY_getpeername 84 +#define KEY_getpgrp 85 +#define KEY_getppid 86 +#define KEY_getpriority 87 +#define KEY_getprotobyname 88 +#define KEY_getprotobynumber 89 +#define KEY_getprotoent 90 +#define KEY_getpwent 91 +#define KEY_getpwnam 92 +#define KEY_getpwuid 93 +#define KEY_getservbyname 94 +#define KEY_getservbyport 95 +#define KEY_getservent 96 +#define KEY_getsockname 97 +#define KEY_getsockopt 98 +#define KEY_given 99 +#define KEY_glob 100 +#define KEY_gmtime 101 +#define KEY_goto 102 +#define KEY_grep 103 +#define KEY_gt 104 +#define KEY_hex 105 +#define KEY_if 106 +#define KEY_index 107 +#define KEY_int 108 +#define KEY_ioctl 109 +#define KEY_join 110 +#define KEY_keys 111 +#define KEY_kill 112 +#define KEY_last 113 +#define KEY_lc 114 +#define KEY_lcfirst 115 +#define KEY_le 116 +#define KEY_length 117 +#define KEY_link 118 +#define KEY_listen 119 +#define KEY_local 120 +#define KEY_localtime 121 +#define KEY_lock 122 +#define KEY_log 123 +#define KEY_lstat 124 +#define KEY_lt 125 +#define KEY_m 126 +#define KEY_map 127 +#define KEY_mkdir 128 +#define KEY_msgctl 129 +#define KEY_msgget 130 +#define KEY_msgrcv 131 +#define KEY_msgsnd 132 +#define KEY_my 133 +#define KEY_ne 134 +#define KEY_next 135 +#define KEY_no 136 +#define KEY_not 137 +#define KEY_oct 138 +#define KEY_open 139 +#define KEY_opendir 140 +#define KEY_or 141 +#define KEY_ord 142 +#define KEY_our 143 +#define KEY_pack 144 +#define KEY_package 145 +#define KEY_pipe 146 +#define KEY_pop 147 +#define KEY_pos 148 +#define KEY_print 149 +#define KEY_printf 150 +#define KEY_prototype 151 +#define KEY_push 152 +#define KEY_q 153 +#define KEY_qq 154 +#define KEY_qr 155 +#define KEY_quotemeta 156 +#define KEY_qw 157 +#define KEY_qx 158 +#define KEY_rand 159 +#define KEY_read 160 +#define KEY_readdir 161 +#define KEY_readline 162 +#define KEY_readlink 163 +#define KEY_readpipe 164 +#define KEY_recv 165 +#define KEY_redo 166 +#define KEY_ref 167 +#define KEY_rename 168 +#define KEY_require 169 +#define KEY_reset 170 +#define KEY_return 171 +#define KEY_reverse 172 +#define KEY_rewinddir 173 +#define KEY_rindex 174 +#define KEY_rmdir 175 +#define KEY_s 176 +#define KEY_say 177 +#define KEY_scalar 178 +#define KEY_seek 179 +#define KEY_seekdir 180 +#define KEY_select 181 +#define KEY_semctl 182 +#define KEY_semget 183 +#define KEY_semop 184 +#define KEY_send 185 +#define KEY_setgrent 186 +#define KEY_sethostent 187 +#define KEY_setnetent 188 +#define KEY_setpgrp 189 +#define KEY_setpriority 190 +#define KEY_setprotoent 191 +#define KEY_setpwent 192 +#define KEY_setservent 193 +#define KEY_setsockopt 194 +#define KEY_shift 195 +#define KEY_shmctl 196 +#define KEY_shmget 197 +#define KEY_shmread 198 +#define KEY_shmwrite 199 +#define KEY_shutdown 200 +#define KEY_sin 201 +#define KEY_sleep 202 +#define KEY_socket 203 +#define KEY_socketpair 204 +#define KEY_sort 205 +#define KEY_splice 206 +#define KEY_split 207 +#define KEY_sprintf 208 +#define KEY_sqrt 209 +#define KEY_srand 210 +#define KEY_stat 211 +#define KEY_state 212 +#define KEY_study 213 +#define KEY_sub 214 +#define KEY_substr 215 +#define KEY_symlink 216 +#define KEY_syscall 217 +#define KEY_sysopen 218 +#define KEY_sysread 219 +#define KEY_sysseek 220 +#define KEY_system 221 +#define KEY_syswrite 222 +#define KEY_tell 223 +#define KEY_telldir 224 +#define KEY_tie 225 +#define KEY_tied 226 +#define KEY_time 227 +#define KEY_times 228 +#define KEY_tr 229 +#define KEY_truncate 230 +#define KEY_uc 231 +#define KEY_ucfirst 232 +#define KEY_umask 233 +#define KEY_undef 234 +#define KEY_unless 235 +#define KEY_unlink 236 +#define KEY_unpack 237 +#define KEY_unshift 238 +#define KEY_untie 239 +#define KEY_until 240 +#define KEY_use 241 +#define KEY_utime 242 +#define KEY_values 243 +#define KEY_vec 244 +#define KEY_wait 245 +#define KEY_waitpid 246 +#define KEY_wantarray 247 +#define KEY_warn 248 +#define KEY_when 249 +#define KEY_while 250 +#define KEY_write 251 +#define KEY_x 252 +#define KEY_xor 253 +#define KEY_y 254 /* Generated from: - * b2741ab99701d1c72b58afb96a9f210532b6f6ce81aacdf5188a4871c16ee239 regen/keywords.pl + * db0472e0ad4f44bd0816cad799d63b60d1bbd7e11cef40ea15bf0d00f69669f6 regen/keywords.pl * ex: set ro: */ diff --git a/lib/B/Deparse-core.t b/lib/B/Deparse-core.t index 4071e5e5f2..6ee935f5f7 100644 --- a/lib/B/Deparse-core.t +++ b/lib/B/Deparse-core.t @@ -36,7 +36,7 @@ BEGIN { use strict; use Test::More; -plan tests => 3874; +plan tests => 3886; use feature (sprintf(":%vd", $^V)); # to avoid relying on the feature # logic to add CORE:: @@ -381,8 +381,7 @@ my %not_tested = map { $_ => 1} qw( unless until use - whereis - whereso + when while y ); @@ -465,6 +464,7 @@ atan2 2 p bind 2 p binmode 12 p bless 1 p +break 0 - caller 0 - chdir 01 - chmod @ p1 diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm index d10e6a0868..86f262acf1 100644 --- a/lib/B/Deparse.pm +++ b/lib/B/Deparse.pm @@ -52,7 +52,7 @@ use B qw(class main_root main_start main_cv svref_2object opnumber perlstring MDEREF_SHIFT ); -$VERSION = '1.46'; +$VERSION = '1.47'; use strict; our $AUTOLOAD; use warnings (); @@ -2267,8 +2267,9 @@ my %feature_keywords = ( state => 'state', say => 'say', given => 'switch', - whereis => 'switch', - whereso => 'switch', + when => 'switch', + default => 'switch', + break => 'switch', evalbytes=>'evalbytes', __SUB__ => '__SUB__', fc => 'fc', @@ -2560,31 +2561,33 @@ sub pp_ggrgid { unop(@_, "getgrgid") } sub pp_lock { unop(@_, "lock") } sub pp_continue { unop(@_, "continue"); } +sub pp_break { unop(@_, "break"); } -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 givwhen { + my $self = shift; + my($op, $cx, $givwhen) = @_; -sub pp_leavewhereso { - my($self, $op, $cx) = @_; 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 ($head, $block); + if ($enterop->flags & OPf_SPECIAL) { + $head = $self->keyword("default"); + $block = $self->deparse($enterop->first, 0); } - my $cond_str = $self->deparse($cond, 1); - $keyword = $self->keyword($keyword); - $block = $self->deparse($block, 0); - return "$keyword ($cond_str) {\n\t$block\n\b}\cK"; + else { + my $cond = $enterop->first; + my $cond_str = $self->deparse($cond, 1); + $head = "$givwhen ($cond_str)"; + $block = $self->deparse($cond->sibling, 0); + } + + return "$head {\n". + "\t$block\n". + "\b}\cK"; } +sub pp_leavegiven { givwhen(@_, $_[0]->keyword("given")); } +sub pp_leavewhen { givwhen(@_, $_[0]->keyword("when")); } + sub pp_exists { my $self = shift; my($op, $cx) = @_; @@ -3019,7 +3022,6 @@ sub pp_i_ge { binop(@_, ">=", 15) } sub pp_i_le { binop(@_, "<=", 15) } sub pp_i_ncmp { maybe_targmy(@_, \&binop, "<=>", 14) } -sub pp_smartmatch { binop(@_, "~~", 14) } sub pp_seq { binop(@_, "eq", 14) } sub pp_sne { binop(@_, "ne", 14) } sub pp_slt { binop(@_, "lt", 15) } @@ -3031,6 +3033,16 @@ sub pp_scmp { maybe_targmy(@_, \&binop, "cmp", 14) } sub pp_sassign { binop(@_, "=", 7, SWAP_CHILDREN) } sub pp_aassign { binop(@_, "=", 7, SWAP_CHILDREN | LIST_CONTEXT) } +sub pp_smartmatch { + my ($self, $op, $cx) = @_; + if (($op->flags & OPf_SPECIAL) && $self->{expand} < 2) { + return $self->deparse($op->last, $cx); + } + else { + binop(@_, "~~", 14); + } +} + # '.' is special because concats-of-concats are optimized to save copying # by making all but the first concat stacked. The effect is as if the # programmer had written '($a . $b) .= $c', except legal. @@ -3834,13 +3846,6 @@ sub loop_common { $bare = 1; } $body = $kid; - } elsif ($enter->name eq "entergiven") { # given - my $given = $self->keyword("given"); - my $enterop = $op->first; - my $topic = $enterop->first; - my $topic_str = $self->deparse($topic, 1); - my $block = $self->deparse($topic->sibling, 0); - return "$given ($topic_str) {\n\t$block\n\b}\cK"; } elsif ($enter->name eq "enteriter") { # foreach my $ary = $enter->first->sibling; # first was pushmark my $var = $ary->sibling; diff --git a/lib/B/Deparse.t b/lib/B/Deparse.t index 576cd7456f..00fbb01cf8 100644 --- a/lib/B/Deparse.t +++ b/lib/B/Deparse.t @@ -1039,14 +1039,13 @@ my $b = \{}; my $c = []; my $d = \[]; #### -# SKIP ?$] < 5.010 && "smartmatch and given/whereso not implemented on this Perl version" +# SKIP ?$] < 5.010 && "smartmatch and given/when not implemented on this Perl version" # CONTEXT use feature ':5.10'; no warnings 'experimental::smartmatch'; -# implicit smartmatch in given/whereso +# implicit smartmatch in given/when given ('foo') { - whereso ('bar') { continue; } - whereso ($_ == 3) { continue; } - whereis ('quux') { continue; } - 0; + when ('bar') { continue; } + when ($_ ~~ 'quux') { continue; } + default { 0; } } #### # conditions in elsifs (regression in change #33710 which fixed bug #37302) @@ -1528,13 +1527,12 @@ $a[0] = 1; CORE::state $x; CORE::say $x; CORE::given ($x) { - CORE::whereso (3) { + CORE::when (3) { continue; } - CORE::whereis (5) { - continue; + CORE::default { + CORE::break; } - next; } CORE::evalbytes ''; () = CORE::__SUB__; @@ -1547,13 +1545,12 @@ use 1; CORE::say $_; CORE::state $x; CORE::given ($x) { - CORE::whereso (3) { + CORE::when (3) { continue; } - CORE::whereis (5) { - continue; + CORE::default { + CORE::break; } - next; } CORE::evalbytes ''; () = CORE::__SUB__; @@ -1561,13 +1558,12 @@ CORE::evalbytes ''; CORE::say $_; CORE::state $x; CORE::given ($x) { - CORE::whereso (3) { + CORE::when (3) { continue; } - CORE::whereis (5) { - continue; + CORE::default { + CORE::break; } - next; } CORE::evalbytes ''; () = CORE::__SUB__; @@ -1580,13 +1576,12 @@ use 1; CORE::say $_; CORE::state $x; CORE::given ($x) { - CORE::whereso (3) { + CORE::when (3) { continue; } - CORE::whereis (5) { - continue; + CORE::default { + CORE::break; } - next; } CORE::evalbytes ''; () = CORE::__SUB__; @@ -1596,13 +1591,12 @@ use feature ':default'; CORE::say $_; CORE::state $x; CORE::given ($x) { - CORE::whereso (3) { + CORE::when (3) { continue; } - CORE::whereis (5) { - continue; + CORE::default { + CORE::break; } - next; } CORE::evalbytes ''; () = CORE::__SUB__; @@ -1610,6 +1604,7 @@ CORE::evalbytes ''; # SKIP ?$] < 5.017004 && "lexical subs not implemented on this Perl version" # lexical subroutines and keywords of the same name # CONTEXT use feature 'lexical_subs', 'switch'; no warnings 'experimental'; +my sub default; my sub else; my sub elsif; my sub for; @@ -1630,9 +1625,9 @@ my sub tr; my sub unless; my sub until; my sub use; -my sub whereis; -my sub whereso; +my sub when; my sub while; +CORE::default { die; } CORE::if ($1) { die; } CORE::if ($1) { die; } CORE::elsif ($1) { die; } @@ -1654,8 +1649,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::when ($1 ~~ $2) { die; } CORE::while ($1) { die; } die CORE::while $1; #### diff --git a/lib/B/Op_private.pm b/lib/B/Op_private.pm index 1bf9c57e27..25e9a8c6f2 100644 --- a/lib/B/Op_private.pm +++ b/lib/B/Op_private.pm @@ -304,9 +304,11 @@ $bits{dorassign}{0} = $bf[0]; $bits{dump}{0} = $bf[0]; $bits{each}{0} = $bf[0]; @{$bits{entereval}}{5,4,3,2,1,0} = ('OPpEVAL_RE_REPARSING', 'OPpEVAL_COPHH', 'OPpEVAL_BYTES', 'OPpEVAL_UNICODE', 'OPpEVAL_HAS_HH', $bf[0]); +$bits{entergiven}{0} = $bf[0]; +$bits{enteriter}{3} = 'OPpITER_DEF'; @{$bits{entersub}}{5,4,0} = ($bf[8], $bf[8], 'OPpENTERSUB_INARGS'); $bits{entertry}{0} = $bf[0]; -$bits{enterwhereso}{0} = $bf[0]; +$bits{enterwhen}{0} = $bf[0]; @{$bits{enterwrite}}{3,2,1,0} = ($bf[4], $bf[4], $bf[4], $bf[4]); @{$bits{eof}}{3,2,1,0} = ($bf[4], $bf[4], $bf[4], $bf[4]); @{$bits{eq}}{1,0} = ($bf[1], $bf[1]); @@ -405,10 +407,11 @@ $bits{lc}{0} = $bf[0]; $bits{lcfirst}{0} = $bf[0]; @{$bits{le}}{1,0} = ($bf[1], $bf[1]); $bits{leaveeval}{0} = $bf[0]; +$bits{leavegiven}{0} = $bf[0]; @{$bits{leaveloop}}{1,0} = ($bf[1], $bf[1]); $bits{leavesub}{0} = $bf[0]; $bits{leavesublv}{0} = $bf[0]; -$bits{leavewhereso}{0} = $bf[0]; +$bits{leavewhen}{0} = $bf[0]; $bits{leavewrite}{0} = $bf[0]; @{$bits{left_shift}}{1,0} = ($bf[1], $bf[1]); $bits{length}{0} = $bf[0]; @@ -632,6 +635,7 @@ our %defines = ( OPpHINT_STRICT_REFS => 2, OPpHUSH_VMSISH => 32, OPpINDEX_BOOLNEG => 64, + OPpITER_DEF => 8, OPpITER_REVERSED => 2, OPpKVSLICE => 32, OPpLIST_GUESSED => 64, @@ -737,6 +741,7 @@ our %labels = ( OPpHINT_STRICT_REFS => 'STRICT', OPpHUSH_VMSISH => 'HUSH', OPpINDEX_BOOLNEG => 'NEG', + OPpITER_DEF => 'DEF', OPpITER_REVERSED => 'REVERSED', OPpKVSLICE => 'KVSLICE', OPpLIST_GUESSED => 'GUESSED', @@ -814,6 +819,7 @@ our %ops_using = ( OPpHINT_STRICT_REFS => [qw(entersub multideref rv2av rv2cv rv2gv rv2hv rv2sv)], OPpHUSH_VMSISH => [qw(dbstate nextstate)], OPpINDEX_BOOLNEG => [qw(index rindex)], + OPpITER_DEF => [qw(enteriter)], OPpITER_REVERSED => [qw(enteriter iter)], OPpKVSLICE => [qw(delete)], OPpLIST_GUESSED => [qw(list)], diff --git a/lib/feature.pm b/lib/feature.pm index e9cf2f77b9..70df619e49 100644 --- a/lib/feature.pm +++ b/lib/feature.pm @@ -5,7 +5,7 @@ package feature; -our $VERSION = '1.50'; +our $VERSION = '1.51'; our %feature = ( fc => 'feature_fc', @@ -151,7 +151,7 @@ explicitly disabled the warning: no warnings "experimental::smartmatch"; -C<use feature 'switch'> tells the compiler to enable the +C<use feature 'switch'> tells the compiler to enable the Perl 6 given/when construct. See L<perlsyn/"Switch Statements"> for details. diff --git a/lib/overload.pm b/lib/overload.pm index 45c48958e5..b19c5a53cb 100644 --- a/lib/overload.pm +++ b/lib/overload.pm @@ -1,6 +1,6 @@ package overload; -our $VERSION = '1.29'; +our $VERSION = '1.30'; %ops = ( with_assign => "+ - * / % ** << >> x .", @@ -522,8 +522,33 @@ This overload was introduced in Perl 5.12. =item * I<Matching> The key C<"~~"> allows you to override the smart matching logic used by -the C<~~> operator. See L<perlop/"Smartmatch Operator">. -Unusually, the overloaded only takes effect for the right-hand operand. +the C<~~> operator and the switch construct (C<given>/C<when>). See +L<perlsyn/Switch Statements> and L<feature>. + +Unusually, the overloaded implementation of the smart match operator +does not get full control of the smart match behaviour. +In particular, in the following code: + + package Foo; + use overload '~~' => 'match'; + + my $obj = Foo->new(); + $obj ~~ [ 1,2,3 ]; + +the smart match does I<not> invoke the method call like this: + + $obj->match([1,2,3],0); + +rather, the smart match distributive rule takes precedence, so $obj is +smart matched against each array element in turn until a match is found, +so you may see between one and three of these calls instead: + + $obj->match(1,0); + $obj->match(2,0); + $obj->match(3,0); + +Consult the match table in L<perlop/"Smartmatch Operator"> for +details of when overloading is invoked. =item * I<Dereferencing> diff --git a/lib/overload.t b/lib/overload.t index 99f5b64adb..2afa6cf437 100644 --- a/lib/overload.t +++ b/lib/overload.t @@ -48,7 +48,7 @@ package main; $| = 1; BEGIN { require './test.pl'; require './charset_tools.pl' } -plan tests => 5392; +plan tests => 5338; use Scalar::Util qw(tainted); @@ -1622,11 +1622,6 @@ foreach my $op (qw(<=> == != < <= > >=)) { is($y, $o, "copy constructor falls back to assignment (preinc)"); } -{ - package MatchAbc; - use overload '~~' => sub { $_[1] eq "abc" }; -} - # only scalar 'x' should currently overload { @@ -1840,10 +1835,7 @@ foreach my $op (qw(<=> == != < <= > >=)) { $e = '"abc" ~~ (%s)'; $subs{'~~'} = $e; - push @tests, [ bless({}, "MatchAbc"), $e, '(~~)', '(NM:~~)', - [ 1, 1, 0 ], 0 ]; - $e = '(%s) ~~ bless({}, "MatchAbc")'; - push @tests, [ "xyz", $e, '(eq)', '(NM:eq)', [ 1, 1, 0 ], 0 ]; + push @tests, [ "abc", $e, '(~~)', '(NM:~~)', [ 1, 1, 0 ], 0 ]; $subs{'-X'} = 'do { my $f = (%s);' . '$_[1] eq "r" ? (-r ($f)) :' @@ -1832,7 +1832,7 @@ Perl_scalar(pTHX_ OP *o) do_kids: while (kid) { OP *sib = OpSIBLING(kid); - if (sib && kid->op_type != OP_LEAVEWHERESO + if (sib && kid->op_type != OP_LEAVEWHEN && ( OpHAS_SIBLING(sib) || sib->op_type != OP_NULL || ( sib->op_targ != OP_NEXTSTATE && sib->op_targ != OP_DBSTATE ))) @@ -1923,7 +1923,7 @@ Perl_scalarvoid(pTHX_ OP *arg) want = o->op_flags & OPf_WANT; if ((want && want != OPf_WANT_SCALAR) || (PL_parser && PL_parser->error_count) - || o->op_type == OP_RETURN || o->op_type == OP_REQUIRE || o->op_type == OP_LEAVEWHERESO) + || o->op_type == OP_RETURN || o->op_type == OP_REQUIRE || o->op_type == OP_LEAVEWHEN) { continue; } @@ -2191,7 +2191,7 @@ Perl_scalarvoid(pTHX_ OP *arg) case OP_DOR: case OP_COND_EXPR: case OP_ENTERGIVEN: - case OP_ENTERWHERESO: + case OP_ENTERWHEN: for (kid = OpSIBLING(cUNOPo->op_first); kid; kid = OpSIBLING(kid)) if (!(kid->op_flags & OPf_KIDS)) scalarvoid(kid); @@ -2215,7 +2215,8 @@ Perl_scalarvoid(pTHX_ OP *arg) case OP_LEAVETRY: case OP_LEAVELOOP: case OP_LINESEQ: - case OP_LEAVEWHERESO: + case OP_LEAVEGIVEN: + case OP_LEAVEWHEN: kids: for (kid = cLISTOPo->op_first; kid; kid = OpSIBLING(kid)) if (!(kid->op_flags & OPf_KIDS)) @@ -2355,7 +2356,7 @@ Perl_list(pTHX_ OP *o) do_kids: while (kid) { OP *sib = OpSIBLING(kid); - if (sib && kid->op_type != OP_LEAVEWHERESO) + if (sib && kid->op_type != OP_LEAVEWHEN) scalarvoid(kid); else list(kid); @@ -8647,6 +8648,16 @@ Perl_newFOROP(pTHX_ I32 flags, OP *sv, OP *expr, OP *block, OP *cont) if (sv->op_type == OP_RV2SV) { /* symbol table variable */ iterpflags = sv->op_private & OPpOUR_INTRO; /* for our $x () */ OpTYPE_set(sv, OP_RV2GV); + + /* The op_type check is needed to prevent a possible segfault + * if the loop variable is undeclared and 'strict vars' is in + * effect. This is illegal but is nonetheless parsed, so we + * may reach this point with an OP_CONST where we're expecting + * an OP_GV. + */ + if (cUNOPx(sv)->op_first->op_type == OP_GV + && cGVOPx_gv(cUNOPx(sv)->op_first) == PL_defgv) + iterpflags |= OPpITER_DEF; } else if (sv->op_type == OP_PADSV) { /* private variable */ iterpflags = sv->op_private & OPpLVAL_INTRO; /* for my $x () */ @@ -8660,9 +8671,17 @@ Perl_newFOROP(pTHX_ I32 flags, OP *sv, OP *expr, OP *block, OP *cont) NOOP; else Perl_croak(aTHX_ "Can't use %s for loop variable", PL_op_desc[sv->op_type]); + if (padoff) { + PADNAME * const pn = PAD_COMPNAME(padoff); + const char * const name = PadnamePV(pn); + + if (PadnameLEN(pn) == 2 && name[0] == '$' && name[1] == '_') + iterpflags |= OPpITER_DEF; + } } else { sv = newGVOP(OP_GV, 0, PL_defgv); + iterpflags |= OPpITER_DEF; } if (expr->op_type == OP_RV2AV || expr->op_type == OP_PADAV) { @@ -8791,11 +8810,178 @@ Perl_newLOOPEX(pTHX_ I32 type, OP *label) return o; } +/* if the condition is a literal array or hash + (or @{ ... } etc), make a reference to it. + */ +STATIC OP * +S_ref_array_or_hash(pTHX_ OP *cond) +{ + if (cond + && (cond->op_type == OP_RV2AV + || cond->op_type == OP_PADAV + || cond->op_type == OP_RV2HV + || cond->op_type == OP_PADHV)) + + return newUNOP(OP_REFGEN, 0, op_lvalue(cond, OP_REFGEN)); + + else if(cond + && (cond->op_type == OP_ASLICE + || cond->op_type == OP_KVASLICE + || cond->op_type == OP_HSLICE + || cond->op_type == OP_KVHSLICE)) { + + /* anonlist now needs a list from this op, was previously used in + * scalar context */ + cond->op_flags &= ~(OPf_WANT_SCALAR | OPf_REF); + cond->op_flags |= OPf_WANT_LIST; + + return newANONLIST(op_lvalue(cond, OP_ANONLIST)); + } + + else + return cond; +} + +/* These construct the optree fragments representing given() + and when() blocks. + + entergiven and enterwhen are LOGOPs; the op_other pointer + points up to the associated leave op. We need this so we + can put it in the context and make break/continue work. + (Also, of course, pp_enterwhen will jump straight to + op_other if the match fails.) + */ + +STATIC OP * +S_newGIVWHENOP(pTHX_ OP *cond, OP *block, + I32 enter_opcode, I32 leave_opcode, + PADOFFSET entertarg) +{ + dVAR; + LOGOP *enterop; + OP *o; + + PERL_ARGS_ASSERT_NEWGIVWHENOP; + PERL_UNUSED_ARG(entertarg); /* used to indicate targ of lexical $_ */ + + enterop = alloc_LOGOP(enter_opcode, block, NULL); + enterop->op_targ = 0; + enterop->op_private = 0; + + o = newUNOP(leave_opcode, 0, (OP *) enterop); + + if (cond) { + /* prepend cond if we have one */ + op_sibling_splice((OP*)enterop, NULL, 0, scalar(cond)); + + o->op_next = LINKLIST(cond); + cond->op_next = (OP *) enterop; + } + else { + /* This is a default {} block */ + enterop->op_flags |= OPf_SPECIAL; + o ->op_flags |= OPf_SPECIAL; + + o->op_next = (OP *) enterop; + } + + CHECKOP(enter_opcode, enterop); /* Currently does nothing, since + entergiven and enterwhen both + use ck_null() */ + + enterop->op_next = LINKLIST(block); + block->op_next = enterop->op_other = o; + + return o; +} + +/* Does this look like a boolean operation? For these purposes + a boolean operation is: + - a subroutine call [*] + - a logical connective + - a comparison operator + - a filetest operator, with the exception of -s -M -A -C + - defined(), exists() or eof() + - /$re/ or $foo =~ /$re/ + + [*] possibly surprising + */ +STATIC bool +S_looks_like_bool(pTHX_ const OP *o) +{ + PERL_ARGS_ASSERT_LOOKS_LIKE_BOOL; + + switch(o->op_type) { + case OP_OR: + case OP_DOR: + return looks_like_bool(cLOGOPo->op_first); + + case OP_AND: + { + OP* sibl = OpSIBLING(cLOGOPo->op_first); + ASSUME(sibl); + return ( + looks_like_bool(cLOGOPo->op_first) + && looks_like_bool(sibl)); + } + + case OP_NULL: + case OP_SCALAR: + return ( + o->op_flags & OPf_KIDS + && looks_like_bool(cUNOPo->op_first)); + + case OP_ENTERSUB: + + case OP_NOT: case OP_XOR: + + case OP_EQ: case OP_NE: case OP_LT: + case OP_GT: case OP_LE: case OP_GE: + + case OP_I_EQ: case OP_I_NE: case OP_I_LT: + case OP_I_GT: case OP_I_LE: case OP_I_GE: + + case OP_SEQ: case OP_SNE: case OP_SLT: + case OP_SGT: case OP_SLE: case OP_SGE: + + case OP_SMARTMATCH: + + case OP_FTRREAD: case OP_FTRWRITE: case OP_FTREXEC: + case OP_FTEREAD: case OP_FTEWRITE: case OP_FTEEXEC: + case OP_FTIS: case OP_FTEOWNED: case OP_FTROWNED: + case OP_FTZERO: case OP_FTSOCK: case OP_FTCHR: + case OP_FTBLK: case OP_FTFILE: case OP_FTDIR: + case OP_FTPIPE: case OP_FTLINK: case OP_FTSUID: + case OP_FTSGID: case OP_FTSVTX: case OP_FTTTY: + case OP_FTTEXT: case OP_FTBINARY: + + case OP_DEFINED: case OP_EXISTS: + case OP_MATCH: case OP_EOF: + + case OP_FLOP: + + return TRUE; + + case OP_CONST: + /* Detect comparisons that have been optimized away */ + if (cSVOPo->op_sv == &PL_sv_yes + || cSVOPo->op_sv == &PL_sv_no) + + return TRUE; + else + return FALSE; + + /* FALLTHROUGH */ + default: + return FALSE; + } +} + /* -=for apidoc Am|OP *|newGIVENOP|OP *topic|OP *block|PADOFFSET defsv_off +=for apidoc Am|OP *|newGIVENOP|OP *cond|OP *block|PADOFFSET defsv_off Constructs, checks, and returns an op tree expressing a C<given> block. -C<topic> supplies the expression to whose value C<$_> will be locally +C<cond> supplies the expression to whose value C<$_> will be locally aliased, and C<block> supplies the body of the C<given> construct; they are consumed by this function and become part of the constructed op tree. C<defsv_off> must be zero (it used to identity the pad slot of lexical $_). @@ -8804,64 +8990,49 @@ C<defsv_off> must be zero (it used to identity the pad slot of lexical $_). */ OP * -Perl_newGIVENOP(pTHX_ OP *topic, OP *block, PADOFFSET defsv_off) +Perl_newGIVENOP(pTHX_ OP *cond, OP *block, PADOFFSET defsv_off) { - OP *enterop, *leaveop; PERL_ARGS_ASSERT_NEWGIVENOP; PERL_UNUSED_ARG(defsv_off); - assert(!defsv_off); - NewOpSz(1101, enterop, sizeof(LOOP)); - OpTYPE_set(enterop, OP_ENTERGIVEN); - cLOOPx(enterop)->op_first = scalar(topic); - cLOOPx(enterop)->op_last = block; - OpMORESIB_set(topic, block); - OpLASTSIB_set(block, enterop); - enterop->op_flags = OPf_KIDS; - - leaveop = newBINOP(OP_LEAVELOOP, 0, enterop, newOP(OP_NULL, 0)); - leaveop->op_next = LINKLIST(topic); - topic->op_next = enterop; - enterop = CHECKOP(OP_ENTERGIVEN, enterop); - cLOOPx(enterop)->op_redoop = enterop->op_next = LINKLIST(block); - cLOOPx(enterop)->op_lastop = cLOOPx(enterop)->op_nextop = block->op_next = - leaveop; - - return leaveop; + assert(!defsv_off); + return newGIVWHENOP( + ref_array_or_hash(cond), + block, + OP_ENTERGIVEN, OP_LEAVEGIVEN, + 0); } /* -=for apidoc Am|OP *|newWHERESOOP|OP *cond|OP *block +=for apidoc Am|OP *|newWHENOP|OP *cond|OP *block -Constructs, checks, and returns an op tree expressing a C<whereso> block. +Constructs, checks, and returns an op tree expressing a C<when> block. C<cond> supplies the test expression, and C<block> supplies the block that will be executed if the test evaluates to true; they are consumed -by this function and become part of the constructed op tree. +by this function and become part of the constructed op tree. C<cond> +will be interpreted DWIMically, often as a comparison against C<$_>, +and may be null to generate a C<default> block. =cut */ OP * -Perl_newWHERESOOP(pTHX_ OP *cond, OP *block) +Perl_newWHENOP(pTHX_ OP *cond, OP *block) { - OP *enterop, *leaveop; - PERL_ARGS_ASSERT_NEWWHERESOOP; - - NewOpSz(1101, enterop, sizeof(LOGOP)); - OpTYPE_set(enterop, OP_ENTERWHERESO); - cLOGOPx(enterop)->op_first = scalar(cond); - OpMORESIB_set(cond, block); - OpLASTSIB_set(block, enterop); - enterop->op_flags = OPf_KIDS; - - leaveop = newUNOP(OP_LEAVEWHERESO, 0, enterop); - leaveop->op_next = LINKLIST(cond); - cond->op_next = enterop; - enterop = CHECKOP(OP_ENTERWHERESO, enterop); - enterop->op_next = LINKLIST(block); - cLOGOPx(enterop)->op_other = block->op_next = leaveop; + const bool cond_llb = (!cond || looks_like_bool(cond)); + OP *cond_op; - return leaveop; + PERL_ARGS_ASSERT_NEWWHENOP; + + if (cond_llb) + cond_op = cond; + else { + cond_op = newBINOP(OP_SMARTMATCH, OPf_SPECIAL, + newDEFSVOP(), + scalar(ref_array_or_hash(cond))); + } + + return newGIVWHENOP(cond_op, block, OP_ENTERWHEN, OP_LEAVEWHEN, 0); } /* must not conflict with SVf_UTF8 */ @@ -11786,6 +11957,40 @@ Perl_ck_listiob(pTHX_ OP *o) return listkids(o); } +OP * +Perl_ck_smartmatch(pTHX_ OP *o) +{ + dVAR; + PERL_ARGS_ASSERT_CK_SMARTMATCH; + if (0 == (o->op_flags & OPf_SPECIAL)) { + OP *first = cBINOPo->op_first; + OP *second = OpSIBLING(first); + + /* Implicitly take a reference to an array or hash */ + + /* remove the original two siblings, then add back the + * (possibly different) first and second sibs. + */ + op_sibling_splice(o, NULL, 1, NULL); + op_sibling_splice(o, NULL, 1, NULL); + first = ref_array_or_hash(first); + second = ref_array_or_hash(second); + op_sibling_splice(o, NULL, 0, second); + op_sibling_splice(o, NULL, 0, first); + + /* Implicitly take a reference to a regular expression */ + if (first->op_type == OP_MATCH && !(first->op_flags & OPf_STACKED)) { + OpTYPE_set(first, OP_QR); + } + if (second->op_type == OP_MATCH && !(second->op_flags & OPf_STACKED)) { + OpTYPE_set(second, OP_QR); + } + } + + return o; +} + + static OP * S_maybe_targlex(pTHX_ OP *o) { @@ -15772,7 +15977,6 @@ Perl_rpeep(pTHX_ OP *o) case OP_ENTERLOOP: case OP_ENTERITER: - case OP_ENTERGIVEN: while (cLOOP->op_redoop->op_type == OP_NULL) cLOOP->op_redoop = cLOOP->op_redoop->op_next; while (cLOOP->op_nextop->op_type == OP_NULL) @@ -129,6 +129,9 @@ Deprecated. Use C<GIMME_V> instead. /* On OP_DBSTATE, indicates breakpoint * (runtime property) */ /* On OP_REQUIRE, was seen as CORE::require */ + /* On OP_(ENTER|LEAVE)WHEN, there's + no condition */ + /* On OP_SMARTMATCH, an implicit smartmatch */ /* On OP_ANONHASH and OP_ANONLIST, create a reference to the new anon hash or array */ /* On OP_HELEM, OP_MULTIDEREF and OP_HSLICE, @@ -364,8 +364,10 @@ EXTCONST char* const PL_op_name[] = { "method_redir", "method_redir_super", "entergiven", - "enterwhereso", - "leavewhereso", + "leavegiven", + "enterwhen", + "leavewhen", + "break", "continue", "open", "close", @@ -767,8 +769,10 @@ EXTCONST char* const PL_op_desc[] = { "redirect method with known name", "redirect super method with known name", "given()", - "whereso()", - "leave whereso block", + "leave given block", + "when()", + "leave when block", + "break", "continue", "open", "close", @@ -1182,8 +1186,10 @@ EXT Perl_ppaddr_t PL_ppaddr[] /* or perlvars.h */ Perl_pp_method_redir, Perl_pp_method_redir_super, Perl_pp_entergiven, - Perl_pp_enterwhereso, - Perl_pp_leavewhereso, + Perl_pp_leavegiven, + Perl_pp_enterwhen, + Perl_pp_leavewhen, + Perl_pp_break, Perl_pp_continue, Perl_pp_open, Perl_pp_close, @@ -1482,7 +1488,7 @@ EXT Perl_check_t PL_check[] /* or perlvars.h */ Perl_ck_bitop, /* complement */ Perl_ck_bitop, /* ncomplement */ Perl_ck_bitop, /* scomplement */ - Perl_ck_null, /* smartmatch */ + Perl_ck_smartmatch, /* smartmatch */ Perl_ck_fun, /* atan2 */ Perl_ck_fun, /* sin */ Perl_ck_fun, /* cos */ @@ -1593,8 +1599,10 @@ EXT Perl_check_t PL_check[] /* or perlvars.h */ Perl_ck_null, /* method_redir */ Perl_ck_null, /* method_redir_super */ Perl_ck_null, /* entergiven */ - Perl_ck_null, /* enterwhereso */ - Perl_ck_null, /* leavewhereso */ + Perl_ck_null, /* leavegiven */ + Perl_ck_null, /* enterwhen */ + Perl_ck_null, /* leavewhen */ + Perl_ck_null, /* break */ Perl_ck_null, /* continue */ Perl_ck_open, /* open */ Perl_ck_fun, /* close */ @@ -1889,7 +1897,7 @@ EXTCONST U32 PL_opargs[] = { 0x0000110e, /* complement */ 0x0000111e, /* ncomplement */ 0x0000111e, /* scomplement */ - 0x00011206, /* smartmatch */ + 0x00000204, /* smartmatch */ 0x0001141e, /* atan2 */ 0x00009b9e, /* sin */ 0x00009b9e, /* cos */ @@ -1999,9 +2007,11 @@ EXTCONST U32 PL_opargs[] = { 0x00000e40, /* method_super */ 0x00000e40, /* method_redir */ 0x00000e40, /* method_redir_super */ - 0x00000940, /* entergiven */ - 0x00000340, /* enterwhereso */ - 0x00000100, /* leavewhereso */ + 0x00000340, /* entergiven */ + 0x00000100, /* leavegiven */ + 0x00000340, /* enterwhen */ + 0x00000100, /* leavewhen */ + 0x00000000, /* break */ 0x00000000, /* continue */ 0x0029640d, /* open */ 0x0000eb04, /* close */ @@ -2224,6 +2234,7 @@ END_EXTERN_C #define OPpENTERSUB_AMPER 0x08 #define OPpEVAL_BYTES 0x08 #define OPpFT_STACKING 0x08 +#define OPpITER_DEF 0x08 #define OPpLVREF_ITER 0x08 #define OPpMAYBE_LVSUB 0x08 #define OPpMULTICONCAT_STRINGIFY 0x08 @@ -2340,6 +2351,7 @@ EXTCONST char PL_op_private_labels[] = { 'C','V','\0', 'C','V','2','G','V','\0', 'D','B','G','\0', + 'D','E','F','\0', 'D','E','L','\0', 'D','E','L','E','T','E','\0', 'D','E','R','E','F','1','\0', @@ -2430,14 +2442,14 @@ EXTCONST char PL_op_private_labels[] = { EXTCONST I16 PL_op_private_bitfields[] = { 0, 8, -1, 0, 8, -1, - 0, 579, -1, + 0, 583, -1, 0, 8, -1, 0, 8, -1, - 0, 586, -1, - 0, 575, -1, - 1, -1, 0, 543, 1, 40, 2, 286, -1, - 4, -1, 1, 167, 2, 174, 3, 181, -1, - 4, -1, 0, 543, 1, 40, 2, 286, 3, 117, -1, + 0, 590, -1, + 0, 579, -1, + 1, -1, 0, 547, 1, 40, 2, 290, -1, + 4, -1, 1, 171, 2, 178, 3, 185, -1, + 4, -1, 0, 547, 1, 40, 2, 290, 3, 117, -1, }; @@ -2648,26 +2660,28 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 181, /* leave */ -1, /* scope */ 183, /* enteriter */ - 186, /* iter */ + 187, /* iter */ -1, /* enterloop */ - 187, /* leaveloop */ + 188, /* leaveloop */ -1, /* return */ - 189, /* last */ - 189, /* next */ - 189, /* redo */ - 189, /* dump */ - 189, /* goto */ + 190, /* last */ + 190, /* next */ + 190, /* redo */ + 190, /* dump */ + 190, /* goto */ 52, /* exit */ 0, /* method */ 0, /* method_named */ 0, /* method_super */ 0, /* method_redir */ 0, /* method_redir_super */ - -1, /* entergiven */ - 0, /* enterwhereso */ - 0, /* leavewhereso */ + 0, /* entergiven */ + 0, /* leavegiven */ + 0, /* enterwhen */ + 0, /* leavewhen */ + -1, /* break */ -1, /* continue */ - 191, /* open */ + 192, /* open */ 52, /* close */ 52, /* pipe_op */ 52, /* fileno */ @@ -2713,33 +2727,33 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 0, /* getpeername */ 0, /* lstat */ 0, /* stat */ - 196, /* ftrread */ - 196, /* ftrwrite */ - 196, /* ftrexec */ - 196, /* fteread */ - 196, /* ftewrite */ - 196, /* fteexec */ - 201, /* ftis */ - 201, /* ftsize */ - 201, /* ftmtime */ - 201, /* ftatime */ - 201, /* ftctime */ - 201, /* ftrowned */ - 201, /* fteowned */ - 201, /* ftzero */ - 201, /* ftsock */ - 201, /* ftchr */ - 201, /* ftblk */ - 201, /* ftfile */ - 201, /* ftdir */ - 201, /* ftpipe */ - 201, /* ftsuid */ - 201, /* ftsgid */ - 201, /* ftsvtx */ - 201, /* ftlink */ - 201, /* fttty */ - 201, /* fttext */ - 201, /* ftbinary */ + 197, /* ftrread */ + 197, /* ftrwrite */ + 197, /* ftrexec */ + 197, /* fteread */ + 197, /* ftewrite */ + 197, /* fteexec */ + 202, /* ftis */ + 202, /* ftsize */ + 202, /* ftmtime */ + 202, /* ftatime */ + 202, /* ftctime */ + 202, /* ftrowned */ + 202, /* fteowned */ + 202, /* ftzero */ + 202, /* ftsock */ + 202, /* ftchr */ + 202, /* ftblk */ + 202, /* ftfile */ + 202, /* ftdir */ + 202, /* ftpipe */ + 202, /* ftsuid */ + 202, /* ftsgid */ + 202, /* ftsvtx */ + 202, /* ftlink */ + 202, /* fttty */ + 202, /* fttext */ + 202, /* ftbinary */ 93, /* chdir */ 93, /* chown */ 75, /* chroot */ @@ -2759,17 +2773,17 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 0, /* rewinddir */ 0, /* closedir */ -1, /* fork */ - 205, /* wait */ + 206, /* wait */ 93, /* waitpid */ 93, /* system */ 93, /* exec */ 93, /* kill */ - 205, /* getppid */ + 206, /* getppid */ 93, /* getpgrp */ 93, /* setpgrp */ 93, /* getpriority */ 93, /* setpriority */ - 205, /* time */ + 206, /* time */ -1, /* tms */ 0, /* localtime */ 52, /* gmtime */ @@ -2789,7 +2803,7 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 0, /* require */ 0, /* dofile */ -1, /* hintseval */ - 206, /* entereval */ + 207, /* entereval */ 174, /* leaveeval */ 0, /* entertry */ -1, /* leavetry */ @@ -2828,18 +2842,18 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 0, /* lock */ 0, /* once */ -1, /* custom */ - 212, /* coreargs */ - 216, /* avhvswitch */ + 213, /* coreargs */ + 217, /* avhvswitch */ 3, /* runcv */ 0, /* fc */ -1, /* padcv */ -1, /* introcv */ -1, /* clonecv */ - 218, /* padrange */ - 220, /* refassign */ - 226, /* lvref */ - 232, /* lvrefslice */ - 233, /* lvavref */ + 219, /* padrange */ + 221, /* refassign */ + 227, /* lvref */ + 233, /* lvrefslice */ + 234, /* lvavref */ 0, /* anonconst */ }; @@ -2859,76 +2873,76 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { */ EXTCONST U16 PL_op_private_bitdefs[] = { - 0x0003, /* scalar, prototype, refgen, srefgen, readline, regcmaybe, regcreset, regcomp, substcont, chop, schop, defined, undef, study, preinc, i_preinc, predec, i_predec, postinc, i_postinc, postdec, i_postdec, negate, i_negate, not, complement, ucfirst, lcfirst, uc, lc, quotemeta, aeach, avalues, each, pop, shift, grepstart, mapstart, mapwhile, range, and, or, dor, andassign, orassign, dorassign, argcheck, argdefelem, method, method_named, method_super, method_redir, method_redir_super, enterwhereso, leavewhereso, untie, tied, dbmclose, getsockname, getpeername, lstat, stat, readlink, readdir, telldir, rewinddir, closedir, localtime, alarm, require, dofile, entertry, ghbyname, gnbyname, gpbyname, shostent, snetent, sprotoent, sservent, gpwnam, gpwuid, ggrnam, ggrgid, lock, once, fc, anonconst */ - 0x2ebc, 0x4099, /* pushmark */ + 0x0003, /* scalar, prototype, refgen, srefgen, readline, regcmaybe, regcreset, regcomp, substcont, chop, schop, defined, undef, study, preinc, i_preinc, predec, i_predec, postinc, i_postinc, postdec, i_postdec, negate, i_negate, not, complement, ucfirst, lcfirst, uc, lc, quotemeta, aeach, avalues, each, pop, shift, grepstart, mapstart, mapwhile, range, and, or, dor, andassign, orassign, dorassign, argcheck, argdefelem, method, method_named, method_super, method_redir, method_redir_super, entergiven, leavegiven, enterwhen, leavewhen, untie, tied, dbmclose, getsockname, getpeername, lstat, stat, readlink, readdir, telldir, rewinddir, closedir, localtime, alarm, require, dofile, entertry, ghbyname, gnbyname, gpbyname, shostent, snetent, sprotoent, sservent, gpwnam, gpwuid, ggrnam, ggrgid, lock, once, fc, anonconst */ + 0x2f3c, 0x4119, /* pushmark */ 0x00bd, /* wantarray, runcv */ - 0x0578, 0x1930, 0x414c, 0x3c08, 0x33e5, /* const */ - 0x2ebc, 0x3539, /* gvsv */ - 0x1795, /* gv */ + 0x0578, 0x19b0, 0x41cc, 0x3c88, 0x3465, /* const */ + 0x2f3c, 0x35b9, /* gvsv */ + 0x1815, /* gv */ 0x0067, /* gelem, lt, i_lt, gt, i_gt, le, i_le, ge, i_ge, eq, i_eq, ne, i_ne, ncmp, i_ncmp, slt, sgt, sle, sge, seq, sne, scmp, bit_and, bit_xor, bit_or, sbit_and, sbit_xor, sbit_or, smartmatch, lslice, xor */ - 0x2ebc, 0x4098, 0x03d7, /* padsv */ - 0x2ebc, 0x4098, 0x06f4, 0x2fac, 0x3d89, /* padav */ - 0x2ebc, 0x4098, 0x06f4, 0x0790, 0x2fac, 0x3d88, 0x2a21, /* padhv */ - 0x2ebc, 0x1b18, 0x03d6, 0x2fac, 0x3308, 0x4144, 0x0003, /* rv2gv */ - 0x2ebc, 0x3538, 0x03d6, 0x4144, 0x0003, /* rv2sv */ - 0x2fac, 0x0003, /* av2arylen, akeys, values, keys */ - 0x327c, 0x0fd8, 0x0d34, 0x028c, 0x4448, 0x4144, 0x0003, /* rv2cv */ + 0x2f3c, 0x4118, 0x03d7, /* padsv */ + 0x2f3c, 0x4118, 0x06f4, 0x302c, 0x3e09, /* padav */ + 0x2f3c, 0x4118, 0x06f4, 0x0790, 0x302c, 0x3e08, 0x2aa1, /* padhv */ + 0x2f3c, 0x1b98, 0x03d6, 0x302c, 0x3388, 0x41c4, 0x0003, /* rv2gv */ + 0x2f3c, 0x35b8, 0x03d6, 0x41c4, 0x0003, /* rv2sv */ + 0x302c, 0x0003, /* av2arylen, akeys, values, keys */ + 0x32fc, 0x0fd8, 0x0d34, 0x028c, 0x44c8, 0x41c4, 0x0003, /* rv2cv */ 0x06f4, 0x0790, 0x0003, /* ref */ 0x018f, /* bless, glob, sprintf, formline, unpack, pack, join, anonlist, anonhash, splice, warn, die, reset, exit, close, pipe_op, fileno, umask, binmode, tie, dbmopen, sselect, select, getc, read, enterwrite, sysopen, sysseek, sysread, syswrite, eof, tell, seek, truncate, fcntl, ioctl, send, recv, socket, sockpair, bind, connect, listen, accept, shutdown, gsockopt, ssockopt, open_dir, seekdir, gmtime, shmget, shmctl, shmread, shmwrite, msgget, msgctl, msgsnd, msgrcv, semop, semget, semctl, ghbyaddr, gnbyaddr, gpbynumber, gsbyname, gsbyport, syscall */ - 0x371c, 0x3638, 0x2774, 0x26b0, 0x0003, /* backtick */ + 0x379c, 0x36b8, 0x27f4, 0x2730, 0x0003, /* backtick */ 0x06f5, /* subst */ - 0x105c, 0x2098, 0x0914, 0x3ecc, 0x2428, 0x01e4, 0x0141, /* trans, transr */ + 0x10dc, 0x2118, 0x0914, 0x3f4c, 0x24a8, 0x01e4, 0x0141, /* trans, transr */ 0x0f1c, 0x0618, 0x0067, /* sassign */ - 0x0bd8, 0x0ad4, 0x09d0, 0x2fac, 0x06e8, 0x0067, /* aassign */ - 0x44f0, 0x0003, /* chomp, schomp, ncomplement, scomplement, sin, cos, exp, log, sqrt, int, hex, oct, abs, ord, chr, chroot, rmdir */ - 0x06f4, 0x2fac, 0x0003, /* pos */ - 0x44f0, 0x0067, /* pow, multiply, i_multiply, divide, i_divide, modulo, i_modulo, add, i_add, subtract, i_subtract, left_shift, right_shift, nbit_and, nbit_xor, nbit_or */ - 0x1418, 0x0067, /* repeat */ - 0x3198, 0x44f0, 0x0067, /* concat */ - 0x2ebc, 0x0358, 0x1b14, 0x44f0, 0x422c, 0x0003, /* multiconcat */ - 0x44f0, 0x018f, /* stringify, atan2, rand, srand, crypt, push, unshift, flock, chdir, chown, unlink, chmod, utime, rename, link, symlink, mkdir, waitpid, system, exec, kill, getpgrp, setpgrp, getpriority, setpriority, sleep */ - 0x06f4, 0x44f0, 0x0003, /* length */ - 0x3970, 0x2fac, 0x012b, /* substr */ - 0x2fac, 0x0067, /* vec */ - 0x3118, 0x06f4, 0x44f0, 0x018f, /* index, rindex */ - 0x2ebc, 0x3538, 0x06f4, 0x2fac, 0x3d88, 0x4144, 0x0003, /* rv2av */ + 0x0bd8, 0x0ad4, 0x09d0, 0x302c, 0x06e8, 0x0067, /* aassign */ + 0x4570, 0x0003, /* chomp, schomp, ncomplement, scomplement, sin, cos, exp, log, sqrt, int, hex, oct, abs, ord, chr, chroot, rmdir */ + 0x06f4, 0x302c, 0x0003, /* pos */ + 0x4570, 0x0067, /* pow, multiply, i_multiply, divide, i_divide, modulo, i_modulo, add, i_add, subtract, i_subtract, left_shift, right_shift, nbit_and, nbit_xor, nbit_or */ + 0x1498, 0x0067, /* repeat */ + 0x3218, 0x4570, 0x0067, /* concat */ + 0x2f3c, 0x0358, 0x1b94, 0x4570, 0x42ac, 0x0003, /* multiconcat */ + 0x4570, 0x018f, /* stringify, atan2, rand, srand, crypt, push, unshift, flock, chdir, chown, unlink, chmod, utime, rename, link, symlink, mkdir, waitpid, system, exec, kill, getpgrp, setpgrp, getpriority, setpriority, sleep */ + 0x06f4, 0x4570, 0x0003, /* length */ + 0x39f0, 0x302c, 0x012b, /* substr */ + 0x302c, 0x0067, /* vec */ + 0x3198, 0x06f4, 0x4570, 0x018f, /* index, rindex */ + 0x2f3c, 0x35b8, 0x06f4, 0x302c, 0x3e08, 0x41c4, 0x0003, /* rv2av */ 0x025f, /* aelemfast, aelemfast_lex */ - 0x2ebc, 0x2db8, 0x03d6, 0x2fac, 0x0067, /* aelem, helem */ - 0x2ebc, 0x2fac, 0x3d89, /* aslice, hslice */ - 0x2fad, /* kvaslice, kvhslice */ - 0x2ebc, 0x3cd8, 0x2ad4, 0x0003, /* delete */ - 0x4378, 0x0003, /* exists */ - 0x2ebc, 0x3538, 0x06f4, 0x0790, 0x2fac, 0x3d88, 0x4144, 0x2a21, /* rv2hv */ - 0x2ebc, 0x2db8, 0x10d4, 0x1a30, 0x2fac, 0x4144, 0x0003, /* multideref */ - 0x2ebc, 0x3538, 0x0430, 0x2bcc, 0x24e9, /* split */ - 0x2ebc, 0x2159, /* list */ - 0x465c, 0x3fb8, 0x1370, 0x280c, 0x3a68, 0x2904, 0x34a1, /* sort */ - 0x280c, 0x0003, /* reverse */ + 0x2f3c, 0x2e38, 0x03d6, 0x302c, 0x0067, /* aelem, helem */ + 0x2f3c, 0x302c, 0x3e09, /* aslice, hslice */ + 0x302d, /* kvaslice, kvhslice */ + 0x2f3c, 0x3d58, 0x2b54, 0x0003, /* delete */ + 0x43f8, 0x0003, /* exists */ + 0x2f3c, 0x35b8, 0x06f4, 0x0790, 0x302c, 0x3e08, 0x41c4, 0x2aa1, /* rv2hv */ + 0x2f3c, 0x2e38, 0x1154, 0x1ab0, 0x302c, 0x41c4, 0x0003, /* multideref */ + 0x2f3c, 0x35b8, 0x0430, 0x2c4c, 0x2569, /* split */ + 0x2f3c, 0x21d9, /* list */ + 0x46dc, 0x4038, 0x13f0, 0x288c, 0x3ae8, 0x2984, 0x3521, /* sort */ + 0x288c, 0x0003, /* reverse */ 0x06f4, 0x0003, /* grepwhile */ - 0x2c58, 0x0003, /* flip, flop */ - 0x2ebc, 0x0003, /* cond_expr */ - 0x2ebc, 0x0fd8, 0x03d6, 0x028c, 0x4448, 0x4144, 0x25c1, /* entersub */ - 0x37d8, 0x0003, /* leavesub, leavesublv, leavewrite, leaveeval */ + 0x2cd8, 0x0003, /* flip, flop */ + 0x2f3c, 0x0003, /* cond_expr */ + 0x2f3c, 0x0fd8, 0x03d6, 0x028c, 0x44c8, 0x41c4, 0x2641, /* entersub */ + 0x3858, 0x0003, /* leavesub, leavesublv, leavewrite, leaveeval */ 0x02aa, 0x0003, /* argelem */ 0x00bc, 0x018f, /* caller */ - 0x2335, /* nextstate, dbstate */ - 0x2d5c, 0x37d9, /* leave */ - 0x2ebc, 0x3538, 0x3ae5, /* enteriter */ - 0x3ae5, /* iter */ - 0x2d5c, 0x0067, /* leaveloop */ - 0x477c, 0x0003, /* last, next, redo, dump, goto */ - 0x371c, 0x3638, 0x2774, 0x26b0, 0x018f, /* open */ - 0x1cd0, 0x1f2c, 0x1de8, 0x1ba4, 0x0003, /* ftrread, ftrwrite, ftrexec, fteread, ftewrite, fteexec */ - 0x1cd0, 0x1f2c, 0x1de8, 0x0003, /* ftis, ftsize, ftmtime, ftatime, ftctime, ftrowned, fteowned, ftzero, ftsock, ftchr, ftblk, ftfile, ftdir, ftpipe, ftsuid, ftsgid, ftsvtx, ftlink, fttty, fttext, ftbinary */ - 0x44f1, /* wait, getppid, time */ - 0x3874, 0x0df0, 0x084c, 0x45c8, 0x2244, 0x0003, /* entereval */ - 0x307c, 0x0018, 0x1284, 0x11a1, /* coreargs */ - 0x2fac, 0x00c7, /* avhvswitch */ - 0x2ebc, 0x01fb, /* padrange */ - 0x2ebc, 0x4098, 0x04f6, 0x298c, 0x1888, 0x0067, /* refassign */ - 0x2ebc, 0x4098, 0x04f6, 0x298c, 0x1888, 0x0003, /* lvref */ - 0x2ebd, /* lvrefslice */ - 0x2ebc, 0x4098, 0x0003, /* lvavref */ + 0x23b5, /* nextstate, dbstate */ + 0x2ddc, 0x3859, /* leave */ + 0x2f3c, 0x35b8, 0x104c, 0x3b65, /* enteriter */ + 0x3b65, /* iter */ + 0x2ddc, 0x0067, /* leaveloop */ + 0x47fc, 0x0003, /* last, next, redo, dump, goto */ + 0x379c, 0x36b8, 0x27f4, 0x2730, 0x018f, /* open */ + 0x1d50, 0x1fac, 0x1e68, 0x1c24, 0x0003, /* ftrread, ftrwrite, ftrexec, fteread, ftewrite, fteexec */ + 0x1d50, 0x1fac, 0x1e68, 0x0003, /* ftis, ftsize, ftmtime, ftatime, ftctime, ftrowned, fteowned, ftzero, ftsock, ftchr, ftblk, ftfile, ftdir, ftpipe, ftsuid, ftsgid, ftsvtx, ftlink, fttty, fttext, ftbinary */ + 0x4571, /* wait, getppid, time */ + 0x38f4, 0x0df0, 0x084c, 0x4648, 0x22c4, 0x0003, /* entereval */ + 0x30fc, 0x0018, 0x1304, 0x1221, /* coreargs */ + 0x302c, 0x00c7, /* avhvswitch */ + 0x2f3c, 0x01fb, /* padrange */ + 0x2f3c, 0x4118, 0x04f6, 0x2a0c, 0x1908, 0x0067, /* refassign */ + 0x2f3c, 0x4118, 0x04f6, 0x2a0c, 0x1908, 0x0003, /* lvref */ + 0x2f3d, /* lvrefslice */ + 0x2f3c, 0x4118, 0x0003, /* lvavref */ }; @@ -3138,7 +3152,7 @@ EXTCONST U8 PL_op_private_valid[] = { /* ENTER */ (0), /* LEAVE */ (OPpREFCOUNTED|OPpLVALUE), /* SCOPE */ (0), - /* ENTERITER */ (OPpITER_REVERSED|OPpOUR_INTRO|OPpLVAL_INTRO), + /* ENTERITER */ (OPpITER_REVERSED|OPpITER_DEF|OPpOUR_INTRO|OPpLVAL_INTRO), /* ITER */ (OPpITER_REVERSED), /* ENTERLOOP */ (0), /* LEAVELOOP */ (OPpARG2_MASK|OPpLVALUE), @@ -3154,9 +3168,11 @@ EXTCONST U8 PL_op_private_valid[] = { /* METHOD_SUPER */ (OPpARG1_MASK), /* METHOD_REDIR */ (OPpARG1_MASK), /* METHOD_REDIR_SUPER */ (OPpARG1_MASK), - /* ENTERGIVEN */ (0), - /* ENTERWHERESO */ (OPpARG1_MASK), - /* LEAVEWHERESO */ (OPpARG1_MASK), + /* ENTERGIVEN */ (OPpARG1_MASK), + /* LEAVEGIVEN */ (OPpARG1_MASK), + /* ENTERWHEN */ (OPpARG1_MASK), + /* LEAVEWHEN */ (OPpARG1_MASK), + /* BREAK */ (0), /* CONTINUE */ (0), /* OPEN */ (OPpARG4_MASK|OPpOPEN_IN_RAW|OPpOPEN_IN_CRLF|OPpOPEN_OUT_RAW|OPpOPEN_OUT_CRLF), /* CLOSE */ (OPpARG4_MASK), @@ -232,187 +232,189 @@ typedef enum opcode { OP_METHOD_REDIR = 215, OP_METHOD_REDIR_SUPER = 216, OP_ENTERGIVEN = 217, - OP_ENTERWHERESO = 218, - OP_LEAVEWHERESO = 219, - OP_CONTINUE = 220, - OP_OPEN = 221, - OP_CLOSE = 222, - OP_PIPE_OP = 223, - OP_FILENO = 224, - OP_UMASK = 225, - OP_BINMODE = 226, - OP_TIE = 227, - OP_UNTIE = 228, - OP_TIED = 229, - OP_DBMOPEN = 230, - OP_DBMCLOSE = 231, - OP_SSELECT = 232, - OP_SELECT = 233, - OP_GETC = 234, - OP_READ = 235, - OP_ENTERWRITE = 236, - OP_LEAVEWRITE = 237, - OP_PRTF = 238, - OP_PRINT = 239, - OP_SAY = 240, - OP_SYSOPEN = 241, - OP_SYSSEEK = 242, - OP_SYSREAD = 243, - OP_SYSWRITE = 244, - OP_EOF = 245, - OP_TELL = 246, - OP_SEEK = 247, - OP_TRUNCATE = 248, - OP_FCNTL = 249, - OP_IOCTL = 250, - OP_FLOCK = 251, - OP_SEND = 252, - OP_RECV = 253, - OP_SOCKET = 254, - OP_SOCKPAIR = 255, - OP_BIND = 256, - OP_CONNECT = 257, - OP_LISTEN = 258, - OP_ACCEPT = 259, - OP_SHUTDOWN = 260, - OP_GSOCKOPT = 261, - OP_SSOCKOPT = 262, - OP_GETSOCKNAME = 263, - OP_GETPEERNAME = 264, - OP_LSTAT = 265, - OP_STAT = 266, - OP_FTRREAD = 267, - OP_FTRWRITE = 268, - OP_FTREXEC = 269, - OP_FTEREAD = 270, - OP_FTEWRITE = 271, - OP_FTEEXEC = 272, - OP_FTIS = 273, - OP_FTSIZE = 274, - OP_FTMTIME = 275, - OP_FTATIME = 276, - OP_FTCTIME = 277, - OP_FTROWNED = 278, - OP_FTEOWNED = 279, - OP_FTZERO = 280, - OP_FTSOCK = 281, - OP_FTCHR = 282, - OP_FTBLK = 283, - OP_FTFILE = 284, - OP_FTDIR = 285, - OP_FTPIPE = 286, - OP_FTSUID = 287, - OP_FTSGID = 288, - OP_FTSVTX = 289, - OP_FTLINK = 290, - OP_FTTTY = 291, - OP_FTTEXT = 292, - OP_FTBINARY = 293, - OP_CHDIR = 294, - OP_CHOWN = 295, - OP_CHROOT = 296, - OP_UNLINK = 297, - OP_CHMOD = 298, - OP_UTIME = 299, - OP_RENAME = 300, - OP_LINK = 301, - OP_SYMLINK = 302, - OP_READLINK = 303, - OP_MKDIR = 304, - OP_RMDIR = 305, - OP_OPEN_DIR = 306, - OP_READDIR = 307, - OP_TELLDIR = 308, - OP_SEEKDIR = 309, - OP_REWINDDIR = 310, - OP_CLOSEDIR = 311, - OP_FORK = 312, - OP_WAIT = 313, - OP_WAITPID = 314, - OP_SYSTEM = 315, - OP_EXEC = 316, - OP_KILL = 317, - OP_GETPPID = 318, - OP_GETPGRP = 319, - OP_SETPGRP = 320, - OP_GETPRIORITY = 321, - OP_SETPRIORITY = 322, - OP_TIME = 323, - OP_TMS = 324, - OP_LOCALTIME = 325, - OP_GMTIME = 326, - OP_ALARM = 327, - OP_SLEEP = 328, - OP_SHMGET = 329, - OP_SHMCTL = 330, - OP_SHMREAD = 331, - OP_SHMWRITE = 332, - OP_MSGGET = 333, - OP_MSGCTL = 334, - OP_MSGSND = 335, - OP_MSGRCV = 336, - OP_SEMOP = 337, - OP_SEMGET = 338, - OP_SEMCTL = 339, - OP_REQUIRE = 340, - OP_DOFILE = 341, - OP_HINTSEVAL = 342, - OP_ENTEREVAL = 343, - OP_LEAVEEVAL = 344, - OP_ENTERTRY = 345, - OP_LEAVETRY = 346, - OP_GHBYNAME = 347, - OP_GHBYADDR = 348, - OP_GHOSTENT = 349, - OP_GNBYNAME = 350, - OP_GNBYADDR = 351, - OP_GNETENT = 352, - OP_GPBYNAME = 353, - OP_GPBYNUMBER = 354, - OP_GPROTOENT = 355, - OP_GSBYNAME = 356, - OP_GSBYPORT = 357, - OP_GSERVENT = 358, - OP_SHOSTENT = 359, - OP_SNETENT = 360, - OP_SPROTOENT = 361, - OP_SSERVENT = 362, - OP_EHOSTENT = 363, - OP_ENETENT = 364, - OP_EPROTOENT = 365, - OP_ESERVENT = 366, - OP_GPWNAM = 367, - OP_GPWUID = 368, - OP_GPWENT = 369, - OP_SPWENT = 370, - OP_EPWENT = 371, - OP_GGRNAM = 372, - OP_GGRGID = 373, - OP_GGRENT = 374, - OP_SGRENT = 375, - OP_EGRENT = 376, - OP_GETLOGIN = 377, - OP_SYSCALL = 378, - OP_LOCK = 379, - OP_ONCE = 380, - OP_CUSTOM = 381, - OP_COREARGS = 382, - OP_AVHVSWITCH = 383, - OP_RUNCV = 384, - OP_FC = 385, - OP_PADCV = 386, - OP_INTROCV = 387, - OP_CLONECV = 388, - OP_PADRANGE = 389, - OP_REFASSIGN = 390, - OP_LVREF = 391, - OP_LVREFSLICE = 392, - OP_LVAVREF = 393, - OP_ANONCONST = 394, + OP_LEAVEGIVEN = 218, + OP_ENTERWHEN = 219, + OP_LEAVEWHEN = 220, + OP_BREAK = 221, + OP_CONTINUE = 222, + OP_OPEN = 223, + OP_CLOSE = 224, + OP_PIPE_OP = 225, + OP_FILENO = 226, + OP_UMASK = 227, + OP_BINMODE = 228, + OP_TIE = 229, + OP_UNTIE = 230, + OP_TIED = 231, + OP_DBMOPEN = 232, + OP_DBMCLOSE = 233, + OP_SSELECT = 234, + OP_SELECT = 235, + OP_GETC = 236, + OP_READ = 237, + OP_ENTERWRITE = 238, + OP_LEAVEWRITE = 239, + OP_PRTF = 240, + OP_PRINT = 241, + OP_SAY = 242, + OP_SYSOPEN = 243, + OP_SYSSEEK = 244, + OP_SYSREAD = 245, + OP_SYSWRITE = 246, + OP_EOF = 247, + OP_TELL = 248, + OP_SEEK = 249, + OP_TRUNCATE = 250, + OP_FCNTL = 251, + OP_IOCTL = 252, + OP_FLOCK = 253, + OP_SEND = 254, + OP_RECV = 255, + OP_SOCKET = 256, + OP_SOCKPAIR = 257, + OP_BIND = 258, + OP_CONNECT = 259, + OP_LISTEN = 260, + OP_ACCEPT = 261, + OP_SHUTDOWN = 262, + OP_GSOCKOPT = 263, + OP_SSOCKOPT = 264, + OP_GETSOCKNAME = 265, + OP_GETPEERNAME = 266, + OP_LSTAT = 267, + OP_STAT = 268, + OP_FTRREAD = 269, + OP_FTRWRITE = 270, + OP_FTREXEC = 271, + OP_FTEREAD = 272, + OP_FTEWRITE = 273, + OP_FTEEXEC = 274, + OP_FTIS = 275, + OP_FTSIZE = 276, + OP_FTMTIME = 277, + OP_FTATIME = 278, + OP_FTCTIME = 279, + OP_FTROWNED = 280, + OP_FTEOWNED = 281, + OP_FTZERO = 282, + OP_FTSOCK = 283, + OP_FTCHR = 284, + OP_FTBLK = 285, + OP_FTFILE = 286, + OP_FTDIR = 287, + OP_FTPIPE = 288, + OP_FTSUID = 289, + OP_FTSGID = 290, + OP_FTSVTX = 291, + OP_FTLINK = 292, + OP_FTTTY = 293, + OP_FTTEXT = 294, + OP_FTBINARY = 295, + OP_CHDIR = 296, + OP_CHOWN = 297, + OP_CHROOT = 298, + OP_UNLINK = 299, + OP_CHMOD = 300, + OP_UTIME = 301, + OP_RENAME = 302, + OP_LINK = 303, + OP_SYMLINK = 304, + OP_READLINK = 305, + OP_MKDIR = 306, + OP_RMDIR = 307, + OP_OPEN_DIR = 308, + OP_READDIR = 309, + OP_TELLDIR = 310, + OP_SEEKDIR = 311, + OP_REWINDDIR = 312, + OP_CLOSEDIR = 313, + OP_FORK = 314, + OP_WAIT = 315, + OP_WAITPID = 316, + OP_SYSTEM = 317, + OP_EXEC = 318, + OP_KILL = 319, + OP_GETPPID = 320, + OP_GETPGRP = 321, + OP_SETPGRP = 322, + OP_GETPRIORITY = 323, + OP_SETPRIORITY = 324, + OP_TIME = 325, + OP_TMS = 326, + OP_LOCALTIME = 327, + OP_GMTIME = 328, + OP_ALARM = 329, + OP_SLEEP = 330, + OP_SHMGET = 331, + OP_SHMCTL = 332, + OP_SHMREAD = 333, + OP_SHMWRITE = 334, + OP_MSGGET = 335, + OP_MSGCTL = 336, + OP_MSGSND = 337, + OP_MSGRCV = 338, + OP_SEMOP = 339, + OP_SEMGET = 340, + OP_SEMCTL = 341, + OP_REQUIRE = 342, + OP_DOFILE = 343, + OP_HINTSEVAL = 344, + OP_ENTEREVAL = 345, + OP_LEAVEEVAL = 346, + OP_ENTERTRY = 347, + OP_LEAVETRY = 348, + OP_GHBYNAME = 349, + OP_GHBYADDR = 350, + OP_GHOSTENT = 351, + OP_GNBYNAME = 352, + OP_GNBYADDR = 353, + OP_GNETENT = 354, + OP_GPBYNAME = 355, + OP_GPBYNUMBER = 356, + OP_GPROTOENT = 357, + OP_GSBYNAME = 358, + OP_GSBYPORT = 359, + OP_GSERVENT = 360, + OP_SHOSTENT = 361, + OP_SNETENT = 362, + OP_SPROTOENT = 363, + OP_SSERVENT = 364, + OP_EHOSTENT = 365, + OP_ENETENT = 366, + OP_EPROTOENT = 367, + OP_ESERVENT = 368, + OP_GPWNAM = 369, + OP_GPWUID = 370, + OP_GPWENT = 371, + OP_SPWENT = 372, + OP_EPWENT = 373, + OP_GGRNAM = 374, + OP_GGRGID = 375, + OP_GGRENT = 376, + OP_SGRENT = 377, + OP_EGRENT = 378, + OP_GETLOGIN = 379, + OP_SYSCALL = 380, + OP_LOCK = 381, + OP_ONCE = 382, + OP_CUSTOM = 383, + OP_COREARGS = 384, + OP_AVHVSWITCH = 385, + OP_RUNCV = 386, + OP_FC = 387, + OP_PADCV = 388, + OP_INTROCV = 389, + OP_CLONECV = 390, + OP_PADRANGE = 391, + OP_REFASSIGN = 392, + OP_LVREF = 393, + OP_LVREFSLICE = 394, + OP_LVAVREF = 395, + OP_ANONCONST = 396, OP_max } opcode; -#define MAXO 395 +#define MAXO 397 #define OP_FREED MAXO /* the OP_IS_* macros are optimized to a simple range check because @@ -3835,7 +3835,7 @@ Gid_t getegid (void); #define DEBUG_C_FLAG 0x00200000 /*2097152 */ #define DEBUG_A_FLAG 0x00400000 /*4194304 */ #define DEBUG_q_FLAG 0x00800000 /*8388608 */ -/* spare 16777216*/ +#define DEBUG_M_FLAG 0x01000000 /*16777216*/ #define DEBUG_B_FLAG 0x02000000 /*33554432*/ #define DEBUG_L_FLAG 0x04000000 /*67108864*/ #define DEBUG_i_FLAG 0x08000000 /*134217728*/ @@ -3867,6 +3867,7 @@ Gid_t getegid (void); # define DEBUG_C_TEST_ UNLIKELY(PL_debug & DEBUG_C_FLAG) # define DEBUG_A_TEST_ UNLIKELY(PL_debug & DEBUG_A_FLAG) # define DEBUG_q_TEST_ UNLIKELY(PL_debug & DEBUG_q_FLAG) +# define DEBUG_M_TEST_ UNLIKELY(PL_debug & DEBUG_M_FLAG) # define DEBUG_B_TEST_ UNLIKELY(PL_debug & DEBUG_B_FLAG) # define DEBUG_L_TEST_ UNLIKELY(PL_debug & DEBUG_L_FLAG) # define DEBUG_i_TEST_ UNLIKELY(PL_debug & DEBUG_i_FLAG) @@ -3900,6 +3901,7 @@ Gid_t getegid (void); # define DEBUG_C_TEST DEBUG_C_TEST_ # define DEBUG_A_TEST DEBUG_A_TEST_ # define DEBUG_q_TEST DEBUG_q_TEST_ +# define DEBUG_M_TEST DEBUG_M_TEST_ # define DEBUG_B_TEST DEBUG_B_TEST_ # define DEBUG_L_TEST DEBUG_L_TEST_ # define DEBUG_i_TEST DEBUG_i_TEST_ @@ -3963,6 +3965,7 @@ Gid_t getegid (void); # define DEBUG_C(a) DEBUG__(DEBUG_C_TEST, a) # define DEBUG_A(a) DEBUG__(DEBUG_A_TEST, a) # define DEBUG_q(a) DEBUG__(DEBUG_q_TEST, a) +# define DEBUG_M(a) DEBUG__(DEBUG_M_TEST, a) # define DEBUG_B(a) DEBUG__(DEBUG_B_TEST, a) # define DEBUG_L(a) DEBUG__(DEBUG_L_TEST, a) # define DEBUG_i(a) DEBUG__(DEBUG_i_TEST, a) @@ -3992,6 +3995,7 @@ Gid_t getegid (void); # define DEBUG_C_TEST (0) # define DEBUG_A_TEST (0) # define DEBUG_q_TEST (0) +# define DEBUG_M_TEST (0) # define DEBUG_B_TEST (0) # define DEBUG_L_TEST (0) # define DEBUG_i_TEST (0) @@ -4025,6 +4029,7 @@ Gid_t getegid (void); # define DEBUG_C(a) # define DEBUG_A(a) # define DEBUG_q(a) +# define DEBUG_M(a) # define DEBUG_B(a) # define DEBUG_L(a) # define DEBUG_i(a) @@ -4723,9 +4728,9 @@ EXTCONST unsigned char PL_freq[]; #ifdef DOINIT EXTCONST char* const PL_block_type[] = { "NULL", - "WHERESO", + "WHEN", "BLOCK", - "LOOP_GIVEN", + "GIVEN", "LOOP_ARY", "LOOP_LAZYSV", "LOOP_LAZYIV", @@ -392,18 +392,18 @@ case 2: case 39: #line 382 "perly.y" /* yacc.c:1646 */ - { - 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)))); - } + { (yyval.opval) = block_end((ps[-3].val.ival), newWHENOP((ps[-2].val.opval), op_scope((ps[0].val.opval)))); } break; case 40: -#line 390 "perly.y" /* yacc.c:1646 */ +#line 384 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = newWHENOP(0, op_scope((ps[0].val.opval))); } + + break; + + case 41: +#line 386 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = block_end((ps[-5].val.ival), newWHILEOP(0, 1, NULL, @@ -413,8 +413,8 @@ case 2: break; - case 41: -#line 397 "perly.y" /* yacc.c:1646 */ + case 42: +#line 393 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = block_end((ps[-5].val.ival), newWHILEOP(0, 1, NULL, @@ -424,20 +424,20 @@ case 2: break; - case 42: -#line 404 "perly.y" /* yacc.c:1646 */ + case 43: +#line 400 "perly.y" /* yacc.c:1646 */ { parser->expect = XTERM; } break; - case 43: -#line 406 "perly.y" /* yacc.c:1646 */ + case 44: +#line 402 "perly.y" /* yacc.c:1646 */ { parser->expect = XTERM; } break; - case 44: -#line 409 "perly.y" /* yacc.c:1646 */ + case 45: +#line 405 "perly.y" /* yacc.c:1646 */ { OP *initop = (ps[-9].val.opval); OP *forop = newWHILEOP(0, 1, NULL, @@ -455,8 +455,8 @@ case 2: break; - case 45: -#line 424 "perly.y" /* yacc.c:1646 */ + case 46: +#line 420 "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); @@ -464,8 +464,8 @@ case 2: break; - case 46: -#line 429 "perly.y" /* yacc.c:1646 */ + case 47: +#line 425 "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))); @@ -474,14 +474,14 @@ case 2: break; - case 47: -#line 435 "perly.y" /* yacc.c:1646 */ + case 48: +#line 431 "perly.y" /* yacc.c:1646 */ { parser->in_my = 0; (yyval.opval) = my((ps[0].val.opval)); } break; - case 48: -#line 437 "perly.y" /* yacc.c:1646 */ + case 49: +#line 433 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = block_end( (ps[-7].val.ival), @@ -497,8 +497,8 @@ case 2: break; - case 49: -#line 450 "perly.y" /* yacc.c:1646 */ + case 50: +#line 446 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = block_end((ps[-4].val.ival), newFOROP( 0, op_lvalue(newUNOP(OP_REFGEN, 0, @@ -509,8 +509,8 @@ case 2: break; - case 50: -#line 458 "perly.y" /* yacc.c:1646 */ + case 51: +#line 454 "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))); @@ -519,8 +519,8 @@ case 2: break; - case 51: -#line 464 "perly.y" /* yacc.c:1646 */ + case 52: +#line 460 "perly.y" /* yacc.c:1646 */ { /* a block is a loop that happens once */ (yyval.opval) = newWHILEOP(0, 1, NULL, @@ -529,8 +529,8 @@ case 2: break; - case 52: -#line 470 "perly.y" /* yacc.c:1646 */ + case 53: +#line 466 "perly.y" /* yacc.c:1646 */ { package((ps[-2].val.opval)); if ((ps[-3].val.opval)) { @@ -540,8 +540,8 @@ case 2: break; - case 53: -#line 477 "perly.y" /* yacc.c:1646 */ + case 54: +#line 473 "perly.y" /* yacc.c:1646 */ { /* a block is a loop that happens once */ (yyval.opval) = newWHILEOP(0, 1, NULL, @@ -552,16 +552,16 @@ case 2: break; - case 54: -#line 485 "perly.y" /* yacc.c:1646 */ + case 55: +#line 481 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[-1].val.opval); } break; - case 55: -#line 489 "perly.y" /* yacc.c:1646 */ + case 56: +#line 485 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLISTOP(OP_DIE, 0, newOP(OP_PUSHMARK, 0), newSVOP(OP_CONST, 0, newSVpvs("Unimplemented"))); @@ -569,8 +569,8 @@ case 2: break; - case 56: -#line 494 "perly.y" /* yacc.c:1646 */ + case 57: +#line 490 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; parser->copline = NOLINE; @@ -578,8 +578,8 @@ case 2: break; - case 57: -#line 502 "perly.y" /* yacc.c:1646 */ + case 58: +#line 498 "perly.y" /* yacc.c:1646 */ { OP *list; if ((ps[0].val.opval)) { OP *term = (ps[0].val.opval); @@ -597,81 +597,75 @@ case 2: break; - case 58: -#line 519 "perly.y" /* yacc.c:1646 */ + case 59: +#line 515 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 59: -#line 521 "perly.y" /* yacc.c:1646 */ + case 60: +#line 517 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_unscope((ps[-1].val.opval)); } break; - case 60: -#line 526 "perly.y" /* yacc.c:1646 */ + case 61: +#line 522 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 61: -#line 528 "perly.y" /* yacc.c:1646 */ + case 62: +#line 524 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; - case 62: -#line 530 "perly.y" /* yacc.c:1646 */ + case 63: +#line 526 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[0].val.opval), (ps[-2].val.opval)); } break; - case 63: -#line 532 "perly.y" /* yacc.c:1646 */ + case 64: +#line 528 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOGOP(OP_OR, 0, (ps[0].val.opval), (ps[-2].val.opval)); } break; - case 64: -#line 534 "perly.y" /* yacc.c:1646 */ + case 65: +#line 530 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOOPOP(OPf_PARENS, 1, scalar((ps[0].val.opval)), (ps[-2].val.opval)); } break; - case 65: -#line 536 "perly.y" /* yacc.c:1646 */ + case 66: +#line 532 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOOPOP(OPf_PARENS, 1, (ps[0].val.opval), (ps[-2].val.opval)); } break; - case 66: -#line 538 "perly.y" /* yacc.c:1646 */ + case 67: +#line 534 "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 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))); - } + case 68: +#line 537 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = newWHENOP((ps[0].val.opval), op_scope((ps[-2].val.opval))); } break; - case 68: -#line 552 "perly.y" /* yacc.c:1646 */ + case 69: +#line 542 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 69: -#line 554 "perly.y" /* yacc.c:1646 */ + case 70: +#line 544 "perly.y" /* yacc.c:1646 */ { ((ps[0].val.opval))->op_flags |= OPf_PARENS; (yyval.opval) = op_scope((ps[0].val.opval)); @@ -679,8 +673,8 @@ case 2: break; - case 70: -#line 559 "perly.y" /* yacc.c:1646 */ + case 71: +#line 549 "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)), @@ -690,153 +684,153 @@ case 2: break; - case 71: -#line 569 "perly.y" /* yacc.c:1646 */ + case 72: +#line 559 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 72: -#line 571 "perly.y" /* yacc.c:1646 */ + case 73: +#line 561 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_scope((ps[0].val.opval)); } break; - case 73: -#line 576 "perly.y" /* yacc.c:1646 */ + case 74: +#line 566 "perly.y" /* yacc.c:1646 */ { (yyval.ival) = (PL_min_intro_pending && PL_max_intro_pending >= PL_min_intro_pending); intro_my(); } break; - case 74: -#line 582 "perly.y" /* yacc.c:1646 */ + case 75: +#line 572 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 76: -#line 588 "perly.y" /* yacc.c:1646 */ + case 77: +#line 578 "perly.y" /* yacc.c:1646 */ { YYSTYPE tmplval; (void)scan_num("1", &tmplval); (yyval.opval) = tmplval.opval; } break; - case 78: -#line 596 "perly.y" /* yacc.c:1646 */ + case 79: +#line 586 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = invert(scalar((ps[0].val.opval))); } break; - case 79: -#line 601 "perly.y" /* yacc.c:1646 */ + case 80: +#line 591 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); intro_my(); } break; - case 80: -#line 605 "perly.y" /* yacc.c:1646 */ + case 81: +#line 595 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); intro_my(); } break; - case 81: -#line 608 "perly.y" /* yacc.c:1646 */ + case 82: +#line 598 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; - case 82: -#line 609 "perly.y" /* yacc.c:1646 */ + case 83: +#line 599 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 83: -#line 613 "perly.y" /* yacc.c:1646 */ + case 84: +#line 603 "perly.y" /* yacc.c:1646 */ { (yyval.ival) = start_subparse(FALSE, 0); SAVEFREESV(PL_compcv); } break; - case 84: -#line 619 "perly.y" /* yacc.c:1646 */ + case 85: +#line 609 "perly.y" /* yacc.c:1646 */ { (yyval.ival) = start_subparse(FALSE, CVf_ANON); SAVEFREESV(PL_compcv); } break; - case 85: -#line 624 "perly.y" /* yacc.c:1646 */ + case 86: +#line 614 "perly.y" /* yacc.c:1646 */ { (yyval.ival) = start_subparse(TRUE, 0); SAVEFREESV(PL_compcv); } break; - case 88: -#line 635 "perly.y" /* yacc.c:1646 */ + case 89: +#line 625 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 90: -#line 641 "perly.y" /* yacc.c:1646 */ + case 91: +#line 631 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 91: -#line 643 "perly.y" /* yacc.c:1646 */ + case 92: +#line 633 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; - case 92: -#line 645 "perly.y" /* yacc.c:1646 */ + case 93: +#line 635 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 93: -#line 650 "perly.y" /* yacc.c:1646 */ + case 94: +#line 640 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; - case 94: -#line 652 "perly.y" /* yacc.c:1646 */ + case 95: +#line 642 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 95: -#line 663 "perly.y" /* yacc.c:1646 */ + case 96: +#line 653 "perly.y" /* yacc.c:1646 */ { parser->in_my = 0; (yyval.opval) = NULL; } break; - case 96: -#line 665 "perly.y" /* yacc.c:1646 */ + case 97: +#line 655 "perly.y" /* yacc.c:1646 */ { parser->in_my = 0; (yyval.opval) = (ps[0].val.opval); } break; - case 97: -#line 670 "perly.y" /* yacc.c:1646 */ + case 98: +#line 660 "perly.y" /* yacc.c:1646 */ { (yyval.ival) = '@'; } break; - case 98: -#line 672 "perly.y" /* yacc.c:1646 */ + case 99: +#line 662 "perly.y" /* yacc.c:1646 */ { (yyval.ival) = '%'; } break; - case 99: -#line 676 "perly.y" /* yacc.c:1646 */ + case 100: +#line 666 "perly.y" /* yacc.c:1646 */ { I32 sigil = (ps[-2].val.ival); OP *var = (ps[-1].val.opval); @@ -855,26 +849,26 @@ case 2: break; - case 100: -#line 695 "perly.y" /* yacc.c:1646 */ + case 101: +#line 685 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 101: -#line 697 "perly.y" /* yacc.c:1646 */ + case 102: +#line 687 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newOP(OP_NULL, 0); } break; - case 102: -#line 699 "perly.y" /* yacc.c:1646 */ + case 103: +#line 689 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; - case 103: -#line 705 "perly.y" /* yacc.c:1646 */ + case 104: +#line 695 "perly.y" /* yacc.c:1646 */ { OP *var = (ps[-1].val.opval); OP *defexpr = (ps[0].val.opval); @@ -938,52 +932,52 @@ case 2: break; - case 104: -#line 770 "perly.y" /* yacc.c:1646 */ + case 105: +#line 760 "perly.y" /* yacc.c:1646 */ { parser->in_my = KEY_sigvar; (yyval.opval) = (ps[0].val.opval); } break; - case 105: -#line 772 "perly.y" /* yacc.c:1646 */ + case 106: +#line 762 "perly.y" /* yacc.c:1646 */ { parser->in_my = KEY_sigvar; (yyval.opval) = (ps[0].val.opval); } break; - case 106: -#line 778 "perly.y" /* yacc.c:1646 */ + case 107: +#line 768 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[-1].val.opval); } break; - case 107: -#line 780 "perly.y" /* yacc.c:1646 */ + case 108: +#line 770 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_append_list(OP_LINESEQ, (ps[-2].val.opval), (ps[0].val.opval)); } break; - case 108: -#line 784 "perly.y" /* yacc.c:1646 */ + case 109: +#line 774 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; - case 109: -#line 789 "perly.y" /* yacc.c:1646 */ + case 110: +#line 779 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 110: -#line 791 "perly.y" /* yacc.c:1646 */ + case 111: +#line 781 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; - case 111: -#line 795 "perly.y" /* yacc.c:1646 */ + case 112: +#line 785 "perly.y" /* yacc.c:1646 */ { ENTER; SAVEIV(parser->sig_elems); @@ -997,8 +991,8 @@ case 2: break; - case 112: -#line 807 "perly.y" /* yacc.c:1646 */ + case 113: +#line 797 "perly.y" /* yacc.c:1646 */ { OP *sigops = (ps[-1].val.opval); UNOP_AUX_item *aux; @@ -1036,38 +1030,38 @@ case 2: break; - case 114: -#line 847 "perly.y" /* yacc.c:1646 */ + case 115: +#line 837 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 115: -#line 852 "perly.y" /* yacc.c:1646 */ + case 116: +#line 842 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[-2].val.opval), (ps[0].val.opval)); } break; - case 116: -#line 854 "perly.y" /* yacc.c:1646 */ + case 117: +#line 844 "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 856 "perly.y" /* yacc.c:1646 */ + case 118: +#line 846 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOGOP(OP_DOR, 0, (ps[-2].val.opval), (ps[0].val.opval)); } break; - case 119: -#line 862 "perly.y" /* yacc.c:1646 */ + case 120: +#line 852 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[-1].val.opval); } break; - case 120: -#line 864 "perly.y" /* yacc.c:1646 */ + case 121: +#line 854 "perly.y" /* yacc.c:1646 */ { OP* term = (ps[0].val.opval); (yyval.opval) = op_append_elem(OP_LIST, (ps[-2].val.opval), term); @@ -1075,24 +1069,24 @@ case 2: break; - case 122: -#line 873 "perly.y" /* yacc.c:1646 */ + case 123: +#line 863 "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)) ); } break; - case 123: -#line 877 "perly.y" /* yacc.c:1646 */ + case 124: +#line 867 "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)) ); } break; - case 124: -#line 881 "perly.y" /* yacc.c:1646 */ + case 125: +#line 871 "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)), @@ -1101,8 +1095,8 @@ case 2: break; - case 125: -#line 887 "perly.y" /* yacc.c:1646 */ + case 126: +#line 877 "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)))); @@ -1110,8 +1104,8 @@ case 2: break; - case 126: -#line 892 "perly.y" /* yacc.c:1646 */ + case 127: +#line 882 "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)), @@ -1120,8 +1114,8 @@ case 2: break; - case 127: -#line 898 "perly.y" /* yacc.c:1646 */ + case 128: +#line 888 "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)), @@ -1130,27 +1124,27 @@ case 2: break; - case 128: -#line 904 "perly.y" /* yacc.c:1646 */ + case 129: +#line 894 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_convert_list((ps[-1].val.ival), 0, (ps[0].val.opval)); } break; - case 129: -#line 906 "perly.y" /* yacc.c:1646 */ + case 130: +#line 896 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_convert_list((ps[-3].val.ival), 0, (ps[-1].val.opval)); } break; - case 130: -#line 908 "perly.y" /* yacc.c:1646 */ + case 131: +#line 898 "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 911 "perly.y" /* yacc.c:1646 */ + case 132: +#line 901 "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))); @@ -1158,21 +1152,21 @@ case 2: break; - case 134: -#line 926 "perly.y" /* yacc.c:1646 */ + case 135: +#line 916 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP(OP_GELEM, 0, (ps[-4].val.opval), scalar((ps[-2].val.opval))); } break; - case 135: -#line 928 "perly.y" /* yacc.c:1646 */ + case 136: +#line 918 "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 931 "perly.y" /* yacc.c:1646 */ + case 137: +#line 921 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP(OP_AELEM, 0, ref(newAVREF((ps[-4].val.opval)),OP_RV2AV), scalar((ps[-1].val.opval))); @@ -1180,8 +1174,8 @@ case 2: break; - case 137: -#line 936 "perly.y" /* yacc.c:1646 */ + case 138: +#line 926 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP(OP_AELEM, 0, ref(newAVREF((ps[-3].val.opval)),OP_RV2AV), scalar((ps[-1].val.opval))); @@ -1189,91 +1183,91 @@ case 2: break; - case 138: -#line 941 "perly.y" /* yacc.c:1646 */ + case 139: +#line 931 "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 944 "perly.y" /* yacc.c:1646 */ + case 140: +#line 934 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP(OP_HELEM, 0, ref(newHVREF((ps[-5].val.opval)),OP_RV2HV), jmaybe((ps[-2].val.opval))); } break; - case 140: -#line 948 "perly.y" /* yacc.c:1646 */ + case 141: +#line 938 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newBINOP(OP_HELEM, 0, ref(newHVREF((ps[-4].val.opval)),OP_RV2HV), jmaybe((ps[-2].val.opval))); } break; - case 141: -#line 952 "perly.y" /* yacc.c:1646 */ + case 142: +#line 942 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, newCVREF(0, scalar((ps[-3].val.opval)))); } break; - case 142: -#line 955 "perly.y" /* yacc.c:1646 */ + case 143: +#line 945 "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))))); } break; - case 143: -#line 960 "perly.y" /* yacc.c:1646 */ + case 144: +#line 950 "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))))); } break; - case 144: -#line 964 "perly.y" /* yacc.c:1646 */ + case 145: +#line 954 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, newCVREF(0, scalar((ps[-2].val.opval)))); } break; - case 145: -#line 967 "perly.y" /* yacc.c:1646 */ + case 146: +#line 957 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newSLICEOP(0, (ps[-1].val.opval), (ps[-4].val.opval)); } break; - case 146: -#line 969 "perly.y" /* yacc.c:1646 */ + case 147: +#line 959 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newSLICEOP(0, (ps[-1].val.opval), (ps[-3].val.opval)); } break; - case 147: -#line 971 "perly.y" /* yacc.c:1646 */ + case 148: +#line 961 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newSLICEOP(0, (ps[-1].val.opval), NULL); } break; - case 148: -#line 976 "perly.y" /* yacc.c:1646 */ + case 149: +#line 966 "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 978 "perly.y" /* yacc.c:1646 */ + case 150: +#line 968 "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 980 "perly.y" /* yacc.c:1646 */ + case 151: +#line 970 "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))); @@ -1281,112 +1275,112 @@ case 2: break; - case 151: -#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 987 "perly.y" /* yacc.c:1646 */ +#line 975 "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 989 "perly.y" /* yacc.c:1646 */ +#line 977 "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 991 "perly.y" /* yacc.c:1646 */ +#line 979 "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 993 "perly.y" /* yacc.c:1646 */ +#line 981 "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 995 "perly.y" /* yacc.c:1646 */ +#line 983 "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 997 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = newRANGE((ps[-1].val.ival), scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); } +#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 158: -#line 999 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[-2].val.opval), (ps[0].val.opval)); } +#line 987 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = newRANGE((ps[-1].val.ival), scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); } break; case 159: -#line 1001 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = newLOGOP(OP_OR, 0, (ps[-2].val.opval), (ps[0].val.opval)); } +#line 989 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[-2].val.opval), (ps[0].val.opval)); } break; case 160: -#line 1003 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = newLOGOP(OP_DOR, 0, (ps[-2].val.opval), (ps[0].val.opval)); } +#line 991 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = newLOGOP(OP_OR, 0, (ps[-2].val.opval), (ps[0].val.opval)); } break; case 161: -#line 1005 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = bind_match((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); } +#line 993 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = newLOGOP(OP_DOR, 0, (ps[-2].val.opval), (ps[0].val.opval)); } break; case 162: -#line 1010 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = newUNOP(OP_NEGATE, 0, scalar((ps[0].val.opval))); } +#line 995 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = bind_match((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); } break; case 163: -#line 1012 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = (ps[0].val.opval); } +#line 1000 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = newUNOP(OP_NEGATE, 0, scalar((ps[0].val.opval))); } break; case 164: -#line 1015 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = newUNOP(OP_NOT, 0, scalar((ps[0].val.opval))); } +#line 1002 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = (ps[0].val.opval); } break; case 165: -#line 1017 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, scalar((ps[0].val.opval))); } +#line 1005 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = newUNOP(OP_NOT, 0, scalar((ps[0].val.opval))); } break; case 166: -#line 1019 "perly.y" /* yacc.c:1646 */ +#line 1007 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, scalar((ps[0].val.opval))); } + + break; + + case 167: +#line 1009 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_POSTINC, 0, op_lvalue(scalar((ps[-1].val.opval)), OP_POSTINC)); } break; - case 167: -#line 1022 "perly.y" /* yacc.c:1646 */ + case 168: +#line 1012 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_POSTDEC, 0, op_lvalue(scalar((ps[-1].val.opval)), OP_POSTDEC));} break; - case 168: -#line 1025 "perly.y" /* yacc.c:1646 */ + case 169: +#line 1015 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_convert_list(OP_JOIN, 0, op_append_elem( OP_LIST, @@ -1400,53 +1394,53 @@ case 2: break; - case 169: -#line 1036 "perly.y" /* yacc.c:1646 */ + case 170: +#line 1026 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_PREINC, 0, op_lvalue(scalar((ps[0].val.opval)), OP_PREINC)); } break; - case 170: -#line 1039 "perly.y" /* yacc.c:1646 */ + case 171: +#line 1029 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_PREDEC, 0, op_lvalue(scalar((ps[0].val.opval)), OP_PREDEC)); } break; - case 171: -#line 1046 "perly.y" /* yacc.c:1646 */ + case 172: +#line 1036 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newANONLIST((ps[-1].val.opval)); } break; - case 172: -#line 1048 "perly.y" /* yacc.c:1646 */ + case 173: +#line 1038 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newANONLIST(NULL);} break; - case 173: -#line 1050 "perly.y" /* yacc.c:1646 */ + case 174: +#line 1040 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newANONHASH((ps[-2].val.opval)); } break; - case 174: -#line 1052 "perly.y" /* yacc.c:1646 */ + case 175: +#line 1042 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newANONHASH(NULL); } break; - case 175: -#line 1054 "perly.y" /* yacc.c:1646 */ + case 176: +#line 1044 "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 1057 "perly.y" /* yacc.c:1646 */ + case 177: +#line 1047 "perly.y" /* yacc.c:1646 */ { OP *body; if (parser->copline > (line_t)(ps[-2].val.ival)) @@ -1459,104 +1453,104 @@ case 2: break; - case 177: -#line 1071 "perly.y" /* yacc.c:1646 */ + case 178: +#line 1061 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = dofile((ps[0].val.opval), (ps[-1].val.ival));} break; - case 178: -#line 1073 "perly.y" /* yacc.c:1646 */ + case 179: +#line 1063 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_NULL, OPf_SPECIAL, op_scope((ps[0].val.opval)));} break; - case 183: -#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 1083 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = newUNOP(OP_REFGEN, 0, (ps[0].val.opval)); } +#line 1071 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = newCONDOP(0, (ps[-4].val.opval), (ps[-2].val.opval), (ps[0].val.opval)); } break; case 185: -#line 1085 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = newUNOP(OP_REFGEN, 0, localize((ps[0].val.opval),1)); } +#line 1073 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = newUNOP(OP_REFGEN, 0, (ps[0].val.opval)); } break; case 186: -#line 1087 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = (ps[0].val.opval); } +#line 1075 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = newUNOP(OP_REFGEN, 0, localize((ps[0].val.opval),1)); } break; case 187: -#line 1089 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = localize((ps[0].val.opval),0); } +#line 1077 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = (ps[0].val.opval); } break; case 188: -#line 1091 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = sawparens((ps[-1].val.opval)); } +#line 1079 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = localize((ps[0].val.opval),0); } break; case 189: -#line 1093 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = (ps[0].val.opval); } +#line 1081 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = sawparens((ps[-1].val.opval)); } break; case 190: -#line 1095 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = sawparens(newNULLLIST()); } +#line 1083 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = (ps[0].val.opval); } break; case 191: -#line 1097 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = (ps[0].val.opval); } +#line 1085 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = sawparens(newNULLLIST()); } break; case 192: -#line 1099 "perly.y" /* yacc.c:1646 */ +#line 1087 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 193: -#line 1101 "perly.y" /* yacc.c:1646 */ +#line 1089 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 194: -#line 1103 "perly.y" /* yacc.c:1646 */ +#line 1091 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; case 195: -#line 1105 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = newUNOP(OP_AV2ARYLEN, 0, ref((ps[0].val.opval), OP_AV2ARYLEN));} +#line 1093 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = (ps[0].val.opval); } break; case 196: -#line 1107 "perly.y" /* yacc.c:1646 */ - { (yyval.opval) = (ps[0].val.opval); } +#line 1095 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = newUNOP(OP_AV2ARYLEN, 0, ref((ps[0].val.opval), OP_AV2ARYLEN));} break; case 197: -#line 1109 "perly.y" /* yacc.c:1646 */ +#line 1097 "perly.y" /* yacc.c:1646 */ + { (yyval.opval) = (ps[0].val.opval); } + + break; + + case 198: +#line 1099 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_prepend_elem(OP_ASLICE, newOP(OP_PUSHMARK, 0), newLISTOP(OP_ASLICE, 0, @@ -1569,8 +1563,8 @@ case 2: break; - case 198: -#line 1119 "perly.y" /* yacc.c:1646 */ + case 199: +#line 1109 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_prepend_elem(OP_KVASLICE, newOP(OP_PUSHMARK, 0), newLISTOP(OP_KVASLICE, 0, @@ -1583,8 +1577,8 @@ case 2: break; - case 199: -#line 1129 "perly.y" /* yacc.c:1646 */ + case 200: +#line 1119 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_prepend_elem(OP_HSLICE, newOP(OP_PUSHMARK, 0), newLISTOP(OP_HSLICE, 0, @@ -1597,8 +1591,8 @@ case 2: break; - case 200: -#line 1139 "perly.y" /* yacc.c:1646 */ + case 201: +#line 1129 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_prepend_elem(OP_KVHSLICE, newOP(OP_PUSHMARK, 0), newLISTOP(OP_KVHSLICE, 0, @@ -1611,27 +1605,27 @@ case 2: break; - case 201: -#line 1149 "perly.y" /* yacc.c:1646 */ + case 202: +#line 1139 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; - case 202: -#line 1151 "perly.y" /* yacc.c:1646 */ + case 203: +#line 1141 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, 0, scalar((ps[0].val.opval))); } break; - case 203: -#line 1153 "perly.y" /* yacc.c:1646 */ + case 204: +#line 1143 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar((ps[-2].val.opval))); } break; - case 204: -#line 1156 "perly.y" /* yacc.c:1646 */ + case 205: +#line 1146 "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)))); @@ -1639,153 +1633,153 @@ case 2: break; - case 205: -#line 1161 "perly.y" /* yacc.c:1646 */ + case 206: +#line 1151 "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 206: -#line 1165 "perly.y" /* yacc.c:1646 */ + case 207: +#line 1155 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newSVREF((ps[-3].val.opval)); } break; - case 207: -#line 1167 "perly.y" /* yacc.c:1646 */ + case 208: +#line 1157 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newAVREF((ps[-3].val.opval)); } break; - case 208: -#line 1169 "perly.y" /* yacc.c:1646 */ + case 209: +#line 1159 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newHVREF((ps[-3].val.opval)); } break; - case 209: -#line 1171 "perly.y" /* yacc.c:1646 */ + case 210: +#line 1161 "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 1174 "perly.y" /* yacc.c:1646 */ + case 211: +#line 1164 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newGVREF(0,(ps[-3].val.opval)); } break; - case 211: -#line 1176 "perly.y" /* yacc.c:1646 */ + case 212: +#line 1166 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newOP((ps[0].val.ival), OPf_SPECIAL); PL_hints |= HINT_BLOCK_SCOPE; } break; - case 212: -#line 1179 "perly.y" /* yacc.c:1646 */ + case 213: +#line 1169 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newLOOPEX((ps[-1].val.ival),(ps[0].val.opval)); } break; - case 213: -#line 1181 "perly.y" /* yacc.c:1646 */ + case 214: +#line 1171 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_NOT, 0, scalar((ps[0].val.opval))); } break; - case 214: -#line 1183 "perly.y" /* yacc.c:1646 */ + case 215: +#line 1173 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newOP((ps[0].val.ival), 0); } break; - case 215: -#line 1185 "perly.y" /* yacc.c:1646 */ + case 216: +#line 1175 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, (ps[0].val.opval)); } break; - case 216: -#line 1187 "perly.y" /* yacc.c:1646 */ + case 217: +#line 1177 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, (ps[0].val.opval)); } break; - case 217: -#line 1189 "perly.y" /* yacc.c:1646 */ + case 218: +#line 1179 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newOP(OP_REQUIRE, (ps[0].val.ival) ? OPf_SPECIAL : 0); } break; - case 218: -#line 1191 "perly.y" /* yacc.c:1646 */ + case 219: +#line 1181 "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 1193 "perly.y" /* yacc.c:1646 */ + case 220: +#line 1183 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar((ps[0].val.opval))); } break; - case 220: -#line 1195 "perly.y" /* yacc.c:1646 */ + case 221: +#line 1185 "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 1198 "perly.y" /* yacc.c:1646 */ + case 222: +#line 1188 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newOP((ps[0].val.ival), 0); } break; - case 222: -#line 1200 "perly.y" /* yacc.c:1646 */ + case 223: +#line 1190 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newOP((ps[-2].val.ival), 0);} break; - case 223: -#line 1202 "perly.y" /* yacc.c:1646 */ + case 224: +#line 1192 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; - case 224: -#line 1204 "perly.y" /* yacc.c:1646 */ + case 225: +#line 1194 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[-2].val.opval); } break; - case 225: -#line 1206 "perly.y" /* yacc.c:1646 */ + case 226: +#line 1196 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar((ps[0].val.opval))); } break; - case 226: -#line 1208 "perly.y" /* yacc.c:1646 */ + case 227: +#line 1198 "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); } break; - case 227: -#line 1212 "perly.y" /* yacc.c:1646 */ + case 228: +#line 1202 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newUNOP((ps[-3].val.ival), 0, (ps[-1].val.opval)); } break; - case 228: -#line 1214 "perly.y" /* yacc.c:1646 */ + case 229: +#line 1204 "perly.y" /* yacc.c:1646 */ { if ( (ps[0].val.opval)->op_type != OP_TRANS && (ps[0].val.opval)->op_type != OP_TRANSR @@ -1799,186 +1793,186 @@ case 2: break; - case 229: -#line 1225 "perly.y" /* yacc.c:1646 */ + case 230: +#line 1215 "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 1233 "perly.y" /* yacc.c:1646 */ + case 234: +#line 1223 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = my_attrs((ps[-1].val.opval),(ps[0].val.opval)); } break; - case 234: -#line 1235 "perly.y" /* yacc.c:1646 */ + case 235: +#line 1225 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = localize((ps[0].val.opval),1); } break; - case 235: -#line 1237 "perly.y" /* yacc.c:1646 */ + case 236: +#line 1227 "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 1242 "perly.y" /* yacc.c:1646 */ + case 237: +#line 1232 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = sawparens((ps[-1].val.opval)); } break; - case 237: -#line 1244 "perly.y" /* yacc.c:1646 */ + case 238: +#line 1234 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = sawparens(newNULLLIST()); } break; - case 238: -#line 1247 "perly.y" /* yacc.c:1646 */ + case 239: +#line 1237 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; - case 239: -#line 1249 "perly.y" /* yacc.c:1646 */ + case 240: +#line 1239 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; - case 240: -#line 1251 "perly.y" /* yacc.c:1646 */ + case 241: +#line 1241 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; - case 241: -#line 1256 "perly.y" /* yacc.c:1646 */ + case 242: +#line 1246 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 242: -#line 1258 "perly.y" /* yacc.c:1646 */ + case 243: +#line 1248 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; - case 243: -#line 1262 "perly.y" /* yacc.c:1646 */ + case 244: +#line 1252 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 244: -#line 1264 "perly.y" /* yacc.c:1646 */ + case 245: +#line 1254 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; - case 245: -#line 1268 "perly.y" /* yacc.c:1646 */ + case 246: +#line 1258 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = NULL; } break; - case 246: -#line 1270 "perly.y" /* yacc.c:1646 */ + case 247: +#line 1260 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; - case 247: -#line 1276 "perly.y" /* yacc.c:1646 */ + case 248: +#line 1266 "perly.y" /* yacc.c:1646 */ { parser->in_my = 0; (yyval.opval) = my((ps[0].val.opval)); } break; - case 255: -#line 1293 "perly.y" /* yacc.c:1646 */ + case 256: +#line 1283 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newCVREF((ps[-1].val.ival),(ps[0].val.opval)); } break; - case 256: -#line 1297 "perly.y" /* yacc.c:1646 */ + case 257: +#line 1287 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newSVREF((ps[0].val.opval)); } break; - case 257: -#line 1301 "perly.y" /* yacc.c:1646 */ + case 258: +#line 1291 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newAVREF((ps[0].val.opval)); if ((yyval.opval)) (yyval.opval)->op_private |= (ps[-1].val.ival); } break; - case 258: -#line 1307 "perly.y" /* yacc.c:1646 */ + case 259: +#line 1297 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newHVREF((ps[0].val.opval)); if ((yyval.opval)) (yyval.opval)->op_private |= (ps[-1].val.ival); } break; - case 259: -#line 1313 "perly.y" /* yacc.c:1646 */ + case 260: +#line 1303 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newAVREF((ps[0].val.opval)); } break; - case 260: -#line 1315 "perly.y" /* yacc.c:1646 */ + case 261: +#line 1305 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newAVREF((ps[-3].val.opval)); } break; - case 261: -#line 1319 "perly.y" /* yacc.c:1646 */ + case 262: +#line 1309 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newGVREF(0,(ps[0].val.opval)); } break; - case 263: -#line 1324 "perly.y" /* yacc.c:1646 */ + case 264: +#line 1314 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newAVREF((ps[-2].val.opval)); } break; - case 265: -#line 1329 "perly.y" /* yacc.c:1646 */ + case 266: +#line 1319 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newHVREF((ps[-2].val.opval)); } break; - case 267: -#line 1334 "perly.y" /* yacc.c:1646 */ + case 268: +#line 1324 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = newGVREF(0,(ps[-2].val.opval)); } break; - case 268: -#line 1339 "perly.y" /* yacc.c:1646 */ + case 269: +#line 1329 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = scalar((ps[0].val.opval)); } break; - case 269: -#line 1341 "perly.y" /* yacc.c:1646 */ + case 270: +#line 1331 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = scalar((ps[0].val.opval)); } break; - case 270: -#line 1343 "perly.y" /* yacc.c:1646 */ + case 271: +#line 1333 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = op_scope((ps[0].val.opval)); } break; - case 271: -#line 1346 "perly.y" /* yacc.c:1646 */ + case 272: +#line 1336 "perly.y" /* yacc.c:1646 */ { (yyval.opval) = (ps[0].val.opval); } break; @@ -1989,6 +1983,6 @@ case 2: /* Generated from: - * 1d0c087affbf85a8f1482eb4d34eefd435666c6d9e1cb4d7f9d1aeb62b37e907 perly.y + * 78f9e1daf948a161b43e7457943b7d91cada7c92c8b941a1c1dbbc23c2c10aa8 perly.y * b6fae5748f9bef6db4740aa5e122b84ac5181852d42474d0ecad621fa4253306 regen_perly.pl * ex: set ro: */ @@ -86,51 +86,52 @@ extern int yydebug; CONTINUE = 289, FOR = 290, GIVEN = 291, - WHERESO = 292, - LOOPEX = 293, - DOTDOT = 294, - YADAYADA = 295, - FUNC0 = 296, - FUNC1 = 297, - FUNC = 298, - UNIOP = 299, - LSTOP = 300, - RELOP = 301, - EQOP = 302, - MULOP = 303, - ADDOP = 304, - DOLSHARP = 305, - DO = 306, - HASHBRACK = 307, - NOAMP = 308, - LOCAL = 309, - MY = 310, - REQUIRE = 311, - COLONATTR = 312, - FORMLBRACK = 313, - FORMRBRACK = 314, - PREC_LOW = 315, - OROP = 316, - DOROP = 317, - ANDOP = 318, - NOTOP = 319, - ASSIGNOP = 320, - OROR = 321, - DORDOR = 322, - ANDAND = 323, - BITOROP = 324, - BITANDOP = 325, - SHIFTOP = 326, - MATCHOP = 327, - UMINUS = 328, - REFGEN = 329, - POWOP = 330, - PREINC = 331, - PREDEC = 332, - POSTINC = 333, - POSTDEC = 334, - POSTJOIN = 335, - ARROW = 336 + WHEN = 292, + DEFAULT = 293, + LOOPEX = 294, + DOTDOT = 295, + YADAYADA = 296, + FUNC0 = 297, + FUNC1 = 298, + FUNC = 299, + UNIOP = 300, + LSTOP = 301, + RELOP = 302, + EQOP = 303, + MULOP = 304, + ADDOP = 305, + DOLSHARP = 306, + DO = 307, + HASHBRACK = 308, + NOAMP = 309, + LOCAL = 310, + MY = 311, + REQUIRE = 312, + COLONATTR = 313, + FORMLBRACK = 314, + FORMRBRACK = 315, + PREC_LOW = 316, + OROP = 317, + DOROP = 318, + ANDOP = 319, + NOTOP = 320, + ASSIGNOP = 321, + OROR = 322, + DORDOR = 323, + ANDAND = 324, + BITOROP = 325, + BITANDOP = 326, + SHIFTOP = 327, + MATCHOP = 328, + UMINUS = 329, + REFGEN = 330, + POWOP = 331, + PREINC = 332, + PREDEC = 333, + POSTINC = 334, + POSTDEC = 335, + POSTJOIN = 336, + ARROW = 337 }; #endif @@ -180,6 +181,6 @@ int yyparse (void); /* Generated from: - * 1d0c087affbf85a8f1482eb4d34eefd435666c6d9e1cb4d7f9d1aeb62b37e907 perly.y + * 78f9e1daf948a161b43e7457943b7d91cada7c92c8b941a1c1dbbc23c2c10aa8 perly.y * b6fae5748f9bef6db4740aa5e122b84ac5181852d42474d0ecad621fa4253306 regen_perly.pl * ex: set ro: */ @@ -6,21 +6,21 @@ #define YYFINAL 14 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 3058 +#define YYLAST 3096 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 104 +#define YYNTOKENS 105 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 86 /* YYNRULES -- Number of rules. */ -#define YYNRULES 271 +#define YYNRULES 272 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 538 +#define YYNSTATES 540 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 336 +#define YYMAXUTOK 337 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -32,16 +32,16 @@ static const yytype_uint8 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 87, 2, 2, 101, 16, 17, 2, - 99, 98, 102, 14, 76, 13, 19, 103, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 79, 100, - 2, 18, 2, 78, 15, 2, 2, 2, 2, 2, + 2, 2, 2, 88, 2, 2, 102, 16, 17, 2, + 100, 99, 103, 14, 77, 13, 19, 104, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 80, 101, + 2, 18, 2, 79, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 11, 2, 12, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 9, 2, 10, 88, 2, 2, 2, + 2, 2, 2, 9, 2, 10, 89, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -61,8 +61,8 @@ static const yytype_uint8 yytranslate[] = 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 77, 80, 81, 82, 83, 84, 85, 86, 89, 90, - 91, 92, 93, 94, 95, 96, 97 + 76, 78, 81, 82, 83, 84, 85, 86, 87, 90, + 91, 92, 93, 94, 95, 96, 97, 98 }; #if YYDEBUG @@ -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, - 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 + 383, 385, 392, 400, 402, 399, 419, 424, 431, 430, + 445, 453, 459, 466, 465, 480, 484, 489, 497, 515, + 516, 521, 523, 525, 527, 529, 531, 533, 536, 542, + 543, 548, 559, 560, 566, 572, 573, 578, 581, 585, + 590, 594, 598, 599, 603, 609, 614, 619, 620, 625, + 626, 631, 632, 634, 639, 641, 653, 654, 659, 661, + 665, 685, 686, 688, 694, 759, 761, 767, 769, 773, + 779, 780, 785, 784, 836, 837, 841, 843, 845, 847, + 851, 853, 858, 862, 866, 870, 876, 881, 887, 893, + 895, 898, 897, 908, 909, 913, 917, 920, 925, 930, + 933, 937, 941, 944, 949, 953, 956, 958, 960, 965, + 967, 969, 974, 976, 978, 980, 982, 984, 986, 988, + 990, 992, 994, 999, 1001, 1004, 1006, 1008, 1011, 1014, + 1025, 1028, 1035, 1037, 1039, 1041, 1043, 1046, 1060, 1062, + 1066, 1067, 1068, 1069, 1070, 1072, 1074, 1076, 1078, 1080, + 1082, 1084, 1086, 1088, 1090, 1092, 1094, 1096, 1098, 1108, + 1118, 1128, 1138, 1140, 1142, 1145, 1150, 1154, 1156, 1158, + 1160, 1163, 1165, 1168, 1170, 1172, 1174, 1176, 1178, 1180, + 1182, 1184, 1187, 1189, 1191, 1193, 1195, 1197, 1201, 1204, + 1203, 1216, 1217, 1218, 1222, 1224, 1226, 1231, 1233, 1236, + 1238, 1240, 1245, 1247, 1252, 1253, 1258, 1259, 1265, 1269, + 1270, 1271, 1274, 1275, 1278, 1279, 1282, 1286, 1290, 1296, + 1302, 1304, 1308, 1312, 1313, 1317, 1318, 1322, 1323, 1328, + 1330, 1332, 1335 }; #endif @@ -111,9 +111,9 @@ static const char *const yytname[] = "METHOD", "FUNCMETH", "THING", "PMFUNC", "PRIVATEREF", "QWLIST", "FUNC0OP", "FUNC0SUB", "UNIOPSUB", "LSTOPSUB", "PLUGEXPR", "PLUGSTMT", "LABEL", "FORMAT", "SUB", "ANONSUB", "PACKAGE", "USE", "WHILE", "UNTIL", - "IF", "UNLESS", "ELSE", "ELSIF", "CONTINUE", "FOR", "GIVEN", "WHERESO", - "LOOPEX", "DOTDOT", "YADAYADA", "FUNC0", "FUNC1", "FUNC", "UNIOP", - "LSTOP", "RELOP", "EQOP", "MULOP", "ADDOP", "DOLSHARP", "DO", + "IF", "UNLESS", "ELSE", "ELSIF", "CONTINUE", "FOR", "GIVEN", "WHEN", + "DEFAULT", "LOOPEX", "DOTDOT", "YADAYADA", "FUNC0", "FUNC1", "FUNC", + "UNIOP", "LSTOP", "RELOP", "EQOP", "MULOP", "ADDOP", "DOLSHARP", "DO", "HASHBRACK", "NOAMP", "LOCAL", "MY", "REQUIRE", "COLONATTR", "FORMLBRACK", "FORMRBRACK", "PREC_LOW", "OROP", "DOROP", "ANDOP", "NOTOP", "','", "ASSIGNOP", "'?'", "':'", "OROR", "DORDOR", "ANDAND", @@ -149,81 +149,81 @@ static const yytype_uint16 yytoknum[] = 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 315, 316, 317, 318, 319, 44, 320, 63, 58, - 321, 322, 323, 324, 325, 326, 327, 33, 126, 328, - 329, 330, 331, 332, 333, 334, 335, 336, 41, 40, - 59, 36, 42, 47 + 314, 315, 316, 317, 318, 319, 320, 44, 321, 63, + 58, 322, 323, 324, 325, 326, 327, 328, 33, 126, + 329, 330, 331, 332, 333, 334, 335, 336, 337, 41, + 40, 59, 36, 42, 47 }; # endif -#define YYPACT_NINF -437 +#define YYPACT_NINF -455 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-437))) + (!!((Yystate) == (-455))) -#define YYTABLE_NINF -267 +#define YYTABLE_NINF -268 #define yytable_value_is_error(Yytable_value) \ - (!!((Yytable_value) == (-267))) + (!!((Yytable_value) == (-268))) /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int16 yypact[] = { - 738, -437, -437, -437, -437, -437, -437, 28, -437, 2801, - 35, 1507, 1413, -437, -437, -437, 1973, 2801, 2801, 70, - 70, 70, -437, 70, 70, -437, -437, 49, -21, -437, - 2801, -437, -437, -437, 2801, -10, -1, 18, 1881, 1787, - 70, 1881, 2065, 42, 2801, 135, 2801, 2801, 2801, 2801, - 2801, 2801, 2801, 2157, 70, 70, 34, 45, -437, 14, - -437, -437, -437, -437, 2919, -437, -437, 23, 152, 179, - 228, -437, 84, 235, 253, 116, -437, -437, -437, -437, - -437, 42, 106, -437, 37, 44, 50, 53, 150, 57, - 69, 29, -437, 132, -437, 46, 2155, 1413, -437, -437, - -437, 661, 755, -437, 102, 457, 457, -437, -437, -437, - -437, -437, -437, -437, 2801, 90, 118, 2801, 124, 518, - 35, 17, 2919, 125, 2249, 1787, -437, 518, 560, 45, - -437, 485, 2801, -437, -437, 518, 216, 169, -437, -437, - 2801, 518, 2893, 2341, 164, -437, -437, -437, 518, 45, - 457, 457, 457, 287, 287, 222, 187, -437, -437, 2801, - 2801, 2801, 2801, 2801, 2801, 2433, 2801, 2801, 2801, 2801, - 2801, 2801, 2801, 2801, 2801, 2801, 2801, 2801, 2801, 2801, - 2801, -437, -437, -437, 71, 2525, 2801, 2801, 2801, 2801, - 2801, 2801, 2801, -437, 227, -437, 245, -437, -437, -437, - -437, -437, 158, 149, -437, -437, 156, -437, -437, -437, - 35, -437, -437, 2801, 2801, 2801, 2801, 2801, 2801, -437, - -437, -437, -437, -437, 2801, 2801, 194, -437, -437, -437, - 176, 211, -437, -437, 288, 182, 2801, 45, -437, 274, - -437, 2617, 457, 164, 47, 59, 101, -437, 394, 263, - -437, 2801, 282, 221, 221, -437, 2919, 334, 209, -437, - 432, 1588, 443, 1956, 643, 248, 2919, 393, 1679, 1679, - 1772, 1866, 2048, 530, 457, 457, 2801, 2801, 201, 204, - 224, -437, 226, 2709, 32, 230, 197, -437, -437, 438, - 340, 217, 346, 251, 354, 280, 391, 849, -437, 300, - 212, 3, 299, 2801, 2801, 2801, 2801, -437, 232, -437, - -437, 236, -437, -437, -437, -437, 1600, -7, -437, 2801, - 2801, -437, 34, -437, 34, 34, 34, 34, 34, 240, - -22, -437, 2801, -437, 211, 324, 35, -437, -437, 449, - -437, 4, 524, -437, -437, -437, 293, 2801, 338, -437, - -437, 2801, 408, 305, -437, -437, -437, -437, -437, 575, - -437, -437, 2801, -437, 341, -437, 345, -437, 347, -437, - 360, -437, -437, -437, 327, -437, -437, -437, 351, 276, - 34, 289, 295, 34, 302, 273, -437, -437, -437, -437, - 303, 304, 357, -437, 2801, 318, 323, -437, 2801, 326, - -437, 30, 416, -437, -437, -437, 15, -437, 317, -437, - 2961, 423, -437, -437, 337, -437, -437, -437, -437, 342, - 211, 176, -437, 2801, -437, -437, 428, 428, 2801, 2801, - 428, -437, 339, 343, 428, 428, 34, -437, -437, -437, - 419, 419, -437, -437, -437, 369, 349, -437, -437, -437, - -437, 378, 5, 211, -437, 356, 428, 428, -437, 41, - 41, 359, 362, 132, 2801, 2801, 428, -437, -437, -437, - 372, 372, 30, -437, 943, -437, -437, -437, -437, 452, - 1037, -437, 132, 132, -437, 428, 384, -437, -437, 428, - 428, -437, 395, 400, 132, 2801, -437, -437, -437, -437, - 9, -437, -437, -437, -437, 1131, -437, 2801, 132, 132, - -437, 428, -437, 2919, 424, 480, -437, 1225, -437, 409, - -437, -437, -437, 132, -437, -437, -437, -437, 428, 1693, - -437, 1319, 41, 415, -437, -437, 428, -437 + 805, -455, -455, -455, -455, -455, -455, 18, -455, 2795, + 19, 1487, 1392, -455, -455, -455, 1958, 2795, 2795, 32, + 32, 32, -455, 32, 32, -455, -455, 35, -47, -455, + 2795, -455, -455, -455, 2795, -42, -28, -7, 1865, 1770, + 32, 1865, 2051, 58, 2795, 133, 2795, 2795, 2795, 2795, + 2795, 2795, 2795, 2144, 32, 32, 394, 8, -455, 5, + -455, -455, -455, -455, 2956, -455, -455, -3, 45, 51, + 59, -455, 85, 126, 269, 108, -455, -455, -455, -455, + -455, 58, 98, -455, 26, 44, 50, 57, 337, 62, + 75, 19, 31, -455, 82, -455, 88, 2049, 1392, -455, + -455, -455, 632, 727, -455, 33, 412, 412, -455, -455, + -455, -455, -455, -455, -455, 2795, 90, 115, 2795, 46, + 500, 19, 16, 2956, 117, 2237, 1770, -455, 500, 530, + 8, -455, 454, 2795, -455, -455, 500, 213, 184, -455, + -455, 2795, 500, 2888, 2330, 162, -455, -455, -455, 500, + 8, 412, 412, 412, 504, 504, 223, 214, -455, -455, + 2795, 2795, 2795, 2795, 2795, 2795, 2423, 2795, 2795, 2795, + 2795, 2795, 2795, 2795, 2795, 2795, 2795, 2795, 2795, 2795, + 2795, 2795, -455, -455, -455, 312, 2516, 2795, 2795, 2795, + 2795, 2795, 2795, 2795, -455, 221, -455, 224, -455, -455, + -455, -455, -455, 158, 72, -455, -455, 168, -455, -455, + -455, -455, 19, -455, -455, 2795, 2795, 2795, 2795, 2795, + 2795, -455, -455, -455, -455, -455, 2795, 2795, 49, -455, + -455, -455, 174, 212, -455, -455, 424, 166, 2795, 8, + -455, 265, -455, 2609, 412, 162, 167, 208, 239, -455, + 445, 267, -455, 2795, 282, 220, 220, -455, 2956, 292, + 55, -455, 545, 1569, 487, 1848, 709, 290, 2956, 2914, + 389, 389, 1660, 1755, 1941, 311, 412, 412, 2795, 2795, + 194, 200, 204, -455, 215, 2702, 12, 227, 209, -455, + -455, 602, 356, 67, 369, 78, 378, 165, 416, 822, + -455, 308, 235, -2, 319, 2795, 2795, 2795, 2795, -455, + 229, -455, -455, 240, -455, -455, -455, -455, 1581, 7, + -455, 2795, 2795, -455, 394, -455, 394, 394, 394, 394, + 394, 245, -60, -455, 2795, -455, 212, 329, 19, -455, + -455, 617, -455, 15, 630, -455, -455, -455, 179, 2795, + 335, -455, -455, 2795, 492, 196, -455, -455, -455, -455, + -455, 638, -455, -455, 2795, -455, 344, -455, 345, -455, + 347, -455, 349, -455, -455, -455, 350, -455, -455, -455, + 340, 277, 394, 284, 285, 394, 293, 281, -455, -455, + -455, -455, 300, 288, 322, -455, 2795, 301, 303, -455, + 2795, 314, -455, 9, 402, -455, -455, -455, 27, -455, + 231, -455, 2998, 406, -455, -455, 318, -455, -455, -455, + -455, 321, 212, 174, -455, 2795, -455, -455, 410, 410, + 2795, 2795, 410, -455, 320, 324, 410, 410, 394, -455, + -455, -455, 407, 407, -455, -455, -455, 358, 328, -455, + -455, -455, -455, 362, 2, 212, -455, 339, 410, 410, + -455, 38, 38, 346, 357, 82, 2795, 2795, 410, -455, + -455, -455, 360, 360, 9, -455, 917, -455, -455, -455, + -455, 427, 1012, -455, 82, 82, -455, 410, 355, -455, + -455, 410, 410, -455, 361, 359, 82, 2795, -455, -455, + -455, -455, -10, -455, -455, -455, -455, 1107, -455, 2795, + 82, 82, -455, 410, -455, 2956, 376, 440, -455, 1202, + -455, 379, -455, -455, -455, 82, -455, -455, -455, -455, + 410, 1675, -455, 1297, 38, 381, -455, -455, 410, -455 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -231,88 +231,88 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 0, 2, 4, 6, 8, 10, 12, 0, 16, 243, + 0, 2, 4, 6, 8, 10, 12, 0, 16, 244, 0, 0, 0, 19, 1, 19, 0, 0, 0, 0, - 0, 0, 230, 0, 0, 201, 228, 189, 223, 225, - 219, 84, 232, 84, 211, 221, 0, 0, 214, 241, - 0, 0, 0, 0, 0, 0, 217, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 244, 118, 231, 196, - 179, 180, 181, 182, 121, 186, 5, 202, 191, 194, - 193, 195, 192, 0, 0, 0, 16, 7, 60, 27, - 85, 0, 0, 83, 0, 0, 0, 0, 0, 0, - 0, 0, 56, 71, 9, 0, 61, 0, 11, 24, - 23, 0, 0, 172, 0, 162, 163, 268, 271, 270, - 269, 257, 258, 255, 241, 0, 0, 0, 0, 220, - 0, 88, 212, 0, 0, 243, 215, 216, 268, 242, - 128, 269, 0, 259, 178, 177, 0, 0, 86, 87, - 241, 187, 0, 0, 234, 238, 240, 239, 218, 213, - 164, 165, 184, 169, 170, 190, 0, 256, 261, 0, - 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 231, 0, 0, 202, 229, 190, 224, 226, + 220, 85, 233, 85, 212, 222, 0, 0, 215, 242, + 0, 0, 0, 0, 0, 0, 218, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 245, 119, 232, 197, + 180, 181, 182, 183, 122, 187, 5, 203, 192, 195, + 194, 196, 193, 0, 0, 0, 16, 7, 61, 27, + 86, 0, 0, 84, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 57, 72, 9, 0, 62, 0, 11, + 24, 23, 0, 0, 173, 0, 163, 164, 269, 272, + 271, 270, 258, 259, 256, 242, 0, 0, 0, 0, + 221, 0, 89, 213, 0, 0, 244, 216, 217, 269, + 243, 129, 270, 0, 260, 179, 178, 0, 0, 87, + 88, 242, 188, 0, 0, 235, 239, 241, 240, 219, + 214, 165, 166, 185, 170, 171, 191, 0, 257, 262, + 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 166, 167, 168, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 19, 82, 83, 0, 34, 16, 16, - 16, 16, 16, 0, 16, 16, 0, 16, 16, 55, - 0, 51, 54, 0, 0, 0, 0, 0, 0, 26, - 25, 20, 171, 126, 243, 0, 0, 224, 130, 89, - 0, 90, 222, 226, 0, 0, 0, 122, 174, 0, - 205, 0, 185, 0, 191, 194, 193, 237, 0, 94, - 233, 0, 188, 116, 117, 115, 120, 0, 0, 144, - 0, 157, 153, 154, 150, 151, 148, 0, 159, 160, - 158, 156, 155, 152, 161, 149, 0, 0, 263, 265, - 0, 132, 0, 0, 0, 267, 125, 133, 203, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, - 29, 0, 0, 76, 0, 0, 0, 253, 0, 254, - 251, 0, 252, 248, 249, 250, 0, 0, 16, 0, - 0, 72, 64, 65, 78, 62, 63, 66, 67, 0, - 245, 146, 241, 111, 90, 92, 0, 227, 129, 0, - 173, 190, 0, 235, 236, 93, 0, 0, 0, 137, - 143, 0, 0, 0, 207, 208, 209, 260, 141, 0, - 206, 210, 243, 204, 0, 135, 0, 197, 0, 198, - 0, 14, 16, 28, 88, 16, 16, 33, 0, 0, - 77, 0, 0, 79, 0, 0, 247, 16, 75, 80, - 0, 0, 61, 47, 0, 0, 0, 127, 0, 0, - 131, 109, 0, 91, 175, 123, 188, 147, 0, 140, - 183, 0, 136, 142, 0, 138, 199, 200, 134, 0, - 90, 0, 52, 241, 73, 73, 0, 0, 0, 0, - 0, 42, 0, 0, 0, 0, 246, 229, 97, 98, - 95, 95, 105, 104, 108, 110, 0, 19, 145, 139, - 124, 0, 0, 90, 19, 0, 0, 0, 18, 68, - 68, 0, 0, 71, 76, 0, 0, 38, 39, 96, - 100, 100, 106, 112, 0, 21, 114, 113, 30, 0, - 0, 35, 71, 71, 19, 0, 0, 36, 37, 0, - 0, 50, 0, 0, 71, 101, 103, 99, 107, 176, - 0, 19, 53, 40, 41, 0, 69, 0, 71, 71, - 43, 0, 46, 102, 58, 0, 22, 0, 17, 0, - 45, 49, 73, 71, 19, 57, 15, 32, 0, 0, - 48, 0, 68, 0, 59, 70, 0, 44 + 0, 0, 167, 168, 169, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 19, 83, 84, 0, 34, 16, + 16, 16, 16, 16, 0, 16, 16, 0, 16, 16, + 40, 56, 0, 52, 55, 0, 0, 0, 0, 0, + 0, 26, 25, 20, 172, 127, 244, 0, 0, 225, + 131, 90, 0, 91, 223, 227, 0, 0, 0, 123, + 175, 0, 206, 0, 186, 0, 192, 195, 194, 238, + 0, 95, 234, 0, 189, 117, 118, 116, 121, 0, + 0, 145, 0, 158, 154, 155, 151, 152, 149, 0, + 160, 161, 159, 157, 156, 153, 162, 150, 0, 0, + 264, 266, 0, 133, 0, 0, 0, 268, 126, 134, + 204, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 82, 0, 29, 0, 0, 77, 0, 0, 0, 254, + 0, 255, 252, 0, 253, 249, 250, 251, 0, 0, + 16, 0, 0, 73, 65, 66, 79, 63, 64, 67, + 68, 0, 246, 147, 242, 112, 91, 93, 0, 228, + 130, 0, 174, 191, 0, 236, 237, 94, 0, 0, + 0, 138, 144, 0, 0, 0, 208, 209, 210, 261, + 142, 0, 207, 211, 244, 205, 0, 136, 0, 198, + 0, 199, 0, 14, 16, 28, 89, 16, 16, 33, + 0, 0, 78, 0, 0, 80, 0, 0, 248, 16, + 76, 81, 0, 0, 62, 48, 0, 0, 0, 128, + 0, 0, 132, 110, 0, 92, 176, 124, 189, 148, + 0, 141, 184, 0, 137, 143, 0, 139, 200, 201, + 135, 0, 91, 0, 53, 242, 74, 74, 0, 0, + 0, 0, 0, 43, 0, 0, 0, 0, 247, 230, + 98, 99, 96, 96, 106, 105, 109, 111, 0, 19, + 146, 140, 125, 0, 0, 91, 19, 0, 0, 0, + 18, 69, 69, 0, 0, 72, 77, 0, 0, 38, + 39, 97, 101, 101, 107, 113, 0, 21, 115, 114, + 30, 0, 0, 35, 72, 72, 19, 0, 0, 36, + 37, 0, 0, 51, 0, 0, 72, 102, 104, 100, + 108, 177, 0, 19, 54, 41, 42, 0, 70, 0, + 72, 72, 44, 0, 47, 103, 59, 0, 22, 0, + 17, 0, 46, 50, 74, 72, 19, 58, 15, 32, + 0, 0, 49, 0, 69, 0, 60, 71, 0, 45 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -437, -437, -437, -437, -437, -437, -437, -437, 10, -437, - -60, -126, -437, -15, -437, 502, 418, 0, -437, -437, - -437, -437, -437, -437, -437, -437, -437, -310, -436, -114, - -418, -437, 52, 214, -92, 20, -437, 361, 486, -437, - 451, 172, -329, 312, 133, -437, -437, 104, -437, 112, - -437, -437, 165, -437, -437, -6, -12, -437, -437, -437, - -437, -437, -437, -437, -437, 25, -437, -437, 431, -101, - -124, -437, -437, 270, -437, -437, 388, 233, -43, -41, - -437, -437, -437, -437, -437, -2 + -455, -455, -455, -455, -455, -455, -455, -455, 10, -455, + -36, -112, -455, -15, -455, 465, 384, 4, -455, -455, + -455, -455, -455, -455, -455, -455, -455, -313, -454, -174, + -426, -455, 17, 195, -175, -25, -455, 325, 491, -455, + 462, 150, -330, 309, 113, -455, -455, 84, -455, 89, + -455, -455, 136, -455, -455, -6, -20, -455, -455, -455, + -455, -455, -455, -455, -455, 25, -455, -455, 419, -106, + -122, -455, -455, 249, -455, -455, 371, 206, -43, -33, + -455, -455, -455, -455, -455, 243 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 7, 8, 9, 10, 11, 12, 13, 93, 373, - 15, 459, 484, 101, 500, 221, 99, 100, 374, 375, - 302, 464, 522, 432, 454, 516, 525, 95, 487, 211, - 456, 389, 379, 323, 382, 391, 299, 197, 120, 194, - 140, 231, 336, 250, 470, 441, 442, 496, 443, 444, - 445, 446, 334, 401, 478, 96, 57, 58, 332, 286, - 59, 60, 61, 62, 63, 64, 116, 65, 144, 130, - 66, 399, 385, 310, 311, 205, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 157 + -1, 7, 8, 9, 10, 11, 12, 13, 94, 375, + 15, 461, 486, 102, 502, 223, 100, 101, 376, 377, + 304, 466, 524, 434, 456, 518, 527, 96, 489, 213, + 458, 391, 381, 325, 384, 393, 301, 198, 121, 195, + 141, 233, 338, 252, 472, 443, 444, 498, 445, 446, + 447, 448, 336, 403, 480, 97, 57, 58, 334, 288, + 59, 60, 61, 62, 63, 64, 117, 65, 145, 131, + 66, 401, 387, 312, 313, 206, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 158 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -320,715 +320,723 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 102, 235, 146, 56, 147, 402, 388, 457, 19, 20, - 104, 94, 376, 223, 76, 251, 193, 111, 112, 113, - 77, 114, 115, 163, 488, 164, 347, 129, 14, 109, - 109, 109, 514, 109, 109, 149, 137, 132, 133, 240, - 229, 76, 105, 106, 76, 438, 439, 156, 126, 109, - 109, 134, 107, 158, 162, 119, 186, 108, 187, 122, - 117, 230, 138, 127, 109, 109, 135, 139, -262, 141, - -262, 148, -237, 150, 151, 152, 153, 154, 118, 76, - 276, 398, 277, -236, 485, 486, 278, 279, 280, 123, - 107, 452, 281, -266, 54, 108, 535, 220, 124, 245, - 329, 246, 129, 377, 529, 476, 159, 160, 161, 515, - -264, 226, -264, 165, 222, -238, -16, 125, 234, 56, - 237, 162, 185, 236, 479, 192, 196, -240, 129, 209, - 228, 440, 282, 54, 360, 109, 198, 248, 303, 304, - 305, 306, 308, 199, 316, 317, 212, 319, 320, 200, - 19, 20, 201, 253, 254, 255, 207, 257, 258, 260, - 314, 186, 315, 187, 19, 20, 21, 242, 208, -239, - 283, 54, 284, 285, 159, 160, 161, 210, 297, 289, - 290, 291, 292, 293, 294, 295, 296, 256, -262, 224, - -262, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 331, 322, 324, 325, - 326, 327, 328, 330, 384, 309, 202, 225, 56, 388, - 321, 349, 227, 232, 390, 142, 238, 395, 396, 365, - 339, 400, 249, 251, 143, 342, 54, -264, 414, -264, - 203, 159, 160, 161, 188, 346, 189, 298, 307, 204, - 54, 54, 110, 110, 110, 318, 110, 110, 394, 159, - 160, 161, 190, 367, 191, 301, 159, 160, 161, 239, - 352, 353, 131, 110, 314, 333, 315, 359, 145, 335, - 338, 159, 160, 161, 340, 252, 345, 110, 110, 159, - 160, 161, 369, 347, 109, 161, 362, 380, 324, 383, - 383, 460, 433, 354, 463, 407, 355, 169, 467, 468, - 392, -31, 419, 383, 383, 421, 422, 412, 372, 378, - 129, 206, 455, 159, 160, 161, 356, 429, 357, 448, - 482, 483, 361, 54, 179, 387, 461, 462, 397, 180, - 494, 408, 181, 182, 183, 184, 404, 403, 409, 491, - 229, 415, 159, 160, 161, 416, 56, 417, 131, 506, - 159, 160, 161, 508, 509, 159, 160, 161, 503, 504, - 418, 423, 428, 493, 424, 244, 410, 159, 160, 161, - 512, -267, -267, -267, 184, 523, 337, 425, 383, 159, - 160, 161, 436, 426, 520, 521, 213, 214, 215, 216, - 427, 430, 532, 217, 431, 218, 159, 160, 161, 530, - 537, 129, 159, 160, 161, 519, 434, 287, 159, 160, - 161, 435, 383, 383, 437, 447, 159, 160, 161, 159, - 160, 161, 474, 449, 348, 450, 313, 458, 465, 480, - 364, 466, 451, 166, 469, 472, 366, 473, 475, 495, - 167, 168, 169, 170, 368, -79, 481, 489, 380, 383, - 490, 501, 477, 159, 160, 161, 159, 160, 161, 505, - 171, 172, 351, 173, 174, 175, 176, 177, 178, 179, - 159, 160, 161, 507, 180, -191, 517, 181, 182, 183, - 184, 370, 344, 524, 186, 510, 187, -191, 511, 526, - -267, 383, 169, 170, 159, 160, 161, 528, 411, 531, - 159, 160, 161, 536, 98, 219, 492, 110, 381, 121, - 513, 159, 160, 161, -191, -191, -191, -191, 178, 179, - 350, -191, 195, -191, 180, -191, 363, 181, 182, 183, - 184, 386, -191, -191, -191, -191, 420, 405, 180, 533, - 313, 181, 182, 183, 184, 343, 300, -191, -191, -191, - -230, -191, -191, -191, -191, -191, -191, -191, -191, -191, - -191, -191, -230, 243, 471, 497, -191, 169, 170, -191, - -191, -191, -191, -191, 498, -191, 453, 393, -191, 169, - 170, 312, 0, 0, 0, 0, 159, 160, 161, -230, - -230, -230, -230, 178, 179, 0, -230, 0, -230, 180, - -230, 0, 181, 182, 183, 184, 179, -230, -230, -230, - -230, 180, 406, 0, 181, 182, 183, 184, 0, 0, - 0, 0, -230, -230, -230, 0, -230, -230, -230, -230, - -230, -230, -230, -230, -230, -230, -230, 159, 160, 161, - 0, -230, 0, 0, -230, -230, -230, -230, -230, 0, - -230, -13, 78, -230, 0, 0, 0, 0, 0, 0, - 76, 0, 16, 413, 17, 18, 19, 20, 21, 0, - 0, 22, 23, 24, 25, 26, 0, 27, 28, 29, - 30, 31, 32, 79, 97, 80, 81, 33, 82, 83, - 84, 85, 86, 87, 0, 0, 0, 88, 89, 90, - 34, 0, 91, 35, 36, 37, 38, 39, 0, 0, - 0, 0, 40, 41, 42, 43, 44, 45, 46, 179, - 0, 0, 0, 0, 180, 0, 47, 181, 182, 183, - 184, 1, 2, 3, 4, 5, 6, 0, 48, 49, - 0, 50, 0, 51, 52, -3, 78, 0, 0, 0, - 53, 92, 54, 55, 76, 0, 16, 0, 17, 18, - 19, 20, 21, 0, 0, 22, 23, 24, 25, 26, - 0, 27, 28, 29, 30, 31, 32, 79, 97, 80, - 81, 33, 82, 83, 84, 85, 86, 87, 0, 0, - 0, 88, 89, 90, 34, 0, 91, 35, 36, 37, - 38, 39, 0, 0, 0, 0, 40, 41, 42, 43, - 44, 45, 46, 0, 0, 0, 0, 0, 0, 0, - 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 48, 49, 0, 50, 0, 51, 52, 0, - 78, 0, 0, 0, 53, 92, 54, 55, 76, 371, - 16, 0, 17, 18, 19, 20, 21, 0, 0, 22, - 23, 24, 25, 26, 0, 27, 28, 29, 30, 31, - 32, 79, 97, 80, 81, 33, 82, 83, 84, 85, - 86, 87, 0, 0, 0, 88, 89, 90, 34, 0, - 91, 35, 36, 37, 38, 39, 0, 0, 0, 0, - 40, 41, 42, 43, 44, 45, 46, 0, 0, 0, - 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 48, 49, 0, 50, - 0, 51, 52, 0, 78, 0, 0, 0, 53, 92, - 54, 55, 76, 499, 16, 0, 17, 18, 19, 20, - 21, 0, 0, 22, 23, 24, 25, 26, 0, 27, - 28, 29, 30, 31, 32, 79, 97, 80, 81, 33, - 82, 83, 84, 85, 86, 87, 0, 0, 0, 88, - 89, 90, 34, 0, 91, 35, 36, 37, 38, 39, + 103, 459, 147, 56, 237, 390, 404, 378, 490, 225, + 105, 76, 148, 516, 164, 95, 165, 163, 14, 130, + 77, 76, 19, 20, 440, 441, 253, 150, 76, 110, + 110, 110, 108, 110, 110, 242, 138, 109, 349, 231, + 194, 76, 106, 107, 400, 224, 118, 157, 127, 110, + 110, 135, 108, 119, 187, 120, 188, 109, 124, 123, + -263, 333, -263, 128, 110, 110, 136, 351, -265, 142, + -265, 149, 125, 151, 152, 153, 154, 155, 139, 367, + 537, 487, 488, 140, -238, 163, 232, 19, 20, 21, + 369, 517, 454, 126, -267, 130, -237, 186, 531, 379, + 247, 210, 222, 478, 331, 166, 160, 161, 162, 54, + 248, 442, 228, 239, 54, 362, -16, 193, 197, 236, + 56, 130, 160, 161, 162, 481, 199, 212, 160, 161, + 162, 230, 211, 386, 54, 189, 110, 190, 250, 311, + 160, 161, 162, 392, 200, 229, 397, 398, 19, 20, + 201, 160, 161, 162, 255, 256, 257, 202, 259, 260, + 262, 316, 208, 305, 306, 307, 308, 310, 244, 318, + 319, 317, 321, 322, 54, 209, 187, 371, 188, 299, + 291, 292, 293, 294, 295, 296, 297, 298, 258, 214, + 226, 409, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 332, 414, 324, + 326, 327, 328, 329, 330, 227, 234, -263, 390, -263, + 56, 435, 323, 240, 143, 111, 111, 111, 402, 111, + 111, 251, 341, 144, 253, 54, -239, 344, 160, 161, + 162, 300, 416, 450, 303, 132, 111, 348, -265, 309, + -265, 146, 160, 161, 162, 463, 464, 160, 161, 162, + 111, 111, 112, 113, 114, 340, 115, 116, 320, 160, + 161, 162, 354, 355, 335, 342, 316, -241, 191, 361, + 192, 337, 133, 134, 396, 241, 317, 160, 161, 162, + 347, 493, 495, 349, 207, 162, 110, 356, 159, 382, + 326, 385, 385, 357, 160, 161, 162, 358, -240, 364, + 505, 506, 394, 254, 130, 385, 385, 462, 359, 457, + 465, 278, 514, 279, 469, 470, 374, 280, 281, 282, + 363, 54, 132, 283, 521, -31, 522, 523, 421, 380, + 389, 423, 424, 410, 399, 411, 484, 485, 406, 246, + 170, 532, 405, 431, 417, 418, 496, 419, 56, 420, + 425, 215, 216, 217, 218, 160, 161, 162, 219, 238, + 220, 170, 171, 231, 284, 508, 426, 180, 412, 510, + 511, 430, 181, 427, 428, 182, 183, 184, 185, 433, + 385, 289, 429, 350, 438, 160, 161, 162, 180, 432, + 436, 525, 437, 181, 203, 130, 182, 183, 184, 185, + 315, 449, 285, 439, 286, 287, 451, 452, 534, 460, + 467, -80, 453, 468, 385, 385, 539, 475, 204, 160, + 161, 162, 471, 477, 476, 474, 503, 205, 497, 54, + 483, 482, 160, 161, 162, 491, 526, 168, 169, 170, + 171, 160, 161, 162, -192, 509, 492, 366, 513, 528, + 382, 385, 512, 187, 479, 188, -192, 160, 161, 162, + 368, 507, 176, 177, 178, 179, 180, 99, 530, 370, + 538, 181, 221, 494, 182, 183, 184, 185, 519, 160, + 161, 162, 111, -192, -192, -192, -192, 160, 161, 162, + -192, 383, -192, 385, 181, -192, 535, 182, 183, 184, + 185, 533, -192, -192, -192, -192, 388, 372, 160, 161, + 162, 302, 515, 339, 122, 315, 422, -192, -192, -192, + -231, -192, -192, -192, -192, -192, -192, -192, -192, -192, + -192, -192, -231, 196, 346, -268, -192, 170, 171, -192, + -192, -192, -192, -192, 345, -192, 473, 499, -192, 455, + 170, 171, 245, 500, 0, 160, 161, 162, 395, -231, + -231, -231, -231, 179, 180, 314, -231, 0, -231, 181, + 0, -231, 182, 183, 184, 185, 179, 180, -231, -231, + -231, -231, 181, 413, 0, 182, 183, 184, 185, -268, + -268, -268, 185, -231, -231, -231, 0, -231, -231, -231, + -231, -231, -231, -231, -231, -231, -231, -231, 160, 161, + 162, 0, -231, 0, 0, -231, -231, -231, -231, -231, + 0, -231, -13, 78, -231, 0, 0, 0, 0, 0, + 0, 76, 0, 16, 352, 17, 18, 19, 20, 21, + 0, 0, 22, 23, 24, 25, 26, 0, 27, 28, + 29, 30, 31, 32, 79, 98, 80, 81, 33, 82, + 83, 84, 85, 86, 87, 160, 161, 162, 88, 89, + 90, 91, 34, 0, 92, 35, 36, 37, 38, 39, + 160, 161, 162, 0, 40, 41, 42, 43, 44, 45, + 46, 365, 0, 160, 161, 162, 0, 0, 47, 0, + 0, 160, 161, 162, 0, 0, 407, 0, 0, 0, + 48, 49, 0, 50, 0, 51, 52, -3, 78, 408, + 0, 0, 53, 93, 54, 55, 76, 415, 16, 0, + 17, 18, 19, 20, 21, 0, 0, 22, 23, 24, + 25, 26, 0, 27, 28, 29, 30, 31, 32, 79, + 98, 80, 81, 33, 82, 83, 84, 85, 86, 87, + 0, 0, 0, 88, 89, 90, 91, 34, 0, 92, + 35, 36, 37, 38, 39, 0, 0, 0, 0, 40, + 41, 42, 43, 44, 45, 46, 180, 0, 0, 0, + 0, 181, 0, 47, 182, 183, 184, 185, 1, 2, + 3, 4, 5, 6, 0, 48, 49, 0, 50, 0, + 51, 52, 0, 78, 0, 0, 0, 53, 93, 54, + 55, 76, 373, 16, 0, 17, 18, 19, 20, 21, + 0, 0, 22, 23, 24, 25, 26, 0, 27, 28, + 29, 30, 31, 32, 79, 98, 80, 81, 33, 82, + 83, 84, 85, 86, 87, 0, 0, 0, 88, 89, + 90, 91, 34, 0, 92, 35, 36, 37, 38, 39, 0, 0, 0, 0, 40, 41, 42, 43, 44, 45, 46, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 49, 0, 50, 0, 51, 52, 0, 78, 0, - 0, 0, 53, 92, 54, 55, 76, 502, 16, 0, + 0, 0, 53, 93, 54, 55, 76, 501, 16, 0, 17, 18, 19, 20, 21, 0, 0, 22, 23, 24, 25, 26, 0, 27, 28, 29, 30, 31, 32, 79, - 97, 80, 81, 33, 82, 83, 84, 85, 86, 87, - 0, 0, 0, 88, 89, 90, 34, 0, 91, 35, - 36, 37, 38, 39, 0, 0, 0, 0, 40, 41, - 42, 43, 44, 45, 46, 0, 0, 0, 0, 0, - 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 48, 49, 0, 50, 0, 51, - 52, 0, 78, 0, 0, 0, 53, 92, 54, 55, - 76, 518, 16, 0, 17, 18, 19, 20, 21, 0, - 0, 22, 23, 24, 25, 26, 0, 27, 28, 29, - 30, 31, 32, 79, 97, 80, 81, 33, 82, 83, - 84, 85, 86, 87, 0, 0, 0, 88, 89, 90, - 34, 0, 91, 35, 36, 37, 38, 39, 0, 0, - 0, 0, 40, 41, 42, 43, 44, 45, 46, 0, - 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 48, 49, - 0, 50, 0, 51, 52, 0, 78, 0, 0, 0, - 53, 92, 54, 55, 76, 527, 16, 0, 17, 18, - 19, 20, 21, 0, 0, 22, 23, 24, 25, 26, - 0, 27, 28, 29, 30, 31, 32, 79, 97, 80, - 81, 33, 82, 83, 84, 85, 86, 87, 0, 0, - 0, 88, 89, 90, 34, 0, 91, 35, 36, 37, - 38, 39, 0, 0, 0, 0, 40, 41, 42, 43, - 44, 45, 46, 0, 0, 0, 0, 0, 0, 0, - 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 48, 49, 0, 50, 0, 51, 52, 0, - 78, 0, 0, 0, 53, 92, 54, 55, 76, 0, - 16, 0, 17, 18, 19, 20, 21, 0, 0, 22, - 23, 24, 25, 26, 0, 27, 28, 29, 30, 31, - 32, 79, 97, 80, 81, 33, 82, 83, 84, 85, - 86, 87, 0, 0, 0, 88, 89, 90, 34, 0, - 91, 35, 36, 37, 38, 39, 0, 0, 0, 0, - 40, 41, 42, 43, 44, 45, 46, 0, 0, 534, - 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 48, 49, 0, 50, - 0, 51, 52, 0, 78, 0, 0, 0, 53, 92, - 54, 55, 76, 0, 16, 0, 17, 18, 19, 20, - 21, 0, 0, 22, 23, 24, 25, 26, 0, 27, - 28, 29, 30, 31, 32, 79, 97, 80, 81, 33, - 82, 83, 84, 85, 86, 87, 0, 0, 0, 88, - 89, 90, 34, 0, 91, 35, 36, 37, 38, 39, + 98, 80, 81, 33, 82, 83, 84, 85, 86, 87, + 0, 0, 0, 88, 89, 90, 91, 34, 0, 92, + 35, 36, 37, 38, 39, 0, 0, 0, 0, 40, + 41, 42, 43, 44, 45, 46, 0, 0, 0, 0, + 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 48, 49, 0, 50, 0, + 51, 52, 0, 78, 0, 0, 0, 53, 93, 54, + 55, 76, 504, 16, 0, 17, 18, 19, 20, 21, + 0, 0, 22, 23, 24, 25, 26, 0, 27, 28, + 29, 30, 31, 32, 79, 98, 80, 81, 33, 82, + 83, 84, 85, 86, 87, 0, 0, 0, 88, 89, + 90, 91, 34, 0, 92, 35, 36, 37, 38, 39, 0, 0, 0, 0, 40, 41, 42, 43, 44, 45, 46, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 49, 0, 50, 0, 51, 52, 0, 78, 0, - 0, 0, 53, 92, 54, 55, 76, 0, 16, 0, + 0, 0, 53, 93, 54, 55, 76, 520, 16, 0, 17, 18, 19, 20, 21, 0, 0, 22, 23, 24, 25, 26, 0, 27, 28, 29, 30, 31, 32, 79, - 0, 80, 81, 33, 82, 83, 84, 85, 86, 87, - 0, 0, 0, 88, 89, 90, 34, 0, 91, 35, - 36, 37, 38, 39, 0, 0, 0, 0, 40, 41, - 42, 43, 44, 45, 46, 0, 0, 0, 0, 0, - 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 48, 49, 0, 50, 0, 51, - 52, 78, 0, 0, 0, 0, 53, 92, 54, 55, - 0, 16, 0, 17, 18, 19, 20, 21, 0, 0, - 22, 23, 24, 25, 26, 0, 27, 28, 29, 30, - 31, 32, 0, 0, 0, 0, 33, 0, -267, 0, - 0, 0, 0, 0, 0, 167, 168, 169, 170, 34, - 0, 0, 35, 36, 37, 38, 39, 0, 0, 0, - 0, 40, 41, 42, 43, 44, 45, 46, 173, 174, - 175, 176, 177, 178, 179, 47, 0, 0, 0, 180, - 0, 0, 181, 182, 183, 184, 0, 48, 49, 0, - 50, 0, 51, 52, 78, 0, 0, 0, 0, 53, - -74, 54, 55, 0, 16, 0, 17, 18, 19, 20, - 21, 0, 0, 22, 23, 24, 25, 26, 0, 27, - 28, 29, 30, 31, 32, 0, 0, 0, 0, 33, - 0, 0, 0, 0, 0, 0, 167, 168, 169, 170, - 0, 0, 34, 0, 0, 35, 36, 37, 38, 39, + 98, 80, 81, 33, 82, 83, 84, 85, 86, 87, + 0, 0, 0, 88, 89, 90, 91, 34, 0, 92, + 35, 36, 37, 38, 39, 0, 0, 0, 0, 40, + 41, 42, 43, 44, 45, 46, 0, 0, 0, 0, + 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 48, 49, 0, 50, 0, + 51, 52, 0, 78, 0, 0, 0, 53, 93, 54, + 55, 76, 529, 16, 0, 17, 18, 19, 20, 21, + 0, 0, 22, 23, 24, 25, 26, 0, 27, 28, + 29, 30, 31, 32, 79, 98, 80, 81, 33, 82, + 83, 84, 85, 86, 87, 0, 0, 0, 88, 89, + 90, 91, 34, 0, 92, 35, 36, 37, 38, 39, 0, 0, 0, 0, 40, 41, 42, 43, 44, 45, - 46, 175, 176, 177, 178, 179, 0, 0, 47, 0, - 180, 0, 0, 181, 182, 183, 184, 0, 0, 0, - 48, 49, 0, 50, 0, 51, 52, 0, 0, 0, - 0, -74, 53, 0, 54, 55, 76, 0, 16, 0, - 17, 18, 19, 20, 21, 0, 0, 128, 23, 24, - 25, 26, 108, 27, 28, 29, 30, 31, 32, 0, - 0, 0, 0, 33, 0, 0, 0, 0, 0, 167, - 168, 169, 170, 0, 0, 0, 34, 0, 0, 35, - 36, 37, 38, 39, 0, 0, 0, 0, 40, 41, - 42, 43, 44, 45, 46, 176, 177, 178, 179, 0, - 0, 0, 47, 180, 0, 0, 181, 182, 183, 184, - 0, 0, 0, 0, 48, 49, 0, 50, 0, 51, - 52, 0, 0, 0, 0, 0, 53, 0, 54, 55, - 76, 0, 16, 0, 17, 18, 19, 20, 21, 0, + 46, 0, 0, 0, 0, 0, 0, 0, 47, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 49, 0, 50, 0, 51, 52, 0, 78, 0, + 0, 0, 53, 93, 54, 55, 76, 0, 16, 0, + 17, 18, 19, 20, 21, 0, 0, 22, 23, 24, + 25, 26, 0, 27, 28, 29, 30, 31, 32, 79, + 98, 80, 81, 33, 82, 83, 84, 85, 86, 87, + 0, 0, 0, 88, 89, 90, 91, 34, 0, 92, + 35, 36, 37, 38, 39, 0, 0, 0, 0, 40, + 41, 42, 43, 44, 45, 46, 0, 0, 536, 0, + 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 48, 49, 0, 50, 0, + 51, 52, 0, 78, 0, 0, 0, 53, 93, 54, + 55, 76, 0, 16, 0, 17, 18, 19, 20, 21, + 0, 0, 22, 23, 24, 25, 26, 0, 27, 28, + 29, 30, 31, 32, 79, 98, 80, 81, 33, 82, + 83, 84, 85, 86, 87, 0, 0, 0, 88, 89, + 90, 91, 34, 0, 92, 35, 36, 37, 38, 39, + 0, 0, 0, 0, 40, 41, 42, 43, 44, 45, + 46, 0, 0, 0, 0, 0, 0, 0, 47, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 49, 0, 50, 0, 51, 52, 0, 78, 0, + 0, 0, 53, 93, 54, 55, 76, 0, 16, 0, + 17, 18, 19, 20, 21, 0, 0, 22, 23, 24, + 25, 26, 0, 27, 28, 29, 30, 31, 32, 79, + 0, 80, 81, 33, 82, 83, 84, 85, 86, 87, + 0, 0, 0, 88, 89, 90, 91, 34, 0, 92, + 35, 36, 37, 38, 39, 0, 0, 0, 0, 40, + 41, 42, 43, 44, 45, 46, 0, 0, 0, 0, + 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 48, 49, 0, 50, 0, + 51, 52, 78, 0, 0, 0, 0, 53, 93, 54, + 55, 0, 16, 0, 17, 18, 19, 20, 21, 0, 0, 22, 23, 24, 25, 26, 0, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 33, 0, 0, - 0, 0, 0, 167, 168, 169, 170, 0, 0, 0, + -268, 0, 0, 0, 0, 0, 0, 168, 169, 170, + 171, 34, 0, 0, 35, 36, 37, 38, 39, 0, + 0, 0, 0, 40, 41, 42, 43, 44, 45, 46, + 174, 175, 176, 177, 178, 179, 180, 47, 0, 0, + 0, 181, 0, 0, 182, 183, 184, 185, 0, 48, + 49, 0, 50, 0, 51, 52, 78, 0, 0, 0, + 0, 53, -75, 54, 55, 0, 16, 0, 17, 18, + 19, 20, 21, 0, 0, 22, 23, 24, 25, 26, + 0, 27, 28, 29, 30, 31, 32, 0, 0, 0, + 0, 33, 0, 0, 0, 0, 0, 0, 168, 169, + 170, 171, 0, 0, 0, 34, 0, 0, 35, 36, + 37, 38, 39, 0, 0, 0, 0, 40, 41, 42, + 43, 44, 45, 46, 177, 178, 179, 180, 0, 0, + 0, 47, 181, 0, 0, 182, 183, 184, 185, 0, + 0, 0, 0, 48, 49, 0, 50, 0, 51, 52, + 0, 0, 0, 0, -75, 53, 0, 54, 55, 76, + 0, 16, 0, 17, 18, 19, 20, 21, 0, 0, + 129, 23, 24, 25, 26, 109, 27, 28, 29, 30, + 31, 32, 0, 0, 0, 0, 33, 0, 0, 0, + 0, 0, 0, 168, 169, 170, 171, 0, 0, 0, 34, 0, 0, 35, 36, 37, 38, 39, 0, 0, 0, 0, 40, 41, 42, 43, 44, 45, 46, 0, - 177, 178, 179, 0, 0, 0, 47, 180, 0, 0, - 181, 182, 183, 184, 0, 0, 0, 0, 48, 49, + 178, 179, 180, 0, 0, 0, 47, 181, 0, 0, + 182, 183, 184, 185, 0, 0, 0, 0, 48, 49, 0, 50, 0, 51, 52, 0, 0, 0, 0, 0, - 53, 0, 54, 55, 16, 103, 17, 18, 19, 20, - 21, 0, 0, 22, 23, 24, 25, 26, 0, 27, - 28, 29, 30, 31, 32, 0, 0, 0, 0, 33, - 0, 0, 0, 167, -267, 169, 170, 0, 0, 0, - 0, 0, 34, 0, 0, 35, 36, 37, 38, 39, - 0, 0, 0, 0, 40, 41, 42, 43, 44, 45, - 46, 178, 179, 0, 0, 0, 0, 180, 47, 0, - 181, 182, 183, 184, 0, 0, 0, 0, 0, 0, - 48, 49, 0, 50, 0, 51, 52, 0, 0, 0, - 0, 0, 53, 0, 54, 55, 16, 0, 17, 18, + 53, 0, 54, 55, 76, 0, 16, 0, 17, 18, 19, 20, 21, 0, 0, 22, 23, 24, 25, 26, 0, 27, 28, 29, 30, 31, 32, 0, 0, 0, - 0, 33, 0, 0, 0, 167, 168, 169, 170, 0, + 0, 33, 0, 0, 0, 0, 168, -268, 170, 171, + 0, 0, 0, 0, 0, 34, 0, 0, 35, 36, + 37, 38, 39, 0, 0, 0, 0, 40, 41, 42, + 43, 44, 45, 46, 179, 180, 0, 0, 0, 0, + 181, 47, 0, 182, 183, 184, 185, 0, 0, 0, + 0, 0, 0, 48, 49, 0, 50, 0, 51, 52, + 0, 0, 0, 0, 0, 53, 0, 54, 55, 16, + 104, 17, 18, 19, 20, 21, 0, 0, 22, 23, + 24, 25, 26, 0, 27, 28, 29, 30, 31, 32, + 0, 0, 0, 0, 33, 0, 0, 0, 0, 168, + 169, 170, 171, 0, 0, 0, 0, 0, 34, 0, + 0, 35, 36, 37, 38, 39, 0, 0, 0, 0, + 40, 41, 42, 43, 44, 45, 46, 179, 180, 0, + 0, 0, 0, 181, 47, 0, 182, 183, 184, 185, + 0, 0, 0, 0, 0, 0, 48, 49, 0, 50, + 0, 51, 52, 0, 0, 0, 0, 0, 53, 0, + 54, 55, 16, 0, 17, 18, 19, 20, 21, 0, + 0, 22, 23, 24, 25, 26, 0, 27, 28, 29, + 30, 31, 32, 0, 0, 0, 0, 33, 215, 216, + 217, 218, 0, 0, 0, 219, 0, 220, 0, 0, + 0, 34, 0, 0, 35, 36, 37, 38, 39, 0, + 0, 0, 0, 40, 41, 42, 43, 44, 45, 46, + 0, 0, 160, 161, 162, 0, 0, 47, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, + 49, 0, 50, 0, 51, 52, 0, 0, 0, 0, + 0, 53, 137, 54, 55, 16, 0, 17, 18, 19, + 20, 21, 0, 0, 22, 23, 24, 25, 26, 0, + 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, + 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, 36, 37, 38, 39, 0, 0, 0, 0, 40, 41, 42, 43, - 44, 45, 46, 178, 179, 0, 0, 0, 0, 180, - 47, 0, 181, 182, 183, 184, 0, 0, 0, 0, + 44, 45, 46, 0, 0, 0, 0, 0, 0, 0, + 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 49, 0, 50, 0, 51, 52, 0, - 0, 0, 0, 0, 53, 136, 54, 55, 16, 0, + 0, 0, 0, 156, 53, 0, 54, 55, 16, 0, 17, 18, 19, 20, 21, 0, 0, 22, 23, 24, 25, 26, 0, 27, 28, 29, 30, 31, 32, 0, - 0, 0, 0, 33, 213, 214, 215, 216, 0, 0, - 0, 217, 0, 218, 0, 0, 34, 0, 0, 35, - 36, 37, 38, 39, 0, 0, 0, 0, 40, 41, - 42, 43, 44, 45, 46, 0, 0, 159, 160, 161, - 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 48, 49, 0, 50, 0, 51, - 52, 0, 0, 0, 0, 155, 53, 0, 54, 55, - 16, 0, 17, 18, 19, 20, 21, 0, 0, 22, - 23, 24, 25, 26, 0, 27, 28, 29, 30, 31, - 32, 0, 0, 0, 0, 33, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, - 0, 35, 36, 37, 38, 39, 0, 0, 0, 0, - 40, 41, 42, 43, 44, 45, 46, 0, 0, 0, - 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 48, 49, 0, 50, - 0, 51, 52, 0, 0, 0, 0, 233, 53, 0, - 54, 55, 16, 0, 17, 18, 19, 20, 21, 0, - 0, 22, 23, 24, 25, 26, 0, 27, 28, 29, - 30, 31, 32, 0, 0, 0, 0, 33, 0, 0, + 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, + 35, 36, 37, 38, 39, 0, 0, 0, 0, 40, + 41, 42, 43, 44, 45, 46, 0, 0, 0, 0, + 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 48, 49, 0, 50, 0, + 51, 52, 0, 0, 0, 0, 235, 53, 0, 54, + 55, 16, 0, 17, 18, 19, 20, 21, 0, 0, + 22, 23, 24, 25, 26, 0, 27, 28, 29, 30, + 31, 32, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, 36, 37, 38, 39, 0, 0, 0, 0, 40, 41, 42, 43, 44, 45, 46, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 49, - 0, 50, 0, 51, 52, 0, 0, 0, 0, 247, + 0, 50, 0, 51, 52, 0, 0, 0, 0, 249, 53, 0, 54, 55, 16, 0, 17, 18, 19, 20, 21, 0, 0, 22, 23, 24, 25, 26, 0, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 34, 0, 0, 35, 36, 37, 38, 39, - 0, 0, 0, 0, 40, 41, 42, 43, 44, 45, - 46, 0, 0, 0, 0, 0, 0, 0, 47, 0, + 0, 0, 0, 34, 0, 0, 35, 36, 37, 38, + 39, 0, 0, 0, 0, 40, 41, 42, 43, 44, + 45, 46, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 48, 49, 0, 50, 0, 51, 52, 0, 0, 0, - 0, 259, 53, 0, 54, 55, 16, 0, 17, 18, - 19, 20, 21, 0, 0, 22, 23, 24, 25, 26, - 0, 27, 28, 29, 30, 31, 32, 0, 0, 0, - 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 34, 0, 0, 35, 36, 37, - 38, 39, 0, 0, 0, 0, 40, 41, 42, 43, - 44, 45, 46, 0, 0, 0, 0, 0, 0, 0, - 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 48, 49, 0, 50, 0, 51, 52, 0, - 0, 0, 0, 288, 53, 0, 54, 55, 16, 0, - 17, 18, 19, 20, 21, 0, 0, 22, 23, 24, - 25, 26, 0, 27, 28, 29, 30, 31, 32, 0, - 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, + 0, 48, 49, 0, 50, 0, 51, 52, 0, 0, + 0, 0, 261, 53, 0, 54, 55, 16, 0, 17, + 18, 19, 20, 21, 0, 0, 22, 23, 24, 25, + 26, 0, 27, 28, 29, 30, 31, 32, 0, 0, + 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, 36, 37, 38, 39, 0, 0, 0, 0, 40, 41, 42, 43, 44, 45, 46, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 49, 0, 50, 0, 51, - 52, 0, 0, 0, 0, 341, 53, 0, 54, 55, + 52, 0, 0, 0, 0, 290, 53, 0, 54, 55, 16, 0, 17, 18, 19, 20, 21, 0, 0, 22, 23, 24, 25, 26, 0, 27, 28, 29, 30, 31, 32, 0, 0, 0, 0, 33, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, + 0, 0, 35, 36, 37, 38, 39, 0, 0, 0, + 0, 40, 41, 42, 43, 44, 45, 46, 0, 0, + 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 48, 49, 0, + 50, 0, 51, 52, 0, 0, 0, 0, 343, 53, + 0, 54, 55, 16, 0, 17, 18, 19, 20, 21, + 0, 0, 22, 23, 24, 25, 26, 0, 27, 28, + 29, 30, 31, 32, 0, 0, 0, 0, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 34, 0, 0, 35, 36, 37, 38, 39, + 0, 0, 0, 0, 40, 41, 42, 43, 44, 45, + 46, 0, 0, 0, 0, 0, 0, 0, 47, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 49, 0, 50, 0, 51, 52, 0, 0, 0, + 0, 360, 53, 0, 54, 55, 16, 0, 17, 18, + 19, 20, 21, 0, 0, 22, 23, 24, 25, 26, + 0, 27, 28, 29, 30, 31, 32, 0, 0, 0, + 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 34, 0, 0, 35, 36, + 37, 38, 39, 0, 0, 0, 0, 40, 41, 42, + 43, 44, 45, 46, 0, 0, 0, 0, 0, 0, + 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 48, 49, 0, 50, 0, 51, 52, + 0, 0, 0, 0, 0, 53, 0, 54, 55, 16, + 0, 17, 18, 19, 20, 21, 0, 0, 22, 23, + 24, 25, 26, 0, 27, 28, 29, 30, 31, 32, + 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, 36, 37, 38, 39, 0, 0, 0, 0, 40, 41, 42, 43, 44, 45, 46, 0, 0, 0, - 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 48, 49, 0, 50, - 0, 51, 52, 0, 0, 0, 0, 358, 53, 0, - 54, 55, 16, 0, 17, 18, 19, 20, 21, 0, - 0, 22, 23, 24, 25, 26, 0, 27, 28, 29, - 30, 31, 32, 0, 0, 0, 0, 33, 0, 0, + 0, 0, 0, 0, 47, 167, 0, 0, 0, 0, + 0, 0, 168, 169, 170, 171, 48, 49, 0, 50, + 0, 51, 52, 0, 0, 0, 0, 0, 243, 0, + 54, 55, 172, 173, 353, 174, 175, 176, 177, 178, + 179, 180, 0, 0, 0, 0, 181, 167, 0, 182, + 183, 184, 185, 0, 168, 169, 170, 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 34, 0, 0, 35, 36, 37, 38, 39, 0, 0, - 0, 0, 40, 41, 42, 43, 44, 45, 46, 0, - 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 48, 49, - 0, 50, 0, 51, 52, 0, 0, 0, 0, 0, - 53, 0, 54, 55, 16, 0, 17, 18, 19, 20, - 21, 0, 0, 22, 23, 24, 25, 26, 0, 27, - 28, 29, 30, 31, 32, 0, 0, 0, 0, 33, + 0, 0, 0, 0, 172, 173, 0, 174, 175, 176, + 177, 178, 179, 180, 0, 0, 0, 0, 181, 167, + 0, 182, 183, 184, 185, 0, 168, 169, 170, 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 34, 0, 0, 35, 36, 37, 38, 39, - 0, 0, 0, 0, 40, 41, 42, 43, 44, 45, - 46, 0, 0, 0, 0, 0, 0, 0, 47, 166, - 0, 0, 0, 0, 0, 0, 167, 168, 169, 170, - 48, 49, 0, 50, 0, 51, 52, 0, 0, 0, - 0, 0, 241, 0, 54, 55, 171, 172, 0, 173, - 174, 175, 176, 177, 178, 179, 0, 0, 0, 0, - 180, 166, 0, 181, 182, 183, 184, 0, 167, 168, - 169, 170, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, - 0, 173, 174, 175, 176, 177, 178, 179, 0, 0, - 0, 0, 180, 0, 0, 181, 182, 183, 184 + 0, 0, 0, 0, 0, 0, 0, 173, 0, 174, + 175, 176, 177, 178, 179, 180, 0, 0, 0, 0, + 181, 0, 0, 182, 183, 184, 185 }; static const yytype_int16 yycheck[] = { - 15, 125, 45, 9, 45, 334, 316, 425, 15, 16, - 16, 11, 9, 114, 9, 11, 76, 19, 20, 21, - 10, 23, 24, 9, 460, 11, 11, 39, 0, 19, - 20, 21, 23, 23, 24, 47, 42, 39, 40, 140, - 23, 9, 17, 18, 9, 15, 16, 53, 38, 39, - 40, 41, 20, 55, 76, 30, 9, 25, 11, 34, - 11, 121, 20, 38, 54, 55, 41, 25, 9, 44, - 11, 46, 68, 48, 49, 50, 51, 52, 99, 9, - 9, 103, 11, 68, 43, 44, 15, 16, 17, 99, - 20, 420, 21, 9, 101, 25, 532, 97, 99, 142, - 224, 142, 114, 100, 522, 100, 72, 73, 74, 100, - 9, 117, 11, 99, 12, 68, 99, 99, 124, 125, - 132, 76, 99, 125, 453, 9, 20, 68, 140, 100, - 120, 101, 61, 101, 102, 125, 99, 143, 198, 199, - 200, 201, 202, 99, 204, 205, 100, 207, 208, 99, - 15, 16, 99, 159, 160, 161, 99, 163, 164, 165, - 203, 9, 203, 11, 15, 16, 17, 142, 99, 68, - 99, 101, 101, 102, 72, 73, 74, 45, 193, 185, - 186, 187, 188, 189, 190, 191, 192, 162, 9, 99, - 11, 166, 167, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 177, 178, 179, 180, 12, 213, 214, 215, - 216, 217, 218, 225, 306, 66, 66, 99, 224, 529, - 210, 12, 98, 98, 316, 90, 10, 319, 320, 12, - 236, 332, 68, 11, 99, 241, 101, 9, 362, 11, - 90, 72, 73, 74, 9, 251, 11, 20, 90, 99, - 101, 101, 19, 20, 21, 99, 23, 24, 318, 72, - 73, 74, 9, 12, 11, 20, 72, 73, 74, 100, - 276, 277, 39, 40, 317, 99, 317, 283, 45, 68, - 98, 72, 73, 74, 10, 98, 23, 54, 55, 72, - 73, 74, 12, 11, 284, 74, 99, 303, 304, 305, - 306, 427, 394, 102, 430, 12, 102, 59, 434, 435, - 316, 99, 372, 319, 320, 375, 376, 12, 18, 20, - 332, 88, 423, 72, 73, 74, 102, 387, 102, 12, - 456, 457, 102, 101, 86, 99, 428, 429, 98, 91, - 466, 347, 94, 95, 96, 97, 336, 23, 10, 463, - 23, 10, 72, 73, 74, 10, 362, 10, 125, 485, - 72, 73, 74, 489, 490, 72, 73, 74, 482, 483, - 10, 20, 99, 465, 98, 142, 351, 72, 73, 74, - 494, 94, 95, 96, 97, 511, 98, 98, 394, 72, - 73, 74, 398, 98, 508, 509, 39, 40, 41, 42, - 98, 98, 528, 46, 100, 48, 72, 73, 74, 523, - 536, 423, 72, 73, 74, 507, 98, 184, 72, 73, - 74, 98, 428, 429, 98, 9, 72, 73, 74, 72, - 73, 74, 447, 10, 100, 98, 203, 9, 99, 454, - 100, 98, 100, 50, 25, 76, 100, 98, 70, 77, - 57, 58, 59, 60, 100, 98, 100, 98, 464, 465, - 98, 9, 452, 72, 73, 74, 72, 73, 74, 484, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 72, 73, 74, 99, 91, 0, 501, 94, 95, 96, - 97, 100, 98, 69, 9, 100, 11, 12, 98, 19, - 57, 507, 59, 60, 72, 73, 74, 98, 100, 524, - 72, 73, 74, 98, 12, 97, 464, 284, 304, 33, - 495, 72, 73, 74, 39, 40, 41, 42, 85, 86, - 98, 46, 81, 48, 91, 50, 98, 94, 95, 96, - 97, 308, 57, 58, 59, 60, 374, 98, 91, 529, - 317, 94, 95, 96, 97, 243, 195, 72, 73, 74, - 0, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 12, 142, 441, 471, 91, 59, 60, 94, - 95, 96, 97, 98, 472, 100, 421, 317, 103, 59, - 60, 203, -1, -1, -1, -1, 72, 73, 74, 39, - 40, 41, 42, 85, 86, -1, 46, -1, 48, 91, - 50, -1, 94, 95, 96, 97, 86, 57, 58, 59, - 60, 91, 98, -1, 94, 95, 96, 97, -1, -1, - -1, -1, 72, 73, 74, -1, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 72, 73, 74, - -1, 91, -1, -1, 94, 95, 96, 97, 98, -1, - 100, 0, 1, 103, -1, -1, -1, -1, -1, -1, - 9, -1, 11, 98, 13, 14, 15, 16, 17, -1, - -1, 20, 21, 22, 23, 24, -1, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, -1, -1, -1, 46, 47, 48, - 49, -1, 51, 52, 53, 54, 55, 56, -1, -1, - -1, -1, 61, 62, 63, 64, 65, 66, 67, 86, - -1, -1, -1, -1, 91, -1, 75, 94, 95, 96, - 97, 3, 4, 5, 6, 7, 8, -1, 87, 88, - -1, 90, -1, 92, 93, 0, 1, -1, -1, -1, - 99, 100, 101, 102, 9, -1, 11, -1, 13, 14, - 15, 16, 17, -1, -1, 20, 21, 22, 23, 24, - -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, -1, -1, - -1, 46, 47, 48, 49, -1, 51, 52, 53, 54, - 55, 56, -1, -1, -1, -1, 61, 62, 63, 64, - 65, 66, 67, -1, -1, -1, -1, -1, -1, -1, - 75, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 87, 88, -1, 90, -1, 92, 93, -1, - 1, -1, -1, -1, 99, 100, 101, 102, 9, 10, - 11, -1, 13, 14, 15, 16, 17, -1, -1, 20, - 21, 22, 23, 24, -1, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, -1, -1, -1, 46, 47, 48, 49, -1, - 51, 52, 53, 54, 55, 56, -1, -1, -1, -1, - 61, 62, 63, 64, 65, 66, 67, -1, -1, -1, - -1, -1, -1, -1, 75, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 87, 88, -1, 90, - -1, 92, 93, -1, 1, -1, -1, -1, 99, 100, - 101, 102, 9, 10, 11, -1, 13, 14, 15, 16, - 17, -1, -1, 20, 21, 22, 23, 24, -1, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, -1, -1, -1, 46, - 47, 48, 49, -1, 51, 52, 53, 54, 55, 56, - -1, -1, -1, -1, 61, 62, 63, 64, 65, 66, - 67, -1, -1, -1, -1, -1, -1, -1, 75, -1, + 15, 427, 45, 9, 126, 318, 336, 9, 462, 115, + 16, 9, 45, 23, 9, 11, 11, 77, 0, 39, + 10, 9, 15, 16, 15, 16, 11, 47, 9, 19, + 20, 21, 20, 23, 24, 141, 42, 25, 11, 23, + 76, 9, 17, 18, 104, 12, 11, 53, 38, 39, + 40, 41, 20, 100, 9, 30, 11, 25, 100, 34, + 9, 12, 11, 38, 54, 55, 41, 12, 9, 44, + 11, 46, 100, 48, 49, 50, 51, 52, 20, 12, + 534, 43, 44, 25, 69, 77, 122, 15, 16, 17, + 12, 101, 422, 100, 9, 115, 69, 100, 524, 101, + 143, 91, 98, 101, 226, 100, 73, 74, 75, 102, + 143, 102, 118, 133, 102, 103, 100, 9, 20, 125, + 126, 141, 73, 74, 75, 455, 100, 45, 73, 74, + 75, 121, 101, 308, 102, 9, 126, 11, 144, 67, + 73, 74, 75, 318, 100, 99, 321, 322, 15, 16, + 100, 73, 74, 75, 160, 161, 162, 100, 164, 165, + 166, 204, 100, 199, 200, 201, 202, 203, 143, 205, + 206, 204, 208, 209, 102, 100, 9, 12, 11, 194, + 186, 187, 188, 189, 190, 191, 192, 193, 163, 101, + 100, 12, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 227, 12, 215, + 216, 217, 218, 219, 220, 100, 99, 9, 531, 11, + 226, 396, 212, 10, 91, 19, 20, 21, 334, 23, + 24, 69, 238, 100, 11, 102, 69, 243, 73, 74, + 75, 20, 364, 12, 20, 39, 40, 253, 9, 91, + 11, 45, 73, 74, 75, 430, 431, 73, 74, 75, + 54, 55, 19, 20, 21, 99, 23, 24, 100, 73, + 74, 75, 278, 279, 100, 10, 319, 69, 9, 285, + 11, 69, 39, 40, 320, 101, 319, 73, 74, 75, + 23, 465, 467, 11, 88, 75, 286, 103, 55, 305, + 306, 307, 308, 103, 73, 74, 75, 103, 69, 100, + 484, 485, 318, 99, 334, 321, 322, 429, 103, 425, + 432, 9, 496, 11, 436, 437, 18, 15, 16, 17, + 103, 102, 126, 21, 509, 100, 510, 511, 374, 20, + 100, 377, 378, 349, 99, 10, 458, 459, 338, 143, + 60, 525, 23, 389, 10, 10, 468, 10, 364, 10, + 20, 39, 40, 41, 42, 73, 74, 75, 46, 126, + 48, 60, 61, 23, 62, 487, 99, 87, 353, 491, + 492, 100, 92, 99, 99, 95, 96, 97, 98, 101, + 396, 185, 99, 101, 400, 73, 74, 75, 87, 99, + 99, 513, 99, 92, 67, 425, 95, 96, 97, 98, + 204, 9, 100, 99, 102, 103, 10, 99, 530, 9, + 100, 99, 101, 99, 430, 431, 538, 99, 91, 73, + 74, 75, 25, 71, 449, 77, 9, 100, 78, 102, + 101, 456, 73, 74, 75, 99, 70, 58, 59, 60, + 61, 73, 74, 75, 0, 100, 99, 101, 99, 19, + 466, 467, 101, 9, 454, 11, 12, 73, 74, 75, + 101, 486, 83, 84, 85, 86, 87, 12, 99, 101, + 99, 92, 98, 466, 95, 96, 97, 98, 503, 73, + 74, 75, 286, 39, 40, 41, 42, 73, 74, 75, + 46, 306, 48, 509, 92, 51, 531, 95, 96, 97, + 98, 526, 58, 59, 60, 61, 310, 101, 73, 74, + 75, 196, 497, 99, 33, 319, 376, 73, 74, 75, + 0, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 12, 81, 99, 58, 92, 60, 61, 95, + 96, 97, 98, 99, 245, 101, 443, 473, 104, 423, + 60, 61, 143, 474, -1, 73, 74, 75, 319, 39, + 40, 41, 42, 86, 87, 204, 46, -1, 48, 92, + -1, 51, 95, 96, 97, 98, 86, 87, 58, 59, + 60, 61, 92, 101, -1, 95, 96, 97, 98, 95, + 96, 97, 98, 73, 74, 75, -1, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 73, 74, + 75, -1, 92, -1, -1, 95, 96, 97, 98, 99, + -1, 101, 0, 1, 104, -1, -1, -1, -1, -1, + -1, 9, -1, 11, 99, 13, 14, 15, 16, 17, + -1, -1, 20, 21, 22, 23, 24, -1, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 73, 74, 75, 46, 47, + 48, 49, 50, -1, 52, 53, 54, 55, 56, 57, + 73, 74, 75, -1, 62, 63, 64, 65, 66, 67, + 68, 99, -1, 73, 74, 75, -1, -1, 76, -1, + -1, 73, 74, 75, -1, -1, 99, -1, -1, -1, + 88, 89, -1, 91, -1, 93, 94, 0, 1, 99, + -1, -1, 100, 101, 102, 103, 9, 99, 11, -1, + 13, 14, 15, 16, 17, -1, -1, 20, 21, 22, + 23, 24, -1, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + -1, -1, -1, 46, 47, 48, 49, 50, -1, 52, + 53, 54, 55, 56, 57, -1, -1, -1, -1, 62, + 63, 64, 65, 66, 67, 68, 87, -1, -1, -1, + -1, 92, -1, 76, 95, 96, 97, 98, 3, 4, + 5, 6, 7, 8, -1, 88, 89, -1, 91, -1, + 93, 94, -1, 1, -1, -1, -1, 100, 101, 102, + 103, 9, 10, 11, -1, 13, 14, 15, 16, 17, + -1, -1, 20, 21, 22, 23, 24, -1, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, -1, -1, -1, 46, 47, + 48, 49, 50, -1, 52, 53, 54, 55, 56, 57, + -1, -1, -1, -1, 62, 63, 64, 65, 66, 67, + 68, -1, -1, -1, -1, -1, -1, -1, 76, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 87, 88, -1, 90, -1, 92, 93, -1, 1, -1, - -1, -1, 99, 100, 101, 102, 9, 10, 11, -1, + 88, 89, -1, 91, -1, 93, 94, -1, 1, -1, + -1, -1, 100, 101, 102, 103, 9, 10, 11, -1, 13, 14, 15, 16, 17, -1, -1, 20, 21, 22, 23, 24, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - -1, -1, -1, 46, 47, 48, 49, -1, 51, 52, - 53, 54, 55, 56, -1, -1, -1, -1, 61, 62, - 63, 64, 65, 66, 67, -1, -1, -1, -1, -1, - -1, -1, 75, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 87, 88, -1, 90, -1, 92, - 93, -1, 1, -1, -1, -1, 99, 100, 101, 102, - 9, 10, 11, -1, 13, 14, 15, 16, 17, -1, - -1, 20, 21, 22, 23, 24, -1, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, -1, -1, -1, 46, 47, 48, - 49, -1, 51, 52, 53, 54, 55, 56, -1, -1, - -1, -1, 61, 62, 63, 64, 65, 66, 67, -1, - -1, -1, -1, -1, -1, -1, 75, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 87, 88, - -1, 90, -1, 92, 93, -1, 1, -1, -1, -1, - 99, 100, 101, 102, 9, 10, 11, -1, 13, 14, - 15, 16, 17, -1, -1, 20, 21, 22, 23, 24, - -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, -1, -1, - -1, 46, 47, 48, 49, -1, 51, 52, 53, 54, - 55, 56, -1, -1, -1, -1, 61, 62, 63, 64, - 65, 66, 67, -1, -1, -1, -1, -1, -1, -1, - 75, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 87, 88, -1, 90, -1, 92, 93, -1, - 1, -1, -1, -1, 99, 100, 101, 102, 9, -1, - 11, -1, 13, 14, 15, 16, 17, -1, -1, 20, - 21, 22, 23, 24, -1, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, -1, -1, -1, 46, 47, 48, 49, -1, - 51, 52, 53, 54, 55, 56, -1, -1, -1, -1, - 61, 62, 63, 64, 65, 66, 67, -1, -1, 70, - -1, -1, -1, -1, 75, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 87, 88, -1, 90, - -1, 92, 93, -1, 1, -1, -1, -1, 99, 100, - 101, 102, 9, -1, 11, -1, 13, 14, 15, 16, - 17, -1, -1, 20, 21, 22, 23, 24, -1, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, -1, -1, -1, 46, - 47, 48, 49, -1, 51, 52, 53, 54, 55, 56, - -1, -1, -1, -1, 61, 62, 63, 64, 65, 66, - 67, -1, -1, -1, -1, -1, -1, -1, 75, -1, + -1, -1, -1, 46, 47, 48, 49, 50, -1, 52, + 53, 54, 55, 56, 57, -1, -1, -1, -1, 62, + 63, 64, 65, 66, 67, 68, -1, -1, -1, -1, + -1, -1, -1, 76, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 88, 89, -1, 91, -1, + 93, 94, -1, 1, -1, -1, -1, 100, 101, 102, + 103, 9, 10, 11, -1, 13, 14, 15, 16, 17, + -1, -1, 20, 21, 22, 23, 24, -1, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, -1, -1, -1, 46, 47, + 48, 49, 50, -1, 52, 53, 54, 55, 56, 57, + -1, -1, -1, -1, 62, 63, 64, 65, 66, 67, + 68, -1, -1, -1, -1, -1, -1, -1, 76, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 87, 88, -1, 90, -1, 92, 93, -1, 1, -1, - -1, -1, 99, 100, 101, 102, 9, -1, 11, -1, + 88, 89, -1, 91, -1, 93, 94, -1, 1, -1, + -1, -1, 100, 101, 102, 103, 9, 10, 11, -1, 13, 14, 15, 16, 17, -1, -1, 20, 21, 22, 23, 24, -1, 26, 27, 28, 29, 30, 31, 32, - -1, 34, 35, 36, 37, 38, 39, 40, 41, 42, - -1, -1, -1, 46, 47, 48, 49, -1, 51, 52, - 53, 54, 55, 56, -1, -1, -1, -1, 61, 62, - 63, 64, 65, 66, 67, -1, -1, -1, -1, -1, - -1, -1, 75, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 87, 88, -1, 90, -1, 92, - 93, 1, -1, -1, -1, -1, 99, 100, 101, 102, - -1, 11, -1, 13, 14, 15, 16, 17, -1, -1, - 20, 21, 22, 23, 24, -1, 26, 27, 28, 29, - 30, 31, -1, -1, -1, -1, 36, -1, 50, -1, - -1, -1, -1, -1, -1, 57, 58, 59, 60, 49, - -1, -1, 52, 53, 54, 55, 56, -1, -1, -1, - -1, 61, 62, 63, 64, 65, 66, 67, 80, 81, - 82, 83, 84, 85, 86, 75, -1, -1, -1, 91, - -1, -1, 94, 95, 96, 97, -1, 87, 88, -1, - 90, -1, 92, 93, 1, -1, -1, -1, -1, 99, - 100, 101, 102, -1, 11, -1, 13, 14, 15, 16, - 17, -1, -1, 20, 21, 22, 23, 24, -1, 26, - 27, 28, 29, 30, 31, -1, -1, -1, -1, 36, - -1, -1, -1, -1, -1, -1, 57, 58, 59, 60, - -1, -1, 49, -1, -1, 52, 53, 54, 55, 56, - -1, -1, -1, -1, 61, 62, 63, 64, 65, 66, - 67, 82, 83, 84, 85, 86, -1, -1, 75, -1, - 91, -1, -1, 94, 95, 96, 97, -1, -1, -1, - 87, 88, -1, 90, -1, 92, 93, -1, -1, -1, - -1, 98, 99, -1, 101, 102, 9, -1, 11, -1, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + -1, -1, -1, 46, 47, 48, 49, 50, -1, 52, + 53, 54, 55, 56, 57, -1, -1, -1, -1, 62, + 63, 64, 65, 66, 67, 68, -1, -1, -1, -1, + -1, -1, -1, 76, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 88, 89, -1, 91, -1, + 93, 94, -1, 1, -1, -1, -1, 100, 101, 102, + 103, 9, 10, 11, -1, 13, 14, 15, 16, 17, + -1, -1, 20, 21, 22, 23, 24, -1, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, -1, -1, -1, 46, 47, + 48, 49, 50, -1, 52, 53, 54, 55, 56, 57, + -1, -1, -1, -1, 62, 63, 64, 65, 66, 67, + 68, -1, -1, -1, -1, -1, -1, -1, 76, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 88, 89, -1, 91, -1, 93, 94, -1, 1, -1, + -1, -1, 100, 101, 102, 103, 9, -1, 11, -1, 13, 14, 15, 16, 17, -1, -1, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, - -1, -1, -1, 36, -1, -1, -1, -1, -1, 57, - 58, 59, 60, -1, -1, -1, 49, -1, -1, 52, - 53, 54, 55, 56, -1, -1, -1, -1, 61, 62, - 63, 64, 65, 66, 67, 83, 84, 85, 86, -1, - -1, -1, 75, 91, -1, -1, 94, 95, 96, 97, - -1, -1, -1, -1, 87, 88, -1, 90, -1, 92, - 93, -1, -1, -1, -1, -1, 99, -1, 101, 102, - 9, -1, 11, -1, 13, 14, 15, 16, 17, -1, + 23, 24, -1, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + -1, -1, -1, 46, 47, 48, 49, 50, -1, 52, + 53, 54, 55, 56, 57, -1, -1, -1, -1, 62, + 63, 64, 65, 66, 67, 68, -1, -1, 71, -1, + -1, -1, -1, 76, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 88, 89, -1, 91, -1, + 93, 94, -1, 1, -1, -1, -1, 100, 101, 102, + 103, 9, -1, 11, -1, 13, 14, 15, 16, 17, + -1, -1, 20, 21, 22, 23, 24, -1, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, -1, -1, -1, 46, 47, + 48, 49, 50, -1, 52, 53, 54, 55, 56, 57, + -1, -1, -1, -1, 62, 63, 64, 65, 66, 67, + 68, -1, -1, -1, -1, -1, -1, -1, 76, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 88, 89, -1, 91, -1, 93, 94, -1, 1, -1, + -1, -1, 100, 101, 102, 103, 9, -1, 11, -1, + 13, 14, 15, 16, 17, -1, -1, 20, 21, 22, + 23, 24, -1, 26, 27, 28, 29, 30, 31, 32, + -1, 34, 35, 36, 37, 38, 39, 40, 41, 42, + -1, -1, -1, 46, 47, 48, 49, 50, -1, 52, + 53, 54, 55, 56, 57, -1, -1, -1, -1, 62, + 63, 64, 65, 66, 67, 68, -1, -1, -1, -1, + -1, -1, -1, 76, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 88, 89, -1, 91, -1, + 93, 94, 1, -1, -1, -1, -1, 100, 101, 102, + 103, -1, 11, -1, 13, 14, 15, 16, 17, -1, -1, 20, 21, 22, 23, 24, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, 36, -1, -1, - -1, -1, -1, 57, 58, 59, 60, -1, -1, -1, - 49, -1, -1, 52, 53, 54, 55, 56, -1, -1, - -1, -1, 61, 62, 63, 64, 65, 66, 67, -1, - 84, 85, 86, -1, -1, -1, 75, 91, -1, -1, - 94, 95, 96, 97, -1, -1, -1, -1, 87, 88, - -1, 90, -1, 92, 93, -1, -1, -1, -1, -1, - 99, -1, 101, 102, 11, 12, 13, 14, 15, 16, - 17, -1, -1, 20, 21, 22, 23, 24, -1, 26, - 27, 28, 29, 30, 31, -1, -1, -1, -1, 36, - -1, -1, -1, 57, 58, 59, 60, -1, -1, -1, - -1, -1, 49, -1, -1, 52, 53, 54, 55, 56, - -1, -1, -1, -1, 61, 62, 63, 64, 65, 66, - 67, 85, 86, -1, -1, -1, -1, 91, 75, -1, - 94, 95, 96, 97, -1, -1, -1, -1, -1, -1, - 87, 88, -1, 90, -1, 92, 93, -1, -1, -1, - -1, -1, 99, -1, 101, 102, 11, -1, 13, 14, + 51, -1, -1, -1, -1, -1, -1, 58, 59, 60, + 61, 50, -1, -1, 53, 54, 55, 56, 57, -1, + -1, -1, -1, 62, 63, 64, 65, 66, 67, 68, + 81, 82, 83, 84, 85, 86, 87, 76, -1, -1, + -1, 92, -1, -1, 95, 96, 97, 98, -1, 88, + 89, -1, 91, -1, 93, 94, 1, -1, -1, -1, + -1, 100, 101, 102, 103, -1, 11, -1, 13, 14, 15, 16, 17, -1, -1, 20, 21, 22, 23, 24, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, - -1, 36, -1, -1, -1, 57, 58, 59, 60, -1, - -1, -1, -1, -1, 49, -1, -1, 52, 53, 54, - 55, 56, -1, -1, -1, -1, 61, 62, 63, 64, - 65, 66, 67, 85, 86, -1, -1, -1, -1, 91, - 75, -1, 94, 95, 96, 97, -1, -1, -1, -1, - -1, -1, 87, 88, -1, 90, -1, 92, 93, -1, - -1, -1, -1, -1, 99, 100, 101, 102, 11, -1, + -1, 36, -1, -1, -1, -1, -1, -1, 58, 59, + 60, 61, -1, -1, -1, 50, -1, -1, 53, 54, + 55, 56, 57, -1, -1, -1, -1, 62, 63, 64, + 65, 66, 67, 68, 84, 85, 86, 87, -1, -1, + -1, 76, 92, -1, -1, 95, 96, 97, 98, -1, + -1, -1, -1, 88, 89, -1, 91, -1, 93, 94, + -1, -1, -1, -1, 99, 100, -1, 102, 103, 9, + -1, 11, -1, 13, 14, 15, 16, 17, -1, -1, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, -1, -1, -1, -1, 36, -1, -1, -1, + -1, -1, -1, 58, 59, 60, 61, -1, -1, -1, + 50, -1, -1, 53, 54, 55, 56, 57, -1, -1, + -1, -1, 62, 63, 64, 65, 66, 67, 68, -1, + 85, 86, 87, -1, -1, -1, 76, 92, -1, -1, + 95, 96, 97, 98, -1, -1, -1, -1, 88, 89, + -1, 91, -1, 93, 94, -1, -1, -1, -1, -1, + 100, -1, 102, 103, 9, -1, 11, -1, 13, 14, + 15, 16, 17, -1, -1, 20, 21, 22, 23, 24, + -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, + -1, 36, -1, -1, -1, -1, 58, 59, 60, 61, + -1, -1, -1, -1, -1, 50, -1, -1, 53, 54, + 55, 56, 57, -1, -1, -1, -1, 62, 63, 64, + 65, 66, 67, 68, 86, 87, -1, -1, -1, -1, + 92, 76, -1, 95, 96, 97, 98, -1, -1, -1, + -1, -1, -1, 88, 89, -1, 91, -1, 93, 94, + -1, -1, -1, -1, -1, 100, -1, 102, 103, 11, + 12, 13, 14, 15, 16, 17, -1, -1, 20, 21, + 22, 23, 24, -1, 26, 27, 28, 29, 30, 31, + -1, -1, -1, -1, 36, -1, -1, -1, -1, 58, + 59, 60, 61, -1, -1, -1, -1, -1, 50, -1, + -1, 53, 54, 55, 56, 57, -1, -1, -1, -1, + 62, 63, 64, 65, 66, 67, 68, 86, 87, -1, + -1, -1, -1, 92, 76, -1, 95, 96, 97, 98, + -1, -1, -1, -1, -1, -1, 88, 89, -1, 91, + -1, 93, 94, -1, -1, -1, -1, -1, 100, -1, + 102, 103, 11, -1, 13, 14, 15, 16, 17, -1, + -1, 20, 21, 22, 23, 24, -1, 26, 27, 28, + 29, 30, 31, -1, -1, -1, -1, 36, 39, 40, + 41, 42, -1, -1, -1, 46, -1, 48, -1, -1, + -1, 50, -1, -1, 53, 54, 55, 56, 57, -1, + -1, -1, -1, 62, 63, 64, 65, 66, 67, 68, + -1, -1, 73, 74, 75, -1, -1, 76, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 88, + 89, -1, 91, -1, 93, 94, -1, -1, -1, -1, + -1, 100, 101, 102, 103, 11, -1, 13, 14, 15, + 16, 17, -1, -1, 20, 21, 22, 23, 24, -1, + 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, + 36, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 50, -1, -1, 53, 54, 55, + 56, 57, -1, -1, -1, -1, 62, 63, 64, 65, + 66, 67, 68, -1, -1, -1, -1, -1, -1, -1, + 76, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 88, 89, -1, 91, -1, 93, 94, -1, + -1, -1, -1, 99, 100, -1, 102, 103, 11, -1, 13, 14, 15, 16, 17, -1, -1, 20, 21, 22, 23, 24, -1, 26, 27, 28, 29, 30, 31, -1, - -1, -1, -1, 36, 39, 40, 41, 42, -1, -1, - -1, 46, -1, 48, -1, -1, 49, -1, -1, 52, - 53, 54, 55, 56, -1, -1, -1, -1, 61, 62, - 63, 64, 65, 66, 67, -1, -1, 72, 73, 74, - -1, -1, 75, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 87, 88, -1, 90, -1, 92, - 93, -1, -1, -1, -1, 98, 99, -1, 101, 102, - 11, -1, 13, 14, 15, 16, 17, -1, -1, 20, - 21, 22, 23, 24, -1, 26, 27, 28, 29, 30, - 31, -1, -1, -1, -1, 36, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 49, -1, - -1, 52, 53, 54, 55, 56, -1, -1, -1, -1, - 61, 62, 63, 64, 65, 66, 67, -1, -1, -1, - -1, -1, -1, -1, 75, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 87, 88, -1, 90, - -1, 92, 93, -1, -1, -1, -1, 98, 99, -1, - 101, 102, 11, -1, 13, 14, 15, 16, 17, -1, - -1, 20, 21, 22, 23, 24, -1, 26, 27, 28, - 29, 30, 31, -1, -1, -1, -1, 36, -1, -1, + -1, -1, -1, 36, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 50, -1, -1, + 53, 54, 55, 56, 57, -1, -1, -1, -1, 62, + 63, 64, 65, 66, 67, 68, -1, -1, -1, -1, + -1, -1, -1, 76, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 88, 89, -1, 91, -1, + 93, 94, -1, -1, -1, -1, 99, 100, -1, 102, + 103, 11, -1, 13, 14, 15, 16, 17, -1, -1, + 20, 21, 22, 23, 24, -1, 26, 27, 28, 29, + 30, 31, -1, -1, -1, -1, 36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 49, -1, -1, 52, 53, 54, 55, 56, -1, -1, - -1, -1, 61, 62, 63, 64, 65, 66, 67, -1, - -1, -1, -1, -1, -1, -1, 75, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 87, 88, - -1, 90, -1, 92, 93, -1, -1, -1, -1, 98, - 99, -1, 101, 102, 11, -1, 13, 14, 15, 16, + 50, -1, -1, 53, 54, 55, 56, 57, -1, -1, + -1, -1, 62, 63, 64, 65, 66, 67, 68, -1, + -1, -1, -1, -1, -1, -1, 76, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 88, 89, + -1, 91, -1, 93, 94, -1, -1, -1, -1, 99, + 100, -1, 102, 103, 11, -1, 13, 14, 15, 16, 17, -1, -1, 20, 21, 22, 23, 24, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, 36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 49, -1, -1, 52, 53, 54, 55, 56, - -1, -1, -1, -1, 61, 62, 63, 64, 65, 66, - 67, -1, -1, -1, -1, -1, -1, -1, 75, -1, + -1, -1, -1, 50, -1, -1, 53, 54, 55, 56, + 57, -1, -1, -1, -1, 62, 63, 64, 65, 66, + 67, 68, -1, -1, -1, -1, -1, -1, -1, 76, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 87, 88, -1, 90, -1, 92, 93, -1, -1, -1, - -1, 98, 99, -1, 101, 102, 11, -1, 13, 14, - 15, 16, 17, -1, -1, 20, 21, 22, 23, 24, - -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, - -1, 36, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 49, -1, -1, 52, 53, 54, - 55, 56, -1, -1, -1, -1, 61, 62, 63, 64, - 65, 66, 67, -1, -1, -1, -1, -1, -1, -1, - 75, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 87, 88, -1, 90, -1, 92, 93, -1, - -1, -1, -1, 98, 99, -1, 101, 102, 11, -1, - 13, 14, 15, 16, 17, -1, -1, 20, 21, 22, - 23, 24, -1, 26, 27, 28, 29, 30, 31, -1, - -1, -1, -1, 36, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 49, -1, -1, 52, - 53, 54, 55, 56, -1, -1, -1, -1, 61, 62, - 63, 64, 65, 66, 67, -1, -1, -1, -1, -1, - -1, -1, 75, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 87, 88, -1, 90, -1, 92, - 93, -1, -1, -1, -1, 98, 99, -1, 101, 102, + -1, 88, 89, -1, 91, -1, 93, 94, -1, -1, + -1, -1, 99, 100, -1, 102, 103, 11, -1, 13, + 14, 15, 16, 17, -1, -1, 20, 21, 22, 23, + 24, -1, 26, 27, 28, 29, 30, 31, -1, -1, + -1, -1, 36, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 50, -1, -1, 53, + 54, 55, 56, 57, -1, -1, -1, -1, 62, 63, + 64, 65, 66, 67, 68, -1, -1, -1, -1, -1, + -1, -1, 76, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 88, 89, -1, 91, -1, 93, + 94, -1, -1, -1, -1, 99, 100, -1, 102, 103, 11, -1, 13, 14, 15, 16, 17, -1, -1, 20, 21, 22, 23, 24, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, 36, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 49, -1, - -1, 52, 53, 54, 55, 56, -1, -1, -1, -1, - 61, 62, 63, 64, 65, 66, 67, -1, -1, -1, - -1, -1, -1, -1, 75, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 87, 88, -1, 90, - -1, 92, 93, -1, -1, -1, -1, 98, 99, -1, - 101, 102, 11, -1, 13, 14, 15, 16, 17, -1, - -1, 20, 21, 22, 23, 24, -1, 26, 27, 28, - 29, 30, 31, -1, -1, -1, -1, 36, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, + -1, -1, 53, 54, 55, 56, 57, -1, -1, -1, + -1, 62, 63, 64, 65, 66, 67, 68, -1, -1, + -1, -1, -1, -1, -1, 76, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 88, 89, -1, + 91, -1, 93, 94, -1, -1, -1, -1, 99, 100, + -1, 102, 103, 11, -1, 13, 14, 15, 16, 17, + -1, -1, 20, 21, 22, 23, 24, -1, 26, 27, + 28, 29, 30, 31, -1, -1, -1, -1, 36, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 49, -1, -1, 52, 53, 54, 55, 56, -1, -1, - -1, -1, 61, 62, 63, 64, 65, 66, 67, -1, - -1, -1, -1, -1, -1, -1, 75, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 87, 88, - -1, 90, -1, 92, 93, -1, -1, -1, -1, -1, - 99, -1, 101, 102, 11, -1, 13, 14, 15, 16, - 17, -1, -1, 20, 21, 22, 23, 24, -1, 26, - 27, 28, 29, 30, 31, -1, -1, -1, -1, 36, + -1, -1, 50, -1, -1, 53, 54, 55, 56, 57, + -1, -1, -1, -1, 62, 63, 64, 65, 66, 67, + 68, -1, -1, -1, -1, -1, -1, -1, 76, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 49, -1, -1, 52, 53, 54, 55, 56, - -1, -1, -1, -1, 61, 62, 63, 64, 65, 66, - 67, -1, -1, -1, -1, -1, -1, -1, 75, 50, - -1, -1, -1, -1, -1, -1, 57, 58, 59, 60, - 87, 88, -1, 90, -1, 92, 93, -1, -1, -1, - -1, -1, 99, -1, 101, 102, 77, 78, -1, 80, - 81, 82, 83, 84, 85, 86, -1, -1, -1, -1, - 91, 50, -1, 94, 95, 96, 97, -1, 57, 58, - 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 78, - -1, 80, 81, 82, 83, 84, 85, 86, -1, -1, - -1, -1, 91, -1, -1, 94, 95, 96, 97 + 88, 89, -1, 91, -1, 93, 94, -1, -1, -1, + -1, 99, 100, -1, 102, 103, 11, -1, 13, 14, + 15, 16, 17, -1, -1, 20, 21, 22, 23, 24, + -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, + -1, 36, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 50, -1, -1, 53, 54, + 55, 56, 57, -1, -1, -1, -1, 62, 63, 64, + 65, 66, 67, 68, -1, -1, -1, -1, -1, -1, + -1, 76, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 88, 89, -1, 91, -1, 93, 94, + -1, -1, -1, -1, -1, 100, -1, 102, 103, 11, + -1, 13, 14, 15, 16, 17, -1, -1, 20, 21, + 22, 23, 24, -1, 26, 27, 28, 29, 30, 31, + -1, -1, -1, -1, 36, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 50, -1, + -1, 53, 54, 55, 56, 57, -1, -1, -1, -1, + 62, 63, 64, 65, 66, 67, 68, -1, -1, -1, + -1, -1, -1, -1, 76, 51, -1, -1, -1, -1, + -1, -1, 58, 59, 60, 61, 88, 89, -1, 91, + -1, 93, 94, -1, -1, -1, -1, -1, 100, -1, + 102, 103, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, -1, -1, -1, -1, 92, 51, -1, 95, + 96, 97, 98, -1, 58, 59, 60, 61, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 78, 79, -1, 81, 82, 83, + 84, 85, 86, 87, -1, -1, -1, -1, 92, 51, + -1, 95, 96, 97, 98, -1, 58, 59, 60, 61, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 79, -1, 81, + 82, 83, 84, 85, 86, 87, -1, -1, -1, -1, + 92, -1, -1, 95, 96, 97, 98 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 4, 5, 6, 7, 8, 105, 106, 107, - 108, 109, 110, 111, 0, 114, 11, 13, 14, 15, + 0, 3, 4, 5, 6, 7, 8, 106, 107, 108, + 109, 110, 111, 112, 0, 115, 11, 13, 14, 15, 16, 17, 20, 21, 22, 23, 24, 26, 27, 28, - 29, 30, 31, 36, 49, 52, 53, 54, 55, 56, - 61, 62, 63, 64, 65, 66, 67, 75, 87, 88, - 90, 92, 93, 99, 101, 102, 159, 160, 161, 164, - 165, 166, 167, 168, 169, 171, 174, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 9, 112, 1, 32, + 29, 30, 31, 36, 50, 53, 54, 55, 56, 57, + 62, 63, 64, 65, 66, 67, 68, 76, 88, 89, + 91, 93, 94, 100, 102, 103, 160, 161, 162, 165, + 166, 167, 168, 169, 170, 172, 175, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 9, 113, 1, 32, 34, 35, 37, 38, 39, 40, 41, 42, 46, 47, - 48, 51, 100, 112, 121, 131, 159, 33, 119, 120, - 121, 117, 117, 12, 159, 169, 169, 20, 25, 112, - 181, 189, 189, 189, 189, 189, 170, 11, 99, 169, - 142, 142, 169, 99, 99, 99, 112, 169, 20, 160, - 173, 181, 189, 189, 112, 169, 100, 159, 20, 25, - 144, 169, 90, 99, 172, 181, 182, 183, 169, 160, - 169, 169, 169, 169, 169, 98, 159, 189, 189, 72, - 73, 74, 76, 9, 11, 99, 50, 57, 58, 59, - 60, 77, 78, 80, 81, 82, 83, 84, 85, 86, - 91, 94, 95, 96, 97, 99, 9, 11, 9, 11, - 9, 11, 9, 114, 143, 144, 20, 141, 99, 99, - 99, 99, 66, 90, 99, 179, 181, 99, 99, 100, - 45, 133, 100, 39, 40, 41, 42, 46, 48, 120, - 121, 119, 12, 173, 99, 99, 159, 98, 112, 23, - 114, 145, 98, 98, 159, 174, 189, 160, 10, 100, - 173, 99, 169, 172, 181, 182, 183, 98, 159, 68, - 147, 11, 98, 159, 159, 159, 169, 159, 159, 98, - 159, 169, 169, 169, 169, 169, 169, 169, 169, 169, - 169, 169, 169, 169, 169, 169, 9, 11, 15, 16, - 17, 21, 61, 99, 101, 102, 163, 181, 98, 159, - 159, 159, 159, 159, 159, 159, 159, 117, 20, 140, - 141, 20, 124, 114, 114, 114, 114, 90, 114, 66, - 177, 178, 180, 181, 182, 183, 114, 114, 99, 114, - 114, 112, 159, 137, 159, 159, 159, 159, 159, 174, - 160, 12, 162, 99, 156, 68, 146, 98, 98, 159, - 10, 98, 159, 147, 98, 23, 159, 11, 100, 12, - 98, 79, 159, 159, 102, 102, 102, 102, 98, 159, - 102, 102, 99, 98, 100, 12, 100, 12, 100, 12, - 100, 10, 18, 113, 122, 123, 9, 100, 20, 136, - 159, 137, 138, 159, 138, 176, 181, 99, 131, 135, - 138, 139, 159, 177, 114, 138, 138, 98, 103, 175, - 173, 157, 146, 23, 112, 98, 98, 12, 159, 10, - 169, 100, 12, 98, 174, 10, 10, 10, 10, 114, - 145, 114, 114, 20, 98, 98, 98, 98, 99, 114, - 98, 100, 127, 138, 98, 98, 159, 98, 15, 16, - 101, 149, 150, 152, 153, 154, 155, 9, 12, 10, - 98, 100, 146, 156, 128, 173, 134, 134, 9, 115, - 115, 138, 138, 115, 125, 99, 98, 115, 115, 25, - 148, 148, 76, 98, 117, 70, 100, 112, 158, 146, - 117, 100, 115, 115, 116, 43, 44, 132, 132, 98, - 98, 133, 136, 138, 115, 77, 151, 151, 153, 10, - 118, 9, 10, 133, 133, 117, 115, 99, 115, 115, - 100, 98, 133, 169, 23, 100, 129, 117, 10, 138, - 133, 133, 126, 115, 69, 130, 19, 10, 98, 134, - 133, 117, 115, 139, 70, 132, 98, 115 + 48, 49, 52, 101, 113, 122, 132, 160, 33, 120, + 121, 122, 118, 118, 12, 160, 170, 170, 20, 25, + 113, 182, 190, 190, 190, 190, 190, 171, 11, 100, + 170, 143, 143, 170, 100, 100, 100, 113, 170, 20, + 161, 174, 182, 190, 190, 113, 170, 101, 160, 20, + 25, 145, 170, 91, 100, 173, 182, 183, 184, 170, + 161, 170, 170, 170, 170, 170, 99, 160, 190, 190, + 73, 74, 75, 77, 9, 11, 100, 51, 58, 59, + 60, 61, 78, 79, 81, 82, 83, 84, 85, 86, + 87, 92, 95, 96, 97, 98, 100, 9, 11, 9, + 11, 9, 11, 9, 115, 144, 145, 20, 142, 100, + 100, 100, 100, 67, 91, 100, 180, 182, 100, 100, + 113, 101, 45, 134, 101, 39, 40, 41, 42, 46, + 48, 121, 122, 120, 12, 174, 100, 100, 160, 99, + 113, 23, 115, 146, 99, 99, 160, 175, 190, 161, + 10, 101, 174, 100, 170, 173, 182, 183, 184, 99, + 160, 69, 148, 11, 99, 160, 160, 160, 170, 160, + 160, 99, 160, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 9, 11, + 15, 16, 17, 21, 62, 100, 102, 103, 164, 182, + 99, 160, 160, 160, 160, 160, 160, 160, 160, 118, + 20, 141, 142, 20, 125, 115, 115, 115, 115, 91, + 115, 67, 178, 179, 181, 182, 183, 184, 115, 115, + 100, 115, 115, 113, 160, 138, 160, 160, 160, 160, + 160, 175, 161, 12, 163, 100, 157, 69, 147, 99, + 99, 160, 10, 99, 160, 148, 99, 23, 160, 11, + 101, 12, 99, 80, 160, 160, 103, 103, 103, 103, + 99, 160, 103, 103, 100, 99, 101, 12, 101, 12, + 101, 12, 101, 10, 18, 114, 123, 124, 9, 101, + 20, 137, 160, 138, 139, 160, 139, 177, 182, 100, + 132, 136, 139, 140, 160, 178, 115, 139, 139, 99, + 104, 176, 174, 158, 147, 23, 113, 99, 99, 12, + 160, 10, 170, 101, 12, 99, 175, 10, 10, 10, + 10, 115, 146, 115, 115, 20, 99, 99, 99, 99, + 100, 115, 99, 101, 128, 139, 99, 99, 160, 99, + 15, 16, 102, 150, 151, 153, 154, 155, 156, 9, + 12, 10, 99, 101, 147, 157, 129, 174, 135, 135, + 9, 116, 116, 139, 139, 116, 126, 100, 99, 116, + 116, 25, 149, 149, 77, 99, 118, 71, 101, 113, + 159, 147, 118, 101, 116, 116, 117, 43, 44, 133, + 133, 99, 99, 134, 137, 139, 116, 78, 152, 152, + 154, 10, 119, 9, 10, 134, 134, 118, 116, 100, + 116, 116, 101, 99, 134, 170, 23, 101, 130, 118, + 10, 139, 134, 134, 127, 116, 70, 131, 19, 10, + 99, 135, 134, 118, 116, 140, 71, 133, 99, 116 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 104, 106, 105, 107, 105, 108, 105, 109, 105, - 110, 105, 111, 105, 112, 113, 114, 115, 116, 117, - 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, - 121, 123, 121, 121, 124, 121, 121, 121, 121, 121, - 121, 121, 125, 126, 121, 121, 121, 127, 121, 121, - 121, 121, 128, 121, 121, 121, 121, 129, 130, 130, - 131, 131, 131, 131, 131, 131, 131, 131, 132, 132, - 132, 133, 133, 134, 135, 135, 136, 136, 137, 138, - 139, 140, 140, 141, 142, 143, 144, 144, 145, 145, - 146, 146, 146, 147, 147, 148, 148, 149, 149, 150, - 151, 151, 151, 152, 153, 153, 154, 154, 154, 155, - 155, 157, 156, 158, 158, 159, 159, 159, 159, 160, - 160, 160, 161, 161, 161, 161, 161, 161, 161, 161, - 162, 161, 163, 163, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, - 165, 165, 166, 166, 166, 166, 166, 166, 166, 166, - 166, 167, 167, 167, 167, 167, 167, 168, 168, 169, - 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, - 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, - 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, - 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, - 169, 169, 169, 169, 169, 169, 169, 169, 170, 169, - 169, 169, 169, 171, 171, 171, 172, 172, 172, 172, - 172, 173, 173, 174, 174, 175, 175, 176, 177, 177, - 177, 178, 178, 179, 179, 180, 181, 182, 183, 184, - 184, 185, 186, 186, 187, 187, 188, 188, 189, 189, - 189, 189 + 0, 105, 107, 106, 108, 106, 109, 106, 110, 106, + 111, 106, 112, 106, 113, 114, 115, 116, 117, 118, + 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, + 122, 124, 122, 122, 125, 122, 122, 122, 122, 122, + 122, 122, 122, 126, 127, 122, 122, 122, 128, 122, + 122, 122, 122, 129, 122, 122, 122, 122, 130, 131, + 131, 132, 132, 132, 132, 132, 132, 132, 132, 133, + 133, 133, 134, 134, 135, 136, 136, 137, 137, 138, + 139, 140, 141, 141, 142, 143, 144, 145, 145, 146, + 146, 147, 147, 147, 148, 148, 149, 149, 150, 150, + 151, 152, 152, 152, 153, 154, 154, 155, 155, 155, + 156, 156, 158, 157, 159, 159, 160, 160, 160, 160, + 161, 161, 161, 162, 162, 162, 162, 162, 162, 162, + 162, 163, 162, 164, 164, 165, 165, 165, 165, 165, + 165, 165, 165, 165, 165, 165, 165, 165, 165, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 168, 168, 168, 168, 168, 168, 169, 169, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 171, + 170, 170, 170, 170, 172, 172, 172, 173, 173, 173, + 173, 173, 174, 174, 175, 175, 176, 176, 177, 178, + 178, 178, 179, 179, 180, 180, 181, 182, 183, 184, + 185, 185, 186, 187, 187, 188, 188, 189, 189, 190, + 190, 190, 190 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -1038,30 +1046,30 @@ static const yytype_uint8 yyr2[] = 0, 3, 0, 3, 4, 7, 0, 4, 0, 0, 2, 0, 2, 1, 1, 2, 2, 1, 4, 0, 7, 0, 10, 4, 0, 7, 7, 7, 6, 6, - 8, 8, 0, 0, 13, 9, 8, 0, 10, 9, - 7, 2, 0, 8, 2, 2, 1, 2, 0, 3, - 1, 1, 3, 3, 3, 3, 3, 3, 0, 2, - 6, 0, 2, 0, 0, 1, 0, 1, 1, 1, - 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, - 0, 2, 1, 2, 1, 0, 1, 1, 1, 3, - 0, 1, 2, 3, 1, 1, 2, 3, 1, 0, - 1, 0, 4, 1, 1, 3, 3, 3, 1, 2, - 3, 1, 3, 5, 6, 3, 3, 5, 2, 4, - 0, 5, 1, 1, 5, 4, 5, 4, 5, 6, - 5, 4, 5, 4, 3, 6, 4, 5, 3, 3, + 2, 8, 8, 0, 0, 13, 9, 8, 0, 10, + 9, 7, 2, 0, 8, 2, 2, 1, 2, 0, + 3, 1, 1, 3, 3, 3, 3, 3, 3, 0, + 2, 6, 0, 2, 0, 0, 1, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, + 1, 0, 2, 1, 2, 1, 0, 1, 1, 1, + 3, 0, 1, 2, 3, 1, 1, 2, 3, 1, + 0, 1, 0, 4, 1, 1, 3, 3, 3, 1, + 2, 3, 1, 3, 5, 6, 3, 3, 5, 2, + 4, 0, 5, 1, 1, 5, 4, 5, 4, 5, + 6, 5, 4, 5, 4, 3, 6, 4, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 3, 2, 4, 3, 5, 8, 2, 2, 1, - 1, 1, 1, 5, 2, 3, 1, 2, 3, 1, - 2, 1, 1, 1, 1, 1, 1, 4, 4, 5, - 5, 1, 1, 3, 4, 3, 4, 4, 4, 4, - 4, 1, 2, 2, 1, 2, 2, 1, 2, 1, - 2, 1, 3, 1, 3, 1, 3, 4, 0, 6, - 1, 1, 1, 3, 2, 4, 3, 2, 1, 1, - 1, 0, 1, 0, 1, 0, 2, 1, 1, 1, - 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, - 4, 2, 1, 3, 1, 3, 1, 3, 1, 1, - 1, 1 + 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 3, 2, 4, 3, 5, 8, 2, 2, + 1, 1, 1, 1, 5, 2, 3, 1, 2, 3, + 1, 2, 1, 1, 1, 1, 1, 1, 4, 4, + 5, 5, 1, 1, 3, 4, 3, 4, 4, 4, + 4, 4, 1, 2, 2, 1, 2, 2, 1, 2, + 1, 2, 1, 3, 1, 3, 1, 3, 4, 0, + 6, 1, 1, 1, 3, 2, 4, 3, 2, 1, + 1, 1, 0, 1, 0, 1, 0, 2, 1, 1, + 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 4, 2, 1, 3, 1, 3, 1, 3, 1, + 1, 1, 1 }; typedef enum { @@ -1079,7 +1087,7 @@ static const toketypes yy_type_tab[] = toketype_pval, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, - toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, + toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, @@ -1103,6 +1111,6 @@ static const toketypes yy_type_tab[] = }; /* Generated from: - * 1d0c087affbf85a8f1482eb4d34eefd435666c6d9e1cb4d7f9d1aeb62b37e907 perly.y + * 78f9e1daf948a161b43e7457943b7d91cada7c92c8b941a1c1dbbc23c2c10aa8 perly.y * b6fae5748f9bef6db4740aa5e122b84ac5181852d42474d0ecad621fa4253306 regen_perly.pl * ex: set ro: */ @@ -53,7 +53,7 @@ %token <pval> LABEL %token <ival> FORMAT SUB ANONSUB PACKAGE USE %token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR -%token <ival> GIVEN WHERESO +%token <ival> GIVEN WHEN DEFAULT %token <ival> LOOPEX DOTDOT YADAYADA %token <ival> FUNC0 FUNC1 FUNC UNIOP LSTOP %token <ival> RELOP EQOP MULOP ADDOP @@ -378,14 +378,10 @@ barestmt: PLUGSTMT $$ = block_end($3, newGIVENOP($4, op_scope($6), 0)); parser->copline = (line_t)$1; } - | WHERESO '(' remember mexpr ')' mblock - { - OP *cond = $4; - if ($1) - cond = newBINOP(OP_SMARTMATCH, 0, newDEFSVOP(), - scalar(cond)); - $$ = block_end($3, newWHERESOOP(cond, op_scope($6))); - } + | WHEN '(' remember mexpr ')' mblock + { $$ = block_end($3, newWHENOP($4, op_scope($6))); } + | DEFAULT block + { $$ = newWHENOP(0, op_scope($2)); } | WHILE '(' remember texpr ')' mintro mblock cont { $$ = block_end($3, @@ -537,14 +533,8 @@ sideff : error | expr FOR expr { $$ = newFOROP(0, NULL, $3, $1, NULL); parser->copline = (line_t)$2; } - | expr WHERESO expr - { - OP *cond = $3; - if ($2) - cond = newBINOP(OP_SMARTMATCH, 0, newDEFSVOP(), - scalar(cond)); - $$ = newWHERESOOP(cond, op_scope($1)); - } + | expr WHEN expr + { $$ = newWHENOP($3, op_scope($1)); } ; /* else and elsif blocks */ diff --git a/pod/perldiag.pod b/pod/perldiag.pod index c9779243f3..cca35e88bf 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -726,13 +726,6 @@ which makes no sense. Maybe you meant '%s', or just stringifying it? (F) C<caller> tried to set C<@DB::args>, but found it tied. Tying C<@DB::args> is not supported. (Before this error was added, it used to crash.) -=item Cannot smart match without a matcher object - -(F) You tried to perform a smart match (C<~~>), but the right hand operand -was not an object overloading the smart match operation. Such a matcher -object is required, in order to determine what kind of matching operation -to apply to the left hand operand. - =item Cannot tie unreifiable array (P) You somehow managed to call C<tie> on an array that does not @@ -759,6 +752,15 @@ to compress something else. See L<perlfunc/pack>. (F) Only hard references may be blessed. This is how Perl "enforces" encapsulation of objects. See L<perlobj>. +=item Can't "break" in a loop topicalizer + +(F) You called C<break>, but you're in a C<foreach> block rather than +a C<given> block. You probably meant to use C<next> or C<last>. + +=item Can't "break" outside a given block + +(F) You called C<break>, but you're not inside a C<given> block. + =item Can't call method "%s" on an undefined value (F) You used the syntax of a method call, but the slot filled by the @@ -822,10 +824,10 @@ You CAN say but then $foo no longer contains a glob. -=item Can't "continue" outside a whereso block +=item Can't "continue" outside a when block -(F) You called C<continue>, but you're not inside a C<whereis> or -C<whereso> block. +(F) You called C<continue>, but you're not inside a C<when> +or C<default> block. =item Can't create pipe mailbox @@ -837,6 +839,13 @@ quotas or other plumbing problems. (F) Only scalar, array, and hash variables may be declared as "my", "our" or "state" variables. They must have ordinary identifiers as names. +=item Can't "default" outside a topicalizer + +(F) You have used a C<default> block that is neither inside a +C<foreach> loop nor a C<given> block. (Note that this error is +issued on exit from the C<default> block, so you won't get the +error if you use an explicit C<continue>.) + =item Can't determine class of operator %s, assuming BASEOP (S) This warning indicates something wrong in the internals of perl. @@ -1082,17 +1091,6 @@ usually double the curlies to get the same effect though, because the inner curlies will be considered a block that loops once. See L<perlfunc/last>. -=item Can't leave "whereso" outside a loop block - -(F) Control reached the end of a C<whereis> or C<whereso> block that -isn't inside any loop (including a C<given> block). An implicit C<next> -occurs here, which requires a loop to jump to. You probably wanted the -C<whereis> or C<whereso> to be inside a C<given> block. Note that you -won't get this error if the match controlling the C<whereis> or C<whereso> -fails, or if you use an explicit C<continue> to avoid reaching the end -of the block. But if you rely on not reaching the implicit C<next> -then you probably didn't want C<whereis> or C<whereso>, but rather C<if>. - =item Can't linearize anonymous symbol table (F) Perl tried to calculate the method resolution order (MRO) of a @@ -1553,6 +1551,13 @@ instead. (F) You attempted to weaken something that was not a reference. Only references can be weakened. +=item Can't "when" outside a topicalizer + +(F) You have used a when() block that is neither inside a C<foreach> +loop nor a C<given> block. (Note that this error is issued on exit +from the C<when> block, so you won't get the error if the match fails, +or if you use an explicit C<continue>.) + =item Can't x= to read-only value (F) You tried to repeat a constant value (often the undefined value) @@ -2497,9 +2502,10 @@ L<perlfunc/getsockopt>. =item given is experimental -(S experimental::smartmatch) C<given> is experimental, and its behavior -may change or it may even be removed in any future release of perl. -See the explanation under L<perlsyn/Switch Statements>. +(S experimental::smartmatch) C<given> depends on smartmatch, which +is experimental, so its behavior may change or even be removed +in any future release of perl. See the explanation under +L<perlsyn/Experimental Details on given and when>. =item Global symbol "%s" requires explicit package name (did you forget to declare "my %s"?) @@ -5711,12 +5717,20 @@ requested. hash) parameter. The slurpy parameter takes all the available arguments, so there can't be any left to fill later parameters. +=item Smart matching a non-overloaded object breaks encapsulation + +(F) You should not use the C<~~> operator on an object that does not +overload it: Perl refuses to use the object's underlying structure +for the smart match. + =item Smartmatch is experimental (S experimental::smartmatch) This warning is emitted if you use the smartmatch (C<~~>) operator. This is currently an experimental feature, and its details are subject to change in future releases of -Perl. +Perl. Particularly, its current behavior is noticed for being +unnecessarily complex and unintuitive, and is very likely to be +overhauled. =item Sorry, hash keys must be smaller than 2**31 bytes @@ -7488,17 +7502,13 @@ but in actual fact, you got So put in parentheses to say what you really mean. -=item whereis is experimental - -(S experimental::smartmatch) C<whereis> is experimental, and its behavior -may change or it may even be removed in any future release of perl. -See the explanation under L<perlsyn/Switch Statements>. - -=item whereso is experimental +=item when is experimental -(S experimental::smartmatch) C<whereso> is experimental, and its behavior -may change or it may even be removed in any future release of perl. -See the explanation under L<perlsyn/Switch Statements>. +(S experimental::smartmatch) C<when> depends on smartmatch, which is +experimental. Additionally, it has several special cases that may +not be immediately obvious, and their behavior may change or +even be removed in any future release of perl. See the explanation +under L<perlsyn/Experimental Details on given and when>. =item Wide character in %s diff --git a/pod/perlexperiment.pod b/pod/perlexperiment.pod index 57be5886f4..3918080820 100644 --- a/pod/perlexperiment.pod +++ b/pod/perlexperiment.pod @@ -16,11 +16,11 @@ their inception, versions, etc. There's a lot of speculation here. =over 8 -=item Smart match (C<~~>) and switch (given/when) +=item Smart match (C<~~>) Introduced in Perl 5.10.0 -Modified in Perl 5.10.1, 5.12.0, 5.28.0 +Modified in Perl 5.10.1, 5.12.0 Using this feature triggers warnings in the category C<experimental::smartmatch>. @@ -28,10 +28,6 @@ C<experimental::smartmatch>. The ticket for this feature is 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<given>/C<whereis>/C<whereso>). - =item Pluggable keywords The ticket for this feature is diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod index 901d5c87e1..c13e533dd6 100644 --- a/pod/perlfunc.pod +++ b/pod/perlfunc.pod @@ -256,7 +256,7 @@ X<control flow> =for Pod::Functions =Flow -L<C<caller>|/caller EXPR>, +L<C<break>|/break>, L<C<caller>|/caller EXPR>, L<C<continue>|/continue BLOCK>, L<C<die>|/die LIST>, L<C<do>|/do BLOCK>, L<C<dump>|/dump LABEL>, L<C<eval>|/eval EXPR>, L<C<evalbytes>|/evalbytes EXPR>, L<C<exit>|/exit EXPR>, @@ -267,9 +267,16 @@ L<C<redo>|/redo LABEL>, L<C<return>|/return EXPR>, L<C<sub>|/sub NAME BLOCK>, L<C<__SUB__>|/__SUB__>, L<C<wantarray>|/wantarray> -In Perl v5.14 and earlier, L<C<continue>|/continue BLOCK> -required the L<C<"switch"> feature|feature/The 'switch' feature> to -be enabled. +L<C<break>|/break> is available only if you enable the experimental +L<C<"switch"> feature|feature/The 'switch' feature> or use the C<CORE::> +prefix. The L<C<"switch"> feature|feature/The 'switch' feature> also +enables the C<default>, C<given> and C<when> statements, which are +documented in L<perlsyn/"Switch Statements">. +The L<C<"switch"> feature|feature/The 'switch' feature> is enabled +automatically with a C<use v5.10> (or higher) declaration in the current +scope. In Perl v5.14 and earlier, L<C<continue>|/continue BLOCK> +required the L<C<"switch"> feature|feature/The 'switch' feature>, like +the other keywords. L<C<evalbytes>|/evalbytes EXPR> is only available with the L<C<"evalbytes"> feature|feature/The 'unicode_eval' and 'evalbytes' features> @@ -420,10 +427,10 @@ L<C<time>|/time>, L<C<times>|/times> =for Pod::Functions =!Non-functions C<and>, C<AUTOLOAD>, C<BEGIN>, C<CHECK>, C<cmp>, C<CORE>, C<__DATA__>, -C<DESTROY>, C<else>, C<elseif>, C<elsif>, C<END>, C<__END__>, +C<default>, C<DESTROY>, C<else>, C<elseif>, C<elsif>, C<END>, C<__END__>, C<eq>, C<for>, C<foreach>, C<ge>, C<given>, C<gt>, C<if>, C<INIT>, C<le>, -C<lt>, C<ne>, C<not>, C<or>, C<UNITCHECK>, C<unless>, C<until>, -C<whereis>, C<whereso>, C<while>, C<x>, C<xor> +C<lt>, C<ne>, C<not>, C<or>, C<UNITCHECK>, C<unless>, C<until>, C<when>, +C<while>, C<x>, C<xor> =back @@ -905,6 +912,19 @@ uses the result of L<C<ref>|/ref EXPR> as a truth value. See L<perlmod/"Perl Modules">. +=item break + +=for Pod::Functions +switch break out of a C<given> block + +Break out of a C<given> block. + +L<C<break>|/break> is available only if the +L<C<"switch"> feature|feature/The 'switch' feature> is enabled or if it +is prefixed with C<CORE::>. The +L<C<"switch"> feature|feature/The 'switch' feature> is enabled +automatically with a C<use v5.10> (or higher) declaration in the current +scope. + =item caller EXPR X<caller> X<call stack> X<stack> X<stack trace> @@ -1322,10 +1342,9 @@ using an empty one, logically enough, so L<C<next>|/next LABEL> goes directly back to check the condition at the top of the loop. When there is no BLOCK, L<C<continue>|/continue BLOCK> is a function -that exits the current C<whereis> or C<whereso> block, -avoiding the implicit C<next> -that happens when execution reaches the end of such a block. -In Perl 5.14 and earlier, this form of +that falls through the current C<when> or C<default> block instead of +iterating a dynamically enclosing C<foreach> or exiting a lexically +enclosing C<given>. In Perl 5.14 and earlier, this form of L<C<continue>|/continue BLOCK> was only available when the L<C<"switch"> feature|feature/The 'switch' feature> was enabled. See L<feature> and L<perlsyn/"Switch Statements"> for more information. @@ -3810,8 +3829,7 @@ value such as C<eval {}>, C<sub {}>, or C<do {}>, and should not be used to exit a L<C<grep>|/grep BLOCK LIST> or L<C<map>|/map BLOCK LIST> operation. -Note that a block by itself or a C<given> construct -is semantically identical to a loop +Note that a block by itself is semantically identical to a loop that executes once. Thus L<C<last>|/last LABEL> can be used to effect an early exit out of such a block. @@ -4341,8 +4359,7 @@ value such as C<eval {}>, C<sub {}>, or C<do {}>, and should not be used to exit a L<C<grep>|/grep BLOCK LIST> or L<C<map>|/map BLOCK LIST> operation. -Note that a block by itself or a C<given> construct -is semantically identical to a loop +Note that a block by itself is semantically identical to a loop that executes once. Thus L<C<next>|/next LABEL> will exit such a block early. @@ -6306,8 +6323,7 @@ value such as C<eval {}>, C<sub {}>, or C<do {}>, and should not be used to exit a L<C<grep>|/grep BLOCK LIST> or L<C<map>|/map BLOCK LIST> operation. -Note that a block by itself or a C<given> construct -is semantically identical to a loop +Note that a block by itself is semantically identical to a loop that executes once. Thus L<C<redo>|/redo LABEL> inside such a block will effectively turn it into a looping construct. @@ -10146,11 +10162,11 @@ Statements">. =over -=item given +=item default -=item whereis +=item given -=item whereso +=item when These flow-control keywords related to the experimental switch feature are documented in L<perlsyn/"Switch Statements">. diff --git a/pod/perlintro.pod b/pod/perlintro.pod index f0ab70adf1..5c168c18e1 100644 --- a/pod/perlintro.pod +++ b/pod/perlintro.pod @@ -326,8 +326,8 @@ running the program. Using C<strict> is highly recommended. =head2 Conditional and looping constructs -Perl has most of the usual conditional and looping constructs. -It even has a switch/case statement (spelled C<given>/C<whereso>). See +Perl has most of the usual conditional and looping constructs. As of Perl +5.10, it even has a case/switch statement (spelled C<given>/C<when>). See L<perlsyn/"Switch Statements"> for more details. The conditions can be any Perl expression. See the list of operators in diff --git a/pod/perlop.pod b/pod/perlop.pod index 82e9e753db..023353c12c 100644 --- a/pod/perlop.pod +++ b/pod/perlop.pod @@ -576,24 +576,288 @@ function, available in Perl v5.16 or later: =head2 Smartmatch Operator -Binary C<~~> does a "smartmatch" between its arguments. The smartmatch +First available in Perl 5.10.1 (the 5.10.0 version behaved differently), +binary C<~~> does a "smartmatch" between its arguments. This is mostly +used implicitly in the C<when> construct described in L<perlsyn>, although +not all C<when> clauses call the smartmatch operator. Unique among all of +Perl's operators, the smartmatch operator can recurse. The smartmatch operator is L<experimental|perlpolicy/experimental> and its behavior is -subject to change. It first became available in Perl 5.10, but prior -to Perl 5.28 its behaviour was quite different from its present behaviour. - -The C<~~> operator applies some kind of matching criterion to its -left-hand operand, and returns a truth value result. The criterion to -apply is determined by the right-hand operand, which must be a reference -to an object blessed into a class that overloads the C<~~> operator for -this purpose. The class into which compiled regexp objects are blessed -by the C<qr//> operator has such an overloading, which checks whether -the left-hand operand matches the regexp. If the right-hand operand is -not a reference to such a matcher object, an exception is raised. - -Overloading of C<~~> only applies when the object reference is the -right-hand operand. An object reference as the left-hand operand is -subjected to whatever criterion is specified by the right-hand operand, -regardless of its own overloading. +subject to change. + +It is also unique in that all other Perl operators impose a context +(usually string or numeric context) on their operands, autoconverting +those operands to those imposed contexts. In contrast, smartmatch +I<infers> contexts from the actual types of its operands and uses that +type information to select a suitable comparison mechanism. + +The C<~~> operator compares its operands "polymorphically", determining how +to compare them according to their actual types (numeric, string, array, +hash, etc.) Like the equality operators with which it shares the same +precedence, C<~~> returns 1 for true and C<""> for false. It is often best +read aloud as "in", "inside of", or "is contained in", because the left +operand is often looked for I<inside> the right operand. That makes the +order of the operands to the smartmatch operand often opposite that of +the regular match operator. In other words, the "smaller" thing is usually +placed in the left operand and the larger one in the right. + +The behavior of a smartmatch depends on what type of things its arguments +are, as determined by the following table. The first row of the table +whose types apply determines the smartmatch behavior. Because what +actually happens is mostly determined by the type of the second operand, +the table is sorted on the right operand instead of on the left. + + Left Right Description and pseudocode + =============================================================== + Any undef check whether Any is undefined + like: !defined Any + + Any Object invoke ~~ overloading on Object, or die + + Right operand is an ARRAY: + + Left Right Description and pseudocode + =============================================================== + ARRAY1 ARRAY2 recurse on paired elements of ARRAY1 and ARRAY2[2] + like: (ARRAY1[0] ~~ ARRAY2[0]) + && (ARRAY1[1] ~~ ARRAY2[1]) && ... + HASH ARRAY any ARRAY elements exist as HASH keys + like: grep { exists HASH->{$_} } ARRAY + Regexp ARRAY any ARRAY elements pattern match Regexp + like: grep { /Regexp/ } ARRAY + undef ARRAY undef in ARRAY + like: grep { !defined } ARRAY + Any ARRAY smartmatch each ARRAY element[3] + like: grep { Any ~~ $_ } ARRAY + + Right operand is a HASH: + + Left Right Description and pseudocode + =============================================================== + HASH1 HASH2 all same keys in both HASHes + like: keys HASH1 == + grep { exists HASH2->{$_} } keys HASH1 + ARRAY HASH any ARRAY elements exist as HASH keys + like: grep { exists HASH->{$_} } ARRAY + Regexp HASH any HASH keys pattern match Regexp + like: grep { /Regexp/ } keys HASH + undef HASH always false (undef can't be a key) + like: 0 == 1 + Any HASH HASH key existence + like: exists HASH->{Any} + + Right operand is CODE: + + Left Right Description and pseudocode + =============================================================== + ARRAY CODE sub returns true on all ARRAY elements[1] + like: !grep { !CODE->($_) } ARRAY + HASH CODE sub returns true on all HASH keys[1] + like: !grep { !CODE->($_) } keys HASH + Any CODE sub passed Any returns true + like: CODE->(Any) + +Right operand is a Regexp: + + Left Right Description and pseudocode + =============================================================== + ARRAY Regexp any ARRAY elements match Regexp + like: grep { /Regexp/ } ARRAY + HASH Regexp any HASH keys match Regexp + like: grep { /Regexp/ } keys HASH + Any Regexp pattern match + like: Any =~ /Regexp/ + + Other: + + Left Right Description and pseudocode + =============================================================== + Object Any invoke ~~ overloading on Object, + or fall back to... + + Any Num numeric equality + like: Any == Num + Num nummy[4] numeric equality + like: Num == nummy + undef Any check whether undefined + like: !defined(Any) + Any Any string equality + like: Any eq Any + + +Notes: + +=over + +=item 1. +Empty hashes or arrays match. + +=item 2. +That is, each element smartmatches the element of the same index in the other array.[3] + +=item 3. +If a circular reference is found, fall back to referential equality. + +=item 4. +Either an actual number, or a string that looks like one. + +=back + +The smartmatch implicitly dereferences any non-blessed hash or array +reference, so the C<I<HASH>> and C<I<ARRAY>> entries apply in those cases. +For blessed references, the C<I<Object>> entries apply. Smartmatches +involving hashes only consider hash keys, never hash values. + +The "like" code entry is not always an exact rendition. For example, the +smartmatch operator short-circuits whenever possible, but C<grep> does +not. Also, C<grep> in scalar context returns the number of matches, but +C<~~> returns only true or false. + +Unlike most operators, the smartmatch operator knows to treat C<undef> +specially: + + use v5.10.1; + @array = (1, 2, 3, undef, 4, 5); + say "some elements undefined" if undef ~~ @array; + +Each operand is considered in a modified scalar context, the modification +being that array and hash variables are passed by reference to the +operator, which implicitly dereferences them. Both elements +of each pair are the same: + + use v5.10.1; + + my %hash = (red => 1, blue => 2, green => 3, + orange => 4, yellow => 5, purple => 6, + black => 7, grey => 8, white => 9); + + my @array = qw(red blue green); + + say "some array elements in hash keys" if @array ~~ %hash; + say "some array elements in hash keys" if \@array ~~ \%hash; + + say "red in array" if "red" ~~ @array; + say "red in array" if "red" ~~ \@array; + + say "some keys end in e" if /e$/ ~~ %hash; + say "some keys end in e" if /e$/ ~~ \%hash; + +Two arrays smartmatch if each element in the first array smartmatches +(that is, is "in") the corresponding element in the second array, +recursively. + + use v5.10.1; + my @little = qw(red blue green); + my @bigger = ("red", "blue", [ "orange", "green" ] ); + if (@little ~~ @bigger) { # true! + say "little is contained in bigger"; + } + +Because the smartmatch operator recurses on nested arrays, this +will still report that "red" is in the array. + + use v5.10.1; + my @array = qw(red blue green); + my $nested_array = [[[[[[[ @array ]]]]]]]; + say "red in array" if "red" ~~ $nested_array; + +If two arrays smartmatch each other, then they are deep +copies of each others' values, as this example reports: + + use v5.12.0; + my @a = (0, 1, 2, [3, [4, 5], 6], 7); + my @b = (0, 1, 2, [3, [4, 5], 6], 7); + + if (@a ~~ @b && @b ~~ @a) { + say "a and b are deep copies of each other"; + } + elsif (@a ~~ @b) { + say "a smartmatches in b"; + } + elsif (@b ~~ @a) { + say "b smartmatches in a"; + } + else { + say "a and b don't smartmatch each other at all"; + } + + +If you were to set S<C<$b[3] = 4>>, then instead of reporting that "a and b +are deep copies of each other", it now reports that C<"b smartmatches in a">. +That's because the corresponding position in C<@a> contains an array that +(eventually) has a 4 in it. + +Smartmatching one hash against another reports whether both contain the +same keys, no more and no less. This could be used to see whether two +records have the same field names, without caring what values those fields +might have. For example: + + use v5.10.1; + sub make_dogtag { + state $REQUIRED_FIELDS = { name=>1, rank=>1, serial_num=>1 }; + + my ($class, $init_fields) = @_; + + die "Must supply (only) name, rank, and serial number" + unless $init_fields ~~ $REQUIRED_FIELDS; + + ... + } + +However, this only does what you mean if C<$init_fields> is indeed a hash +reference. The condition C<$init_fields ~~ $REQUIRED_FIELDS> also allows the +strings C<"name">, C<"rank">, C<"serial_num"> as well as any array reference +that contains C<"name"> or C<"rank"> or C<"serial_num"> anywhere to pass +through. + +The smartmatch operator is most often used as the implicit operator of a +C<when> clause. See the section on "Switch Statements" in L<perlsyn>. + +=head3 Smartmatching of Objects + +To avoid relying on an object's underlying representation, if the +smartmatch's right operand is an object that doesn't overload C<~~>, +it raises the exception "C<Smartmatching a non-overloaded object +breaks encapsulation>". That's because one has no business digging +around to see whether something is "in" an object. These are all +illegal on objects without a C<~~> overload: + + %hash ~~ $object + 42 ~~ $object + "fred" ~~ $object + +However, you can change the way an object is smartmatched by overloading +the C<~~> operator. This is allowed to +extend the usual smartmatch semantics. +For objects that do have an C<~~> overload, see L<overload>. + +Using an object as the left operand is allowed, although not very useful. +Smartmatching rules take precedence over overloading, so even if the +object in the left operand has smartmatch overloading, this will be +ignored. A left operand that is a non-overloaded object falls back on a +string or numeric comparison of whatever the C<ref> operator returns. That +means that + + $object ~~ X + +does I<not> invoke the overload method with C<I<X>> as an argument. +Instead the above table is consulted as normal, and based on the type of +C<I<X>>, overloading may or may not be invoked. For simple strings or +numbers, "in" becomes equivalent to this: + + $object ~~ $number ref($object) == $number + $object ~~ $string ref($object) eq $string + +For example, this reports that the handle smells IOish +(but please don't really do this!): + + use IO::Handle; + my $fh = IO::Handle->new(); + if ($fh ~~ /\bIO\b/) { + say "handle smells IOish"; + } + +That's because it treats C<$fh> as a string like +C<"IO::Handle=GLOB(0x8039e0)">, then pattern matches against that. =head2 Bitwise And X<operator, bitwise, and> X<bitwise and> X<&> diff --git a/pod/perlrun.pod b/pod/perlrun.pod index 20080dbf03..a50ebe2944 100644 --- a/pod/perlrun.pod +++ b/pod/perlrun.pod @@ -419,6 +419,7 @@ B<-D14> is equivalent to B<-Dtls>): 4194304 A Consistency checks on internal structures 8388608 q quiet - currently only suppresses the "EXECUTING" message + 16777216 M trace smart match resolution 33554432 B dump suBroutine definitions, including special Blocks like BEGIN 67108864 L trace Locale-related info; what gets output is very diff --git a/pod/perlsyn.pod b/pod/perlsyn.pod index a081242c97..74e228d5d8 100644 --- a/pod/perlsyn.pod +++ b/pod/perlsyn.pod @@ -118,7 +118,7 @@ as the last item in a statement. =head2 Statement Modifiers X<statement modifier> X<modifier> X<if> X<unless> X<while> -X<until> X<whereis> X<whereso> X<foreach> X<for> +X<until> X<when> X<foreach> X<for> Any simple statement may optionally be followed by a I<SINGLE> modifier, just before the terminating semicolon (or block ending). The possible @@ -130,8 +130,7 @@ modifiers are: until EXPR for LIST foreach LIST - whereis EXPR - whereso EXPR + when EXPR The C<EXPR> following the modifier is referred to as the "condition". Its truth or falsehood determines how the modifier will behave. @@ -214,15 +213,18 @@ it. Future versions of perl might do something different from the version of perl you try it out on. Here be dragons. X<my> -The C<whereis> and C<whereso> modifiers are an experimental feature -that first appeared with this spelling in Perl 5.28. To use them, you -should include a C<use feature 'switch'> declaration, or a declaration -that implies it. They behave like the full C<whereis> or C<whereso> -statement with block, described in L</"Switch Statements"> below. -They executes the statement only if the I<EXPR> is true for C<whereso>, -or C<$_> smartmatches the I<EXPR> for C<whereis>. If the statement -executes, control then implicitly jumps to the end of the dynamically -enclosing loop (usually a C<given> block). +The C<when> modifier is an experimental feature that first appeared in Perl +5.14. To use it, you should include a C<use v5.14> declaration. +(Technically, it requires only the C<switch> feature, but that aspect of it +was not available before 5.14.) Operative only from within a C<foreach> +loop or a C<given> block, it executes the statement only if the smartmatch +C<< $_ ~~ I<EXPR> >> is true. If the statement executes, it is followed by +a C<next> from inside a C<foreach> and C<break> from inside a C<given>. + +Under the current implementation, the C<foreach> loop can be +anywhere within the C<when> modifier's dynamic scope, but must be +within the C<given> block's lexical scope. This restriction may +be relaxed in a future release. See L</"Switch Statements"> below. =head2 Compound Statements X<statement, compound> X<block> X<bracket, curly> X<curly bracket> X<brace> @@ -258,9 +260,6 @@ The following compound statements may be used to control flow: given (EXPR) BLOCK - whereis (EXPR) BLOCK - whereso (EXPR) BLOCK - LABEL while (EXPR) BLOCK LABEL while (EXPR) BLOCK continue BLOCK @@ -280,9 +279,8 @@ The following compound statements may be used to control flow: PHASE BLOCK -The experimental C<given>, C<whereis>, and C<whereso> statements are I<not -automatically enabled>; see L</"Switch Statements"> below for how to do -so, and the attendant caveats. +The experimental C<given> statement is I<not automatically enabled>; see +L</"Switch Statements"> below for how to do so, and the attendant caveats. Unlike in C and Pascal, in Perl these are all defined in terms of BLOCKs, not statements. This means that the curly brackets are I<required>--no @@ -610,8 +608,8 @@ The BLOCK construct can be used to emulate case structures. $nothing = 1; } -You'll also find the C<foreach> loop used to establish a topic for -a switch: +You'll also find that C<foreach> loop used to create a topicalizer +and a switch: SWITCH: for ($var) { @@ -623,126 +621,96 @@ a switch: Such constructs are quite frequently used, both because older versions of Perl had no official C<switch> statement, and also because the new version -described immediately below remains experimental. +described immediately below remains experimental and can sometimes be confusing. =head2 Switch Statements -X<switch> X<case> X<given> X<whereis> X<whereso> +X<switch> X<case> X<given> X<when> X<default> -C<given>, C<whereso>, and related keywords make up an experimental feature -that first appeared in Perl 5.10, but behaved quite differently from -its present form prior to Perl 5.28. To use it, you should declare +Starting from Perl 5.10.1 (well, 5.10.0, but it didn't work +right), you can say use feature "switch"; -You also get the switch feature whenever you declare that your +to enable an experimental switch feature. This is loosely based on an +old version of a Perl 6 proposal, but it no longer resembles the Perl 6 +construct. You also get the switch feature whenever you declare that your code prefers to run under a version of Perl that is 5.10 or later. For example: use v5.14; -Under the "switch" feature, Perl gains the experimental keywords C<given>, -C<whereis>, and C<whereso>. Starting from Perl 5.16, one can -prefix the switch keywords with C<CORE::> to access the feature without -a C<use feature> statement. - -The "switch" feature is considered highly experimental; it is subject -to change with little notice. Uses of the C<given>, C<whereis>, and -C<whereso> 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<given> and C<whereis> or C<whereso> -are analogous to C<switch> and C<case> -in C. They're meant to be used together, but can actually be used -independently and mixed with other kinds of compound statement. - -C<given> evaluates its argument in scalar context, and executes its block -with the C<$_> variable locally aliased to the result of evaluating the -argument expression. It is much like a C<foreach> loop that always has -exactly one item to iterate over. -A C<given> construct even counts as a one-iteration loop for the purposes -of loop control, so the C<redo> operator can be used to restart its block, -and C<next> or C<last> can be used to exit the block early. - -C<whereso> evaluates its argument as a truth value. If the argument -was false then it does not execute its block, and proceeds to the -following statement. If the argument was true, it executes the block, -then implicitly performs a C<next>, jumping to the end of the closest -dynamically enclosing C<given> block or other kind of loop. - -C<whereis> 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<next>, -jumping to the end of the closest dynamically enclosing C<given> block -or other kind of loop. This is exactly like C<whereso>, except for the -implicit use of smartmatch. - -Putting this together, the code in the previous section could be -rewritten as +Under the "switch" feature, Perl gains the experimental keywords +C<given>, C<when>, C<default>, C<continue>, and C<break>. +Starting from Perl 5.16, one can prefix the switch +keywords with C<CORE::> to access the feature without a C<use feature> +statement. The keywords C<given> and +C<when> are analogous to C<switch> and +C<case> in other languages -- though C<continue> is not -- so the code +in the previous section could be rewritten as use v5.10.1; - given ($var) { - whereso (/^abc/) { $abc = 1 } - whereso (/^def/) { $def = 1 } - whereso (/^xyz/) { $xyz = 1 } - $nothing = 1; + for ($var) { + when (/^abc/) { $abc = 1 } + when (/^def/) { $def = 1 } + when (/^xyz/) { $xyz = 1 } + default { $nothing = 1 } } -Or if you prefer the modifier form of C<whereso>, it can be written with -less punctuation as +The C<foreach> is the non-experimental way to set a topicalizer. +If you wish to use the highly experimental C<given>, that could be +written like this: - use v5.14; + use v5.10.1; given ($var) { - $abc = 1 whereso /^abc/; - $def = 1 whereso /^def/; - $xyz = 1 whereso /^xyz/; - $nothing = 1; + when (/^abc/) { $abc = 1 } + when (/^def/) { $def = 1 } + when (/^xyz/) { $xyz = 1 } + default { $nothing = 1 } } -You can use the C<continue> keyword to exit a C<whereis> or C<whereso> -block, proceeding to the following statement. This is most commonly -done last thing inside the block, to override the implicit C<next>. -For example +As of 5.14, that can also be written this way: - given($foo) { - whereso (/x/) { say '$foo contains an x'; continue } - whereso (/y/) { say '$foo contains a y' } - say '$foo does not contain a y'; + use v5.14; + for ($var) { + $abc = 1 when /^abc/; + $def = 1 when /^def/; + $xyz = 1 when /^xyz/; + default { $nothing = 1 } } -When a C<given> statement is executed in a position where it will provide -a value, for example when it's the last statement of a subroutine and -so providing the subroutine's return value, it evaluates to: +Or if you don't care to play it safe, like this: -=over 4 - -=item * - -An empty list as soon as an explicit C<next> or C<last> is encountered. - -=item * - -The value of the last evaluated expression of the successful -C<whereis> or C<whereso> clause, if there happens to be one. - -=item * - -The value of the last evaluated expression of the C<given> block if no -condition is true. - -=back - -In both last cases, the last expression is evaluated in the context that -was applied to the C<given> block. -Note that, unlike C<if> and C<unless>, -failed C<whereis>/C<whereso> statements always -evaluate to an empty list. + use v5.14; + given ($var) { + $abc = 1 when /^abc/; + $def = 1 when /^def/; + $xyz = 1 when /^xyz/; + default { $nothing = 1 } + } -On versions of Perl preceding Perl 5.28, C<given> and the related keywords -behave quite differently from their present behaviour. If your code needs -to run on older versions, avoid C<given>, C<whereis>, and C<whereso>. +The arguments to C<given> and C<when> are in scalar context, +and C<given> assigns the C<$_> variable its topic value. + +Exactly what the I<EXPR> argument to C<when> does is hard to describe +precisely, but in general, it tries to guess what you want done. Sometimes +it is interpreted as C<< $_ ~~ I<EXPR> >>, and sometimes it is not. It +also behaves differently when lexically enclosed by a C<given> block than +it does when dynamically enclosed by a C<foreach> loop. The rules are far +too difficult to understand to be described here. See L</"Experimental Details +on given and when"> later on. + +Due to an unfortunate bug in how C<given> was implemented between Perl 5.10 +and 5.16, under those implementations the version of C<$_> governed by +C<given> is merely a lexically scoped copy of the original, not a +dynamically scoped alias to the original, as it would be if it were a +C<foreach> or under both the original and the current Perl 6 language +specification. This bug was fixed in Perl 5.18 (and lexicalized C<$_> itself +was removed in Perl 5.24). + +If your code still needs to run on older versions, +stick to C<foreach> for your topicalizer and +you will be less unhappy. =head2 Goto X<goto> @@ -953,4 +921,335 @@ shell: __END__ foo at goop line 345. +=head2 Experimental Details on given and when + +As previously mentioned, the "switch" feature is considered highly +experimental; it is subject to change with little notice. In particular, +C<when> has tricky behaviours that are expected to change to become less +tricky in the future. Do not rely upon its current (mis)implementation. +Before Perl 5.18, C<given> also had tricky behaviours that you should still +beware of if your code must run on older versions of Perl. + +Here is a longer example of C<given>: + + use feature ":5.10"; + given ($foo) { + when (undef) { + say '$foo is undefined'; + } + when ("foo") { + say '$foo is the string "foo"'; + } + when ([1,3,5,7,9]) { + say '$foo is an odd digit'; + continue; # Fall through + } + when ($_ < 100) { + say '$foo is numerically less than 100'; + } + when (\&complicated_check) { + say 'a complicated check for $foo is true'; + } + default { + die q(I don't know what to do with $foo); + } + } + +Before Perl 5.18, C<given(EXPR)> assigned the value of I<EXPR> to +merely a lexically scoped I<B<copy>> (!) of C<$_>, not a dynamically +scoped alias the way C<foreach> does. That made it similar to + + do { my $_ = EXPR; ... } + +except that the block was automatically broken out of by a successful +C<when> or an explicit C<break>. Because it was only a copy, and because +it was only lexically scoped, not dynamically scoped, you could not do the +things with it that you are used to in a C<foreach> loop. In particular, +it did not work for arbitrary function calls if those functions might try +to access $_. Best stick to C<foreach> for that. + +Most of the power comes from the implicit smartmatching that can +sometimes apply. Most of the time, C<when(EXPR)> is treated as an +implicit smartmatch of C<$_>, that is, C<$_ ~~ EXPR>. (See +L<perlop/"Smartmatch Operator"> for more information on smartmatching.) +But when I<EXPR> is one of the 10 exceptional cases (or things like them) +listed below, it is used directly as a boolean. + +=over 4 + +=item Z<>1. + +A user-defined subroutine call or a method invocation. + +=item Z<>2. + +A regular expression match in the form of C</REGEX/>, C<$foo =~ /REGEX/>, +or C<$foo =~ EXPR>. Also, a negated regular expression match in +the form C<!/REGEX/>, C<$foo !~ /REGEX/>, or C<$foo !~ EXPR>. + +=item Z<>3. + +A smart match that uses an explicit C<~~> operator, such as C<EXPR ~~ EXPR>. + +B<NOTE:> You will often have to use C<$c ~~ $_> because the default case +uses C<$_ ~~ $c> , which is frequentlythe opposite of what you want. + +=item Z<>4. + +A boolean comparison operator such as C<$_ E<lt> 10> or C<$x eq "abc">. The +relational operators that this applies to are the six numeric comparisons +(C<< < >>, C<< > >>, C<< <= >>, C<< >= >>, C<< == >>, and C<< != >>), and +the six string comparisons (C<lt>, C<gt>, C<le>, C<ge>, C<eq>, and C<ne>). + +=item Z<>5. + +At least the three builtin functions C<defined(...)>, C<exists(...)>, and +C<eof(...)>. We might someday add more of these later if we think of them. + +=item Z<>6. + +A negated expression, whether C<!(EXPR)> or C<not(EXPR)>, or a logical +exclusive-or, C<(EXPR1) xor (EXPR2)>. The bitwise versions (C<~> and C<^>) +are not included. + +=item Z<>7. + +A filetest operator, with exactly 4 exceptions: C<-s>, C<-M>, C<-A>, and +C<-C>, as these return numerical values, not boolean ones. The C<-z> +filetest operator is not included in the exception list. + +=item Z<>8. + +The C<..> and C<...> flip-flop operators. Note that the C<...> flip-flop +operator is completely different from the C<...> elliptical statement +just described. + +=back + +In those 8 cases above, the value of EXPR is used directly as a boolean, so +no smartmatching is done. You may think of C<when> as a smartsmartmatch. + +Furthermore, Perl inspects the operands of logical operators to +decide whether to use smartmatching for each one by applying the +above test to the operands: + +=over 4 + +=item Z<>9. + +If EXPR is C<EXPR1 && EXPR2> or C<EXPR1 and EXPR2>, the test is applied +I<recursively> to both EXPR1 and EXPR2. +Only if I<both> operands also pass the +test, I<recursively>, will the expression be treated as boolean. Otherwise, +smartmatching is used. + +=item Z<>10. + +If EXPR is C<EXPR1 || EXPR2>, C<EXPR1 // EXPR2>, or C<EXPR1 or EXPR2>, the +test is applied I<recursively> to EXPR1 only (which might itself be a +higher-precedence AND operator, for example, and thus subject to the +previous rule), not to EXPR2. If EXPR1 is to use smartmatching, then EXPR2 +also does so, no matter what EXPR2 contains. But if EXPR2 does not get to +use smartmatching, then the second argument will not be either. This is +quite different from the C<&&> case just described, so be careful. + +=back + +These rules are complicated, but the goal is for them to do what you want +(even if you don't quite understand why they are doing it). For example: + + when (/^\d+$/ && $_ < 75) { ... } + +will be treated as a boolean match because the rules say both +a regex match and an explicit test on C<$_> will be treated +as boolean. + +Also: + + when ([qw(foo bar)] && /baz/) { ... } + +will use smartmatching because only I<one> of the operands is a boolean: +the other uses smartmatching, and that wins. + +Further: + + when ([qw(foo bar)] || /^baz/) { ... } + +will use smart matching (only the first operand is considered), whereas + + when (/^baz/ || [qw(foo bar)]) { ... } + +will test only the regex, which causes both operands to be +treated as boolean. Watch out for this one, then, because an +arrayref is always a true value, which makes it effectively +redundant. Not a good idea. + +Tautologous boolean operators are still going to be optimized +away. Don't be tempted to write + + when ("foo" or "bar") { ... } + +This will optimize down to C<"foo">, so C<"bar"> will never be considered (even +though the rules say to use a smartmatch +on C<"foo">). For an alternation like +this, an array ref will work, because this will instigate smartmatching: + + when ([qw(foo bar)] { ... } + +This is somewhat equivalent to the C-style switch statement's fallthrough +functionality (not to be confused with I<Perl's> fallthrough +functionality--see below), wherein the same block is used for several +C<case> statements. + +Another useful shortcut is that, if you use a literal array or hash as the +argument to C<given>, it is turned into a reference. So C<given(@foo)> is +the same as C<given(\@foo)>, for example. + +C<default> behaves exactly like C<when(1 == 1)>, which is +to say that it always matches. + +=head3 Breaking out + +You can use the C<break> keyword to break out of the enclosing +C<given> block. Every C<when> block is implicitly ended with +a C<break>. + +=head3 Fall-through + +You can use the C<continue> keyword to fall through from one +case to the next immediate C<when> or C<default>: + + given($foo) { + when (/x/) { say '$foo contains an x'; continue } + when (/y/) { say '$foo contains a y' } + default { say '$foo does not contain a y' } + } + +=head3 Return value + +When a C<given> statement is also a valid expression (for example, +when it's the last statement of a block), it evaluates to: + +=over 4 + +=item * + +An empty list as soon as an explicit C<break> is encountered. + +=item * + +The value of the last evaluated expression of the successful +C<when>/C<default> clause, if there happens to be one. + +=item * + +The value of the last evaluated expression of the C<given> block if no +condition is true. + +=back + +In both last cases, the last expression is evaluated in the context that +was applied to the C<given> block. + +Note that, unlike C<if> and C<unless>, failed C<when> statements always +evaluate to an empty list. + + my $price = do { + given ($item) { + when (["pear", "apple"]) { 1 } + break when "vote"; # My vote cannot be bought + 1e10 when /Mona Lisa/; + "unknown"; + } + }; + +Currently, C<given> blocks can't always +be used as proper expressions. This +may be addressed in a future version of Perl. + +=head3 Switching in a loop + +Instead of using C<given()>, you can use a C<foreach()> loop. +For example, here's one way to count how many times a particular +string occurs in an array: + + use v5.10.1; + my $count = 0; + for (@array) { + when ("foo") { ++$count } + } + print "\@array contains $count copies of 'foo'\n"; + +Or in a more recent version: + + use v5.14; + my $count = 0; + for (@array) { + ++$count when "foo"; + } + print "\@array contains $count copies of 'foo'\n"; + +At the end of all C<when> blocks, there is an implicit C<next>. +You can override that with an explicit C<last> if you're +interested in only the first match alone. + +This doesn't work if you explicitly specify a loop variable, as +in C<for $item (@array)>. You have to use the default variable C<$_>. + +=head3 Differences from Perl 6 + +The Perl 5 smartmatch and C<given>/C<when> constructs are not compatible +with their Perl 6 analogues. The most visible difference and least +important difference is that, in Perl 5, parentheses are required around +the argument to C<given()> and C<when()> (except when this last one is used +as a statement modifier). Parentheses in Perl 6 are always optional in a +control construct such as C<if()>, C<while()>, or C<when()>; they can't be +made optional in Perl 5 without a great deal of potential confusion, +because Perl 5 would parse the expression + + given $foo { + ... + } + +as though the argument to C<given> were an element of the hash +C<%foo>, interpreting the braces as hash-element syntax. + +However, their are many, many other differences. For example, +this works in Perl 5: + + use v5.12; + my @primary = ("red", "blue", "green"); + + if (@primary ~~ "red") { + say "primary smartmatches red"; + } + + if ("red" ~~ @primary) { + say "red smartmatches primary"; + } + + say "that's all, folks!"; + +But it doesn't work at all in Perl 6. Instead, you should +use the (parallelizable) C<any> operator: + + if any(@primary) eq "red" { + say "primary smartmatches red"; + } + + if "red" eq any(@primary) { + say "red smartmatches primary"; + } + +The table of smartmatches in L<perlop/"Smartmatch Operator"> is not +identical to that proposed by the Perl 6 specification, mainly due to +differences between Perl 6's and Perl 5's data models, but also because +the Perl 6 spec has changed since Perl 5 rushed into early adoption. + +In Perl 6, C<when()> will always do an implicit smartmatch with its +argument, while in Perl 5 it is convenient (albeit potentially confusing) to +suppress this implicit smartmatch in various rather loosely-defined +situations, as roughly outlined above. (The difference is largely because +Perl 5 does not have, even internally, a boolean type.) + =cut diff --git a/pod/perltrap.pod b/pod/perltrap.pod index 7830b72fc7..acb43925d1 100644 --- a/pod/perltrap.pod +++ b/pod/perltrap.pod @@ -170,9 +170,8 @@ C<do { } while> construct. See L<perlsyn/"Loop Control">. =item * -The switch statement is called C<given>/C<whereso> and only available -in its current form in perl 5.28 or newer. See L<perlsyn/"Switch -Statements">. +The switch statement is called C<given>/C<when> and only available in +perl 5.10 or newer. See L<perlsyn/"Switch Statements">. =item * @@ -1285,9 +1285,9 @@ PP(pp_flop) static const char * const context_name[] = { "pseudo-block", - NULL, /* CXt_WHERESO never actually needs "block" */ + NULL, /* CXt_WHEN never actually needs "block" */ NULL, /* CXt_BLOCK never actually needs "block" */ - NULL, /* CXt_LOOP_GIVEN never actually needs "block" */ + NULL, /* CXt_GIVEN never actually needs "block" */ NULL, /* CXt_LOOP_PLAIN never actually needs "loop" */ NULL, /* CXt_LOOP_LAZYIV never actually needs "loop" */ NULL, /* CXt_LOOP_LAZYSV never actually needs "loop" */ @@ -1320,7 +1320,6 @@ S_dopoptolabel(pTHX_ const char *label, STRLEN len, U32 flags) if (CxTYPE(cx) == CXt_NULL) /* sort BLOCK */ return -1; break; - case CXt_LOOP_GIVEN: case CXt_LOOP_PLAIN: case CXt_LOOP_LAZYIV: case CXt_LOOP_LAZYSV: @@ -1469,7 +1468,6 @@ S_dopoptoloop(pTHX_ I32 startingblock) if ((CxTYPE(cx)) == CXt_NULL) /* sort BLOCK */ return -1; break; - case CXt_LOOP_GIVEN: case CXt_LOOP_PLAIN: case CXt_LOOP_LAZYIV: case CXt_LOOP_LAZYSV: @@ -1482,8 +1480,38 @@ S_dopoptoloop(pTHX_ I32 startingblock) return i; } +/* find the next GIVEN or FOR (with implicit $_) loop context block */ + +STATIC I32 +S_dopoptogivenfor(pTHX_ I32 startingblock) +{ + I32 i; + for (i = startingblock; i >= 0; i--) { + const PERL_CONTEXT *cx = &cxstack[i]; + switch (CxTYPE(cx)) { + default: + continue; + case CXt_GIVEN: + DEBUG_l( Perl_deb(aTHX_ "(dopoptogivenfor(): found given at cx=%ld)\n", (long)i)); + return i; + case CXt_LOOP_PLAIN: + assert(!(cx->cx_type & CXp_FOR_DEF)); + break; + case CXt_LOOP_LAZYIV: + case CXt_LOOP_LAZYSV: + case CXt_LOOP_LIST: + case CXt_LOOP_ARY: + if (cx->cx_type & CXp_FOR_DEF) { + DEBUG_l( Perl_deb(aTHX_ "(dopoptogivenfor(): found foreach at cx=%ld)\n", (long)i)); + return i; + } + } + } + return i; +} + STATIC I32 -S_dopoptowhereso(pTHX_ I32 startingblock) +S_dopoptowhen(pTHX_ I32 startingblock) { I32 i; for (i = startingblock; i >= 0; i--) { @@ -1491,8 +1519,8 @@ S_dopoptowhereso(pTHX_ I32 startingblock) switch (CxTYPE(cx)) { default: continue; - case CXt_WHERESO: - DEBUG_l( Perl_deb(aTHX_ "(dopoptowhereso(): found whereso at cx=%ld)\n", (long)i)); + case CXt_WHEN: + DEBUG_l( Perl_deb(aTHX_ "(dopoptowhen(): found when at cx=%ld)\n", (long)i)); return i; } } @@ -1536,7 +1564,6 @@ Perl_dounwind(pTHX_ I32 cxix) case CXt_EVAL: cx_popeval(cx); break; - case CXt_LOOP_GIVEN: case CXt_LOOP_PLAIN: case CXt_LOOP_LAZYIV: case CXt_LOOP_LAZYSV: @@ -1544,8 +1571,11 @@ Perl_dounwind(pTHX_ I32 cxix) case CXt_LOOP_ARY: cx_poploop(cx); break; - case CXt_WHERESO: - cx_popwhereso(cx); + case CXt_WHEN: + cx_popwhen(cx); + break; + case CXt_GIVEN: + cx_popgiven(cx); break; case CXt_BLOCK: case CXt_NULL: @@ -2160,6 +2190,8 @@ PP(pp_enteriter) itersave = GvSV(sv); SvREFCNT_inc_simple_void(itersave); cxflags = CXp_FOR_GV; + if (PL_op->op_private & OPpITER_DEF) + cxflags |= CXp_FOR_DEF; } else { /* LV ref: for \$foo (...) */ assert(SvTYPE(sv) == SVt_PVMG); @@ -2169,6 +2201,8 @@ PP(pp_enteriter) cxflags = CXp_FOR_LVREF; } } + /* OPpITER_DEF (implicit $_) should only occur with a GV iter var */ + assert((cxflags & CXp_FOR_GV) || !(PL_op->op_private & OPpITER_DEF)); /* Note that this context is initially set as CXt_NULL. Further on * down it's changed to one of the CXt_LOOP_*. Before it's changed, @@ -2624,7 +2658,8 @@ S_dofindlabel(pTHX_ OP *o, const char *label, STRLEN len, U32 flags, OP **opstac o->op_type == OP_SCOPE || o->op_type == OP_LEAVELOOP || o->op_type == OP_LEAVESUB || - o->op_type == OP_LEAVETRY) + o->op_type == OP_LEAVETRY || + o->op_type == OP_LEAVEGIVEN) { *ops++ = cUNOPo->op_first; if (ops >= oplimit) @@ -2970,8 +3005,8 @@ PP(pp_goto) case CXt_LOOP_LAZYSV: case CXt_LOOP_LIST: case CXt_LOOP_ARY: - case CXt_LOOP_GIVEN: - case CXt_WHERESO: + case CXt_GIVEN: + case CXt_WHEN: gotoprobe = OpSIBLING(cx->blk_oldcop); break; case CXt_SUBST: @@ -4577,34 +4612,572 @@ PP(pp_entergiven) assert(!PL_op->op_targ); /* used to be set for lexical $_ */ GvSV(PL_defgv) = SvREFCNT_inc(newsv); - cx = cx_pushblock(CXt_LOOP_GIVEN|CXp_FOR_GV, gimme, SP, PL_savestack_ix); - cx_pushloop_given(cx, origsv); + cx = cx_pushblock(CXt_GIVEN, gimme, SP, PL_savestack_ix); + cx_pushgiven(cx, origsv); RETURN; } +PP(pp_leavegiven) +{ + PERL_CONTEXT *cx; + U8 gimme; + SV **oldsp; + PERL_UNUSED_CONTEXT; + + cx = CX_CUR(); + assert(CxTYPE(cx) == CXt_GIVEN); + oldsp = PL_stack_base + cx->blk_oldsp; + gimme = cx->blk_gimme; + + if (gimme == G_VOID) + PL_stack_sp = oldsp; + else + leave_adjust_stacks(oldsp, oldsp, gimme, 1); + + CX_LEAVE_SCOPE(cx); + cx_popgiven(cx); + cx_popblock(cx); + CX_POP(cx); + + return NORMAL; +} + +/* Helper routines used by pp_smartmatch */ +STATIC PMOP * +S_make_matcher(pTHX_ REGEXP *re) +{ + PMOP *matcher = (PMOP *) newPMOP(OP_MATCH, OPf_WANT_SCALAR | OPf_STACKED); + + PERL_ARGS_ASSERT_MAKE_MATCHER; + + PM_SETRE(matcher, ReREFCNT_inc(re)); + + SAVEFREEOP((OP *) matcher); + ENTER_with_name("matcher"); SAVETMPS; + SAVEOP(); + return matcher; +} + +STATIC bool +S_matcher_matches_sv(pTHX_ PMOP *matcher, SV *sv) +{ + dSP; + bool result; + + PERL_ARGS_ASSERT_MATCHER_MATCHES_SV; + + PL_op = (OP *) matcher; + XPUSHs(sv); + PUTBACK; + (void) Perl_pp_match(aTHX); + SPAGAIN; + result = SvTRUEx(POPs); + PUTBACK; + + return result; +} + +STATIC void +S_destroy_matcher(pTHX_ PMOP *matcher) +{ + PERL_ARGS_ASSERT_DESTROY_MATCHER; + PERL_UNUSED_ARG(matcher); + + FREETMPS; + LEAVE_with_name("matcher"); +} + +/* Do a smart match */ PP(pp_smartmatch) { + DEBUG_M(Perl_deb(aTHX_ "Starting smart match resolution\n")); + return do_smartmatch(NULL, NULL, 0); +} + +/* This version of do_smartmatch() implements the + * table of smart matches that is found in perlsyn. + */ +STATIC OP * +S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other, const bool copied) +{ dSP; - SV *right = POPs; - SV *left = TOPs; - SV *result; + + bool object_on_left = FALSE; + SV *e = TOPs; /* e is for 'expression' */ + SV *d = TOPm1s; /* d is for 'default', as in PL_defgv */ + + /* Take care only to invoke mg_get() once for each argument. + * Currently we do this by copying the SV if it's magical. */ + if (d) { + if (!copied && SvGMAGICAL(d)) + d = sv_mortalcopy(d); + } + else + d = &PL_sv_undef; + + assert(e); + if (SvGMAGICAL(e)) + e = sv_mortalcopy(e); + + /* First of all, handle overload magic of the rightmost argument */ + if (SvAMAGIC(e)) { + SV * tmpsv; + DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Object\n")); + DEBUG_M(Perl_deb(aTHX_ " attempting overload\n")); + tmpsv = amagic_call(d, e, smart_amg, AMGf_noleft); + if (tmpsv) { + SPAGAIN; + (void)POPs; + SETs(tmpsv); + RETURN; + } + DEBUG_M(Perl_deb(aTHX_ " failed to run overload method; continuing...\n")); + } + + SP -= 2; /* Pop the values */ PUTBACK; - if (SvGMAGICAL(left)) - left = sv_mortalcopy(left); - if (SvGMAGICAL(right)) - right = sv_mortalcopy(right); - if (SvAMAGIC(right) && - (result = amagic_call(left, right, smart_amg, AMGf_noleft))) { + + /* ~~ undef */ + if (!SvOK(e)) { + DEBUG_M(Perl_deb(aTHX_ " applying rule Any-undef\n")); + if (SvOK(d)) + RETPUSHNO; + else + RETPUSHYES; + } + + if (SvROK(e) && SvOBJECT(SvRV(e)) && (SvTYPE(SvRV(e)) != SVt_REGEXP)) { + DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Object\n")); + Perl_croak(aTHX_ "Smart matching a non-overloaded object breaks encapsulation"); + } + if (SvROK(d) && SvOBJECT(SvRV(d)) && (SvTYPE(SvRV(d)) != SVt_REGEXP)) + object_on_left = TRUE; + + /* ~~ sub */ + if (SvROK(e) && SvTYPE(SvRV(e)) == SVt_PVCV) { + I32 c; + if (object_on_left) { + goto sm_any_sub; /* Treat objects like scalars */ + } + else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVHV) { + /* Test sub truth for each key */ + HE *he; + bool andedresults = TRUE; + HV *hv = (HV*) SvRV(d); + I32 numkeys = hv_iterinit(hv); + DEBUG_M(Perl_deb(aTHX_ " applying rule Hash-CodeRef\n")); + if (numkeys == 0) + RETPUSHYES; + while ( (he = hv_iternext(hv)) ) { + DEBUG_M(Perl_deb(aTHX_ " testing hash key...\n")); + ENTER_with_name("smartmatch_hash_key_test"); + SAVETMPS; + PUSHMARK(SP); + PUSHs(hv_iterkeysv(he)); + PUTBACK; + c = call_sv(e, G_SCALAR); + SPAGAIN; + if (c == 0) + andedresults = FALSE; + else + andedresults = SvTRUEx(POPs) && andedresults; + FREETMPS; + LEAVE_with_name("smartmatch_hash_key_test"); + } + if (andedresults) + RETPUSHYES; + else + RETPUSHNO; + } + else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVAV) { + /* Test sub truth for each element */ + SSize_t i; + bool andedresults = TRUE; + AV *av = (AV*) SvRV(d); + const I32 len = av_tindex(av); + DEBUG_M(Perl_deb(aTHX_ " applying rule Array-CodeRef\n")); + if (len == -1) + RETPUSHYES; + for (i = 0; i <= len; ++i) { + SV * const * const svp = av_fetch(av, i, FALSE); + DEBUG_M(Perl_deb(aTHX_ " testing array element...\n")); + ENTER_with_name("smartmatch_array_elem_test"); + SAVETMPS; + PUSHMARK(SP); + if (svp) + PUSHs(*svp); + PUTBACK; + c = call_sv(e, G_SCALAR); + SPAGAIN; + if (c == 0) + andedresults = FALSE; + else + andedresults = SvTRUEx(POPs) && andedresults; + FREETMPS; + LEAVE_with_name("smartmatch_array_elem_test"); + } + if (andedresults) + RETPUSHYES; + else + RETPUSHNO; + } + else { + sm_any_sub: + DEBUG_M(Perl_deb(aTHX_ " applying rule Any-CodeRef\n")); + ENTER_with_name("smartmatch_coderef"); + SAVETMPS; + PUSHMARK(SP); + PUSHs(d); + PUTBACK; + c = call_sv(e, G_SCALAR); + SPAGAIN; + if (c == 0) + PUSHs(&PL_sv_no); + else if (SvTEMP(TOPs)) + SvREFCNT_inc_void(TOPs); + FREETMPS; + LEAVE_with_name("smartmatch_coderef"); + RETURN; + } + } + /* ~~ %hash */ + else if (SvROK(e) && SvTYPE(SvRV(e)) == SVt_PVHV) { + if (object_on_left) { + goto sm_any_hash; /* Treat objects like scalars */ + } + else if (!SvOK(d)) { + DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Hash ($a undef)\n")); + RETPUSHNO; + } + else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVHV) { + /* Check that the key-sets are identical */ + HE *he; + HV *other_hv = MUTABLE_HV(SvRV(d)); + bool tied; + bool other_tied; + U32 this_key_count = 0, + other_key_count = 0; + HV *hv = MUTABLE_HV(SvRV(e)); + + DEBUG_M(Perl_deb(aTHX_ " applying rule Hash-Hash\n")); + /* Tied hashes don't know how many keys they have. */ + tied = cBOOL(SvTIED_mg((SV*)hv, PERL_MAGIC_tied)); + other_tied = cBOOL(SvTIED_mg((const SV *)other_hv, PERL_MAGIC_tied)); + if (!tied ) { + if(other_tied) { + /* swap HV sides */ + HV * const temp = other_hv; + other_hv = hv; + hv = temp; + tied = TRUE; + other_tied = FALSE; + } + else if(HvUSEDKEYS((const HV *) hv) != HvUSEDKEYS(other_hv)) + RETPUSHNO; + } + + /* The hashes have the same number of keys, so it suffices + to check that one is a subset of the other. */ + (void) hv_iterinit(hv); + while ( (he = hv_iternext(hv)) ) { + SV *key = hv_iterkeysv(he); + + DEBUG_M(Perl_deb(aTHX_ " comparing hash key...\n")); + ++ this_key_count; + + if(!hv_exists_ent(other_hv, key, 0)) { + (void) hv_iterinit(hv); /* reset iterator */ + RETPUSHNO; + } + } + + if (other_tied) { + (void) hv_iterinit(other_hv); + while ( hv_iternext(other_hv) ) + ++other_key_count; + } + else + other_key_count = HvUSEDKEYS(other_hv); + + if (this_key_count != other_key_count) + RETPUSHNO; + else + RETPUSHYES; + } + else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVAV) { + AV * const other_av = MUTABLE_AV(SvRV(d)); + const SSize_t other_len = av_tindex(other_av) + 1; + SSize_t i; + HV *hv = MUTABLE_HV(SvRV(e)); + + DEBUG_M(Perl_deb(aTHX_ " applying rule Array-Hash\n")); + for (i = 0; i < other_len; ++i) { + SV ** const svp = av_fetch(other_av, i, FALSE); + DEBUG_M(Perl_deb(aTHX_ " checking for key existence...\n")); + if (svp) { /* ??? When can this not happen? */ + if (hv_exists_ent(hv, *svp, 0)) + RETPUSHYES; + } + } + RETPUSHNO; + } + else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_REGEXP) { + DEBUG_M(Perl_deb(aTHX_ " applying rule Regex-Hash\n")); + sm_regex_hash: + { + PMOP * const matcher = make_matcher((REGEXP*) SvRV(d)); + HE *he; + HV *hv = MUTABLE_HV(SvRV(e)); + + (void) hv_iterinit(hv); + while ( (he = hv_iternext(hv)) ) { + DEBUG_M(Perl_deb(aTHX_ " testing key against pattern...\n")); + PUTBACK; + if (matcher_matches_sv(matcher, hv_iterkeysv(he))) { + SPAGAIN; + (void) hv_iterinit(hv); + destroy_matcher(matcher); + RETPUSHYES; + } + SPAGAIN; + } + destroy_matcher(matcher); + RETPUSHNO; + } + } + else { + sm_any_hash: + DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Hash\n")); + if (hv_exists_ent(MUTABLE_HV(SvRV(e)), d, 0)) + RETPUSHYES; + else + RETPUSHNO; + } + } + /* ~~ @array */ + else if (SvROK(e) && SvTYPE(SvRV(e)) == SVt_PVAV) { + if (object_on_left) { + goto sm_any_array; /* Treat objects like scalars */ + } + else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVHV) { + AV * const other_av = MUTABLE_AV(SvRV(e)); + const SSize_t other_len = av_tindex(other_av) + 1; + SSize_t i; + + DEBUG_M(Perl_deb(aTHX_ " applying rule Hash-Array\n")); + for (i = 0; i < other_len; ++i) { + SV ** const svp = av_fetch(other_av, i, FALSE); + + DEBUG_M(Perl_deb(aTHX_ " testing for key existence...\n")); + if (svp) { /* ??? When can this not happen? */ + if (hv_exists_ent(MUTABLE_HV(SvRV(d)), *svp, 0)) + RETPUSHYES; + } + } + RETPUSHNO; + } + if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVAV) { + AV *other_av = MUTABLE_AV(SvRV(d)); + DEBUG_M(Perl_deb(aTHX_ " applying rule Array-Array\n")); + if (av_tindex(MUTABLE_AV(SvRV(e))) != av_tindex(other_av)) + RETPUSHNO; + else { + SSize_t i; + const SSize_t other_len = av_tindex(other_av); + + if (NULL == seen_this) { + seen_this = newHV(); + (void) sv_2mortal(MUTABLE_SV(seen_this)); + } + if (NULL == seen_other) { + seen_other = newHV(); + (void) sv_2mortal(MUTABLE_SV(seen_other)); + } + for(i = 0; i <= other_len; ++i) { + SV * const * const this_elem = av_fetch(MUTABLE_AV(SvRV(e)), i, FALSE); + SV * const * const other_elem = av_fetch(other_av, i, FALSE); + + if (!this_elem || !other_elem) { + if ((this_elem && SvOK(*this_elem)) + || (other_elem && SvOK(*other_elem))) + RETPUSHNO; + } + else if (hv_exists_ent(seen_this, + sv_2mortal(newSViv(PTR2IV(*this_elem))), 0) || + hv_exists_ent(seen_other, + sv_2mortal(newSViv(PTR2IV(*other_elem))), 0)) + { + if (*this_elem != *other_elem) + RETPUSHNO; + } + else { + (void)hv_store_ent(seen_this, + sv_2mortal(newSViv(PTR2IV(*this_elem))), + &PL_sv_undef, 0); + (void)hv_store_ent(seen_other, + sv_2mortal(newSViv(PTR2IV(*other_elem))), + &PL_sv_undef, 0); + PUSHs(*other_elem); + PUSHs(*this_elem); + + PUTBACK; + DEBUG_M(Perl_deb(aTHX_ " recursively comparing array element...\n")); + (void) do_smartmatch(seen_this, seen_other, 0); + SPAGAIN; + DEBUG_M(Perl_deb(aTHX_ " recursion finished\n")); + + if (!SvTRUEx(POPs)) + RETPUSHNO; + } + } + RETPUSHYES; + } + } + else if (SvROK(d) && SvTYPE(SvRV(d)) == SVt_REGEXP) { + DEBUG_M(Perl_deb(aTHX_ " applying rule Regex-Array\n")); + sm_regex_array: + { + PMOP * const matcher = make_matcher((REGEXP*) SvRV(d)); + const SSize_t this_len = av_tindex(MUTABLE_AV(SvRV(e))); + SSize_t i; + + for(i = 0; i <= this_len; ++i) { + SV * const * const svp = av_fetch(MUTABLE_AV(SvRV(e)), i, FALSE); + DEBUG_M(Perl_deb(aTHX_ " testing element against pattern...\n")); + PUTBACK; + if (svp && matcher_matches_sv(matcher, *svp)) { + SPAGAIN; + destroy_matcher(matcher); + RETPUSHYES; + } + SPAGAIN; + } + destroy_matcher(matcher); + RETPUSHNO; + } + } + else if (!SvOK(d)) { + /* undef ~~ array */ + const SSize_t this_len = av_tindex(MUTABLE_AV(SvRV(e))); + SSize_t i; + + DEBUG_M(Perl_deb(aTHX_ " applying rule Undef-Array\n")); + for (i = 0; i <= this_len; ++i) { + SV * const * const svp = av_fetch(MUTABLE_AV(SvRV(e)), i, FALSE); + DEBUG_M(Perl_deb(aTHX_ " testing for undef element...\n")); + if (!svp || !SvOK(*svp)) + RETPUSHYES; + } + RETPUSHNO; + } + else { + sm_any_array: + { + SSize_t i; + const SSize_t this_len = av_tindex(MUTABLE_AV(SvRV(e))); + + DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Array\n")); + for (i = 0; i <= this_len; ++i) { + SV * const * const svp = av_fetch(MUTABLE_AV(SvRV(e)), i, FALSE); + if (!svp) + continue; + + PUSHs(d); + PUSHs(*svp); + PUTBACK; + /* infinite recursion isn't supposed to happen here */ + DEBUG_M(Perl_deb(aTHX_ " recursively testing array element...\n")); + (void) do_smartmatch(NULL, NULL, 1); + SPAGAIN; + DEBUG_M(Perl_deb(aTHX_ " recursion finished\n")); + if (SvTRUEx(POPs)) + RETPUSHYES; + } + RETPUSHNO; + } + } + } + /* ~~ qr// */ + else if (SvROK(e) && SvTYPE(SvRV(e)) == SVt_REGEXP) { + if (!object_on_left && SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVHV) { + SV *t = d; d = e; e = t; + DEBUG_M(Perl_deb(aTHX_ " applying rule Hash-Regex\n")); + goto sm_regex_hash; + } + else if (!object_on_left && SvROK(d) && SvTYPE(SvRV(d)) == SVt_PVAV) { + SV *t = d; d = e; e = t; + DEBUG_M(Perl_deb(aTHX_ " applying rule Array-Regex\n")); + goto sm_regex_array; + } + else { + PMOP * const matcher = make_matcher((REGEXP*) SvRV(e)); + bool result; + + DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Regex\n")); + PUTBACK; + result = matcher_matches_sv(matcher, d); + SPAGAIN; + PUSHs(result ? &PL_sv_yes : &PL_sv_no); + destroy_matcher(matcher); + RETURN; + } + } + /* ~~ scalar */ + /* See if there is overload magic on left */ + else if (object_on_left && SvAMAGIC(d)) { + SV *tmpsv; + DEBUG_M(Perl_deb(aTHX_ " applying rule Object-Any\n")); + DEBUG_M(Perl_deb(aTHX_ " attempting overload\n")); + PUSHs(d); PUSHs(e); + PUTBACK; + tmpsv = amagic_call(d, e, smart_amg, AMGf_noright); + if (tmpsv) { + SPAGAIN; + (void)POPs; + SETs(tmpsv); + RETURN; + } + SP -= 2; + DEBUG_M(Perl_deb(aTHX_ " failed to run overload method; falling back...\n")); + goto sm_any_scalar; + } + else if (!SvOK(d)) { + /* undef ~~ scalar ; we already know that the scalar is SvOK */ + DEBUG_M(Perl_deb(aTHX_ " applying rule undef-Any\n")); + RETPUSHNO; + } + else + sm_any_scalar: + if (SvNIOK(e) || (SvPOK(e) && looks_like_number(e) && SvNIOK(d))) { + DEBUG_M(if (SvNIOK(e)) + Perl_deb(aTHX_ " applying rule Any-Num\n"); + else + Perl_deb(aTHX_ " applying rule Num-numish\n"); + ); + /* numeric comparison */ + PUSHs(d); PUSHs(e); + PUTBACK; + if (CopHINTS_get(PL_curcop) & HINT_INTEGER) + (void) Perl_pp_i_eq(aTHX); + else + (void) Perl_pp_eq(aTHX); SPAGAIN; - SETs(boolSV(SvTRUE_NN(result))); - return NORMAL; + if (SvTRUEx(POPs)) + RETPUSHYES; + else + RETPUSHNO; } - Perl_croak(aTHX_ "Cannot smart match without a matcher object"); + + /* As a last resort, use string comparison */ + DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Any\n")); + PUSHs(d); PUSHs(e); + PUTBACK; + return Perl_pp_seq(aTHX); } -PP(pp_enterwhereso) +PP(pp_enterwhen) { dSP; PERL_CONTEXT *cx; @@ -4613,22 +5186,22 @@ PP(pp_enterwhereso) /* This is essentially an optimization: if the match fails, we don't want to push a context and then pop it again right away, so we skip straight - to the op that follows the leavewhereso. + to the op that follows the leavewhen. RETURNOP calls PUTBACK which restores the stack pointer after the POPs. */ - if (!SvTRUEx(POPs)) { + if (!(PL_op->op_flags & OPf_SPECIAL) && !SvTRUEx(POPs)) { if (gimme == G_SCALAR) PUSHs(&PL_sv_undef); RETURNOP(cLOGOP->op_other->op_next); } - cx = cx_pushblock(CXt_WHERESO, gimme, SP, PL_savestack_ix); - cx_pushwhereso(cx); + cx = cx_pushblock(CXt_WHEN, gimme, SP, PL_savestack_ix); + cx_pushwhen(cx); RETURN; } -PP(pp_leavewhereso) +PP(pp_leavewhen) { I32 cxix; PERL_CONTEXT *cx; @@ -4636,12 +5209,14 @@ PP(pp_leavewhereso) SV **oldsp; cx = CX_CUR(); - assert(CxTYPE(cx) == CXt_WHERESO); + assert(CxTYPE(cx) == CXt_WHEN); gimme = cx->blk_gimme; - cxix = dopoptoloop(cxstack_ix); + cxix = dopoptogivenfor(cxstack_ix); if (cxix < 0) - DIE(aTHX_ "Can't leave \"whereso\" outside a loop block"); + /* diag_listed_as: Can't "when" outside a topicalizer */ + DIE(aTHX_ "Can't \"%s\" outside a topicalizer", + PL_op->op_flags & OPf_SPECIAL ? "default" : "when"); oldsp = PL_stack_base + cx->blk_oldsp; if (gimme == G_VOID) @@ -4649,25 +5224,24 @@ PP(pp_leavewhereso) else leave_adjust_stacks(oldsp, oldsp, gimme, 1); - /* pop the WHERESO, BLOCK and anything else before the loop */ + /* pop the WHEN, BLOCK and anything else before the GIVEN/FOR */ assert(cxix < cxstack_ix); dounwind(cxix); cx = &cxstack[cxix]; - if (CxTYPE(cx) != CXt_LOOP_GIVEN) { + if (CxFOREACH(cx)) { /* emulate pp_next. Note that any stack(s) cleanup will be * done by the pp_unstack which op_nextop should point to */ cx = CX_CUR(); cx_topblock(cx); PL_curcop = cx->blk_oldcop; - PERL_ASYNC_CHECK(); return cx->blk_loop.my_op->op_nextop; } else { PERL_ASYNC_CHECK(); - assert(cx->blk_loop.my_op->op_nextop->op_type == OP_LEAVELOOP); - return cx->blk_loop.my_op->op_nextop; + assert(cx->blk_givwhen.leave_op->op_type == OP_LEAVEGIVEN); + return cx->blk_givwhen.leave_op; } } @@ -4677,25 +5251,48 @@ PP(pp_continue) PERL_CONTEXT *cx; OP *nextop; - cxix = dopoptowhereso(cxstack_ix); + cxix = dopoptowhen(cxstack_ix); if (cxix < 0) - DIE(aTHX_ "Can't \"continue\" outside a whereso block"); + DIE(aTHX_ "Can't \"continue\" outside a when block"); if (cxix < cxstack_ix) dounwind(cxix); cx = CX_CUR(); - assert(CxTYPE(cx) == CXt_WHERESO); + assert(CxTYPE(cx) == CXt_WHEN); PL_stack_sp = PL_stack_base + cx->blk_oldsp; CX_LEAVE_SCOPE(cx); - cx_popwhereso(cx); + cx_popwhen(cx); cx_popblock(cx); - nextop = cx->blk_whereso.leave_op->op_next; + nextop = cx->blk_givwhen.leave_op->op_next; CX_POP(cx); return nextop; } +PP(pp_break) +{ + I32 cxix; + PERL_CONTEXT *cx; + + cxix = dopoptogivenfor(cxstack_ix); + if (cxix < 0) + DIE(aTHX_ "Can't \"break\" outside a given block"); + + cx = &cxstack[cxix]; + if (CxFOREACH(cx)) + DIE(aTHX_ "Can't \"break\" in a loop topicalizer"); + + if (cxix < cxstack_ix) + dounwind(cxix); + + /* Restore the sp at the time we entered the given block */ + cx = CX_CUR(); + PL_stack_sp = PL_stack_base + cx->blk_oldsp; + + return cx->blk_givwhen.leave_op; +} + static MAGIC * S_doparseform(pTHX_ SV *sv) { diff --git a/pp_proto.h b/pp_proto.h index 304e0f23a1..407cbd14a3 100644 --- a/pp_proto.h +++ b/pp_proto.h @@ -32,6 +32,7 @@ PERL_CALLCONV OP *Perl_pp_binmode(pTHX); PERL_CALLCONV OP *Perl_pp_bit_and(pTHX); PERL_CALLCONV OP *Perl_pp_bit_or(pTHX); PERL_CALLCONV OP *Perl_pp_bless(pTHX); +PERL_CALLCONV OP *Perl_pp_break(pTHX); PERL_CALLCONV OP *Perl_pp_caller(pTHX); PERL_CALLCONV OP *Perl_pp_chdir(pTHX); PERL_CALLCONV OP *Perl_pp_chop(pTHX); @@ -63,7 +64,7 @@ PERL_CALLCONV OP *Perl_pp_enteriter(pTHX); PERL_CALLCONV OP *Perl_pp_enterloop(pTHX); PERL_CALLCONV OP *Perl_pp_entersub(pTHX); PERL_CALLCONV OP *Perl_pp_entertry(pTHX); -PERL_CALLCONV OP *Perl_pp_enterwhereso(pTHX); +PERL_CALLCONV OP *Perl_pp_enterwhen(pTHX); PERL_CALLCONV OP *Perl_pp_enterwrite(pTHX); PERL_CALLCONV OP *Perl_pp_eof(pTHX); PERL_CALLCONV OP *Perl_pp_eq(pTHX); @@ -134,11 +135,12 @@ PERL_CALLCONV OP *Perl_pp_lc(pTHX); PERL_CALLCONV OP *Perl_pp_le(pTHX); PERL_CALLCONV OP *Perl_pp_leave(pTHX); PERL_CALLCONV OP *Perl_pp_leaveeval(pTHX); +PERL_CALLCONV OP *Perl_pp_leavegiven(pTHX); PERL_CALLCONV OP *Perl_pp_leaveloop(pTHX); PERL_CALLCONV OP *Perl_pp_leavesub(pTHX); PERL_CALLCONV OP *Perl_pp_leavesublv(pTHX); PERL_CALLCONV OP *Perl_pp_leavetry(pTHX); -PERL_CALLCONV OP *Perl_pp_leavewhereso(pTHX); +PERL_CALLCONV OP *Perl_pp_leavewhen(pTHX); PERL_CALLCONV OP *Perl_pp_leavewrite(pTHX); PERL_CALLCONV OP *Perl_pp_left_shift(pTHX); PERL_CALLCONV OP *Perl_pp_length(pTHX); @@ -512,6 +512,11 @@ PERL_CALLCONV OP * Perl_ck_shift(pTHX_ OP *o) #define PERL_ARGS_ASSERT_CK_SHIFT \ assert(o) +PERL_CALLCONV OP * Perl_ck_smartmatch(pTHX_ OP *o) + __attribute__warn_unused_result__; +#define PERL_ARGS_ASSERT_CK_SMARTMATCH \ + assert(o) + PERL_CALLCONV OP * Perl_ck_sort(pTHX_ OP *o) __attribute__warn_unused_result__; #define PERL_ARGS_ASSERT_CK_SORT \ @@ -2166,10 +2171,10 @@ PERL_CALLCONV OP* Perl_newFOROP(pTHX_ I32 flags, OP* sv, OP* expr, OP* block, OP #define PERL_ARGS_ASSERT_NEWFOROP \ assert(expr) -PERL_CALLCONV OP* Perl_newGIVENOP(pTHX_ OP* topic, OP* block, PADOFFSET defsv_off) +PERL_CALLCONV OP* Perl_newGIVENOP(pTHX_ OP* cond, OP* block, PADOFFSET defsv_off) __attribute__warn_unused_result__; #define PERL_ARGS_ASSERT_NEWGIVENOP \ - assert(topic); assert(block) + assert(cond); assert(block) PERL_CALLCONV GP * Perl_newGP(pTHX_ GV *const gv); #define PERL_ARGS_ASSERT_NEWGP \ @@ -2356,10 +2361,10 @@ PERL_CALLCONV OP* Perl_newUNOP(pTHX_ I32 type, I32 flags, OP* first) PERL_CALLCONV OP* Perl_newUNOP_AUX(pTHX_ I32 type, I32 flags, OP* first, UNOP_AUX_item *aux) __attribute__warn_unused_result__; -PERL_CALLCONV OP* Perl_newWHERESOOP(pTHX_ OP* cond, OP* block) +PERL_CALLCONV OP* Perl_newWHENOP(pTHX_ OP* cond, OP* block) __attribute__warn_unused_result__; -#define PERL_ARGS_ASSERT_NEWWHERESOOP \ - assert(cond); assert(block) +#define PERL_ARGS_ASSERT_NEWWHENOP \ + assert(block) PERL_CALLCONV OP* Perl_newWHILEOP(pTHX_ I32 flags, I32 debuggable, LOOP* loop, OP* expr, OP* block, OP* cont, I32 has_my) __attribute__warn_unused_result__; @@ -4003,6 +4008,11 @@ PERL_STATIC_INLINE void S_cx_popformat(pTHX_ PERL_CONTEXT *cx); assert(cx) #endif #ifndef PERL_NO_INLINE_FUNCTIONS +PERL_STATIC_INLINE void S_cx_popgiven(pTHX_ PERL_CONTEXT *cx); +#define PERL_ARGS_ASSERT_CX_POPGIVEN \ + assert(cx) +#endif +#ifndef PERL_NO_INLINE_FUNCTIONS PERL_STATIC_INLINE void S_cx_poploop(pTHX_ PERL_CONTEXT *cx); #define PERL_ARGS_ASSERT_CX_POPLOOP \ assert(cx) @@ -4023,8 +4033,8 @@ PERL_STATIC_INLINE void S_cx_popsub_common(pTHX_ PERL_CONTEXT *cx); assert(cx) #endif #ifndef PERL_NO_INLINE_FUNCTIONS -PERL_STATIC_INLINE void S_cx_popwhereso(pTHX_ PERL_CONTEXT *cx); -#define PERL_ARGS_ASSERT_CX_POPWHERESO \ +PERL_STATIC_INLINE void S_cx_popwhen(pTHX_ PERL_CONTEXT *cx); +#define PERL_ARGS_ASSERT_CX_POPWHEN \ assert(cx) #endif #ifndef PERL_NO_INLINE_FUNCTIONS @@ -4043,16 +4053,16 @@ PERL_STATIC_INLINE void S_cx_pushformat(pTHX_ PERL_CONTEXT *cx, CV *cv, OP *reto assert(cx); assert(cv) #endif #ifndef PERL_NO_INLINE_FUNCTIONS +PERL_STATIC_INLINE void S_cx_pushgiven(pTHX_ PERL_CONTEXT *cx, SV *orig_defsv); +#define PERL_ARGS_ASSERT_CX_PUSHGIVEN \ + assert(cx) +#endif +#ifndef PERL_NO_INLINE_FUNCTIONS PERL_STATIC_INLINE void S_cx_pushloop_for(pTHX_ PERL_CONTEXT *cx, void *itervarp, SV *itersave); #define PERL_ARGS_ASSERT_CX_PUSHLOOP_FOR \ assert(cx); assert(itervarp) #endif #ifndef PERL_NO_INLINE_FUNCTIONS -PERL_STATIC_INLINE void S_cx_pushloop_given(pTHX_ PERL_CONTEXT *cx, SV *orig_defsv); -#define PERL_ARGS_ASSERT_CX_PUSHLOOP_GIVEN \ - assert(cx) -#endif -#ifndef PERL_NO_INLINE_FUNCTIONS PERL_STATIC_INLINE void S_cx_pushloop_plain(pTHX_ PERL_CONTEXT *cx); #define PERL_ARGS_ASSERT_CX_PUSHLOOP_PLAIN \ assert(cx) @@ -4063,8 +4073,8 @@ PERL_STATIC_INLINE void S_cx_pushsub(pTHX_ PERL_CONTEXT *cx, CV *cv, OP *retop, assert(cx); assert(cv) #endif #ifndef PERL_NO_INLINE_FUNCTIONS -PERL_STATIC_INLINE void S_cx_pushwhereso(pTHX_ PERL_CONTEXT *cx); -#define PERL_ARGS_ASSERT_CX_PUSHWHERESO \ +PERL_STATIC_INLINE void S_cx_pushwhen(pTHX_ PERL_CONTEXT *cx); +#define PERL_ARGS_ASSERT_CX_PUSHWHEN \ assert(cx) #endif #ifndef PERL_NO_INLINE_FUNCTIONS @@ -4780,6 +4790,9 @@ STATIC bool S_is_handle_constructor(const OP *o, I32 numargs) assert(o) STATIC OP* S_listkids(pTHX_ OP* o); +STATIC bool S_looks_like_bool(pTHX_ const OP* o); +#define PERL_ARGS_ASSERT_LOOKS_LIKE_BOOL \ + assert(o) STATIC OP* S_modkids(pTHX_ OP *o, I32 type); STATIC void S_move_proto_attr(pTHX_ OP **proto, OP **attrs, const GV *name, bool curstash); #define PERL_ARGS_ASSERT_MOVE_PROTO_ATTR \ @@ -4787,6 +4800,9 @@ STATIC void S_move_proto_attr(pTHX_ OP **proto, OP **attrs, const GV *name, bool STATIC OP * S_my_kid(pTHX_ OP *o, OP *attrs, OP **imopsp); #define PERL_ARGS_ASSERT_MY_KID \ assert(imopsp) +STATIC OP* S_newGIVWHENOP(pTHX_ OP* cond, OP *block, I32 enter_opcode, I32 leave_opcode, PADOFFSET entertarg); +#define PERL_ARGS_ASSERT_NEWGIVWHENOP \ + assert(block) #ifndef PERL_NO_INLINE_FUNCTIONS PERL_STATIC_INLINE OP* S_newMETHOP_internal(pTHX_ I32 type, I32 flags, OP* dynamic_meth, SV* const_meth); #endif @@ -4822,6 +4838,7 @@ STATIC OP* S_pmtrans(pTHX_ OP* o, OP* expr, OP* repl); STATIC bool S_process_special_blocks(pTHX_ I32 floor, const char *const fullname, GV *const gv, CV *const cv); #define PERL_ARGS_ASSERT_PROCESS_SPECIAL_BLOCKS \ assert(fullname); assert(gv); assert(cv) +STATIC OP* S_ref_array_or_hash(pTHX_ OP* cond); STATIC OP* S_refkids(pTHX_ OP* o, I32 type); STATIC bool S_scalar_mod_type(const OP *o, I32 type) __attribute__warn_unused_result__; @@ -4936,6 +4953,10 @@ STATIC PerlIO * S_check_type_and_open(pTHX_ SV *name) #define PERL_ARGS_ASSERT_CHECK_TYPE_AND_OPEN \ assert(name) +STATIC void S_destroy_matcher(pTHX_ PMOP* matcher); +#define PERL_ARGS_ASSERT_DESTROY_MATCHER \ + assert(matcher) +STATIC OP* S_do_smartmatch(pTHX_ HV* seen_this, HV* seen_other, const bool copied); STATIC OP* S_docatch(pTHX_ Perl_ppaddr_t firstpp) __attribute__warn_unused_result__; @@ -4951,6 +4972,9 @@ STATIC MAGIC * S_doparseform(pTHX_ SV *sv); STATIC I32 S_dopoptoeval(pTHX_ I32 startingblock) __attribute__warn_unused_result__; +STATIC I32 S_dopoptogivenfor(pTHX_ I32 startingblock) + __attribute__warn_unused_result__; + STATIC I32 S_dopoptolabel(pTHX_ const char *label, STRLEN len, U32 flags) __attribute__warn_unused_result__; #define PERL_ARGS_ASSERT_DOPOPTOLABEL \ @@ -4964,8 +4988,18 @@ STATIC I32 S_dopoptosub_at(pTHX_ const PERL_CONTEXT* cxstk, I32 startingblock) #define PERL_ARGS_ASSERT_DOPOPTOSUB_AT \ assert(cxstk) -STATIC I32 S_dopoptowhereso(pTHX_ I32 startingblock) +STATIC I32 S_dopoptowhen(pTHX_ I32 startingblock) + __attribute__warn_unused_result__; + +STATIC PMOP* S_make_matcher(pTHX_ REGEXP* re) + __attribute__warn_unused_result__; +#define PERL_ARGS_ASSERT_MAKE_MATCHER \ + assert(re) + +STATIC bool S_matcher_matches_sv(pTHX_ PMOP* matcher, SV* sv) __attribute__warn_unused_result__; +#define PERL_ARGS_ASSERT_MATCHER_MATCHES_SV \ + assert(matcher); assert(sv) STATIC bool S_num_overflow(NV value, I32 fldsize, I32 frcsize) __attribute__warn_unused_result__; diff --git a/regen/feature.pl b/regen/feature.pl index 8cad2c4b45..3ce2a6d44b 100755 --- a/regen/feature.pl +++ b/regen/feature.pl @@ -369,7 +369,7 @@ read_only_bottom_close_and_rename($h); __END__ package feature; -our $VERSION = '1.50'; +our $VERSION = '1.51'; FEATURES @@ -461,7 +461,7 @@ explicitly disabled the warning: no warnings "experimental::smartmatch"; -C<use feature 'switch'> tells the compiler to enable the +C<use feature 'switch'> tells the compiler to enable the Perl 6 given/when construct. See L<perlsyn/"Switch Statements"> for details. diff --git a/regen/keywords.pl b/regen/keywords.pl index b794a6bfe9..9619d86faf 100755 --- a/regen/keywords.pl +++ b/regen/keywords.pl @@ -39,9 +39,10 @@ my %feature_kw = ( state => 'state', say => 'say', given => 'switch', - whereis => 'switch', - whereso => 'switch', + when => 'switch', + default => 'switch', # continue is already a keyword + break => 'switch', evalbytes => 'evalbytes', __SUB__ => '__SUB__', fc => 'fc', @@ -128,6 +129,7 @@ __END__ -bind -binmode -bless +-break -caller -chdir -chmod @@ -145,6 +147,7 @@ __END__ -crypt -dbmclose -dbmopen ++default +defined +delete -die @@ -353,8 +356,7 @@ __END__ -waitpid -wantarray -warn -+whereis -+whereso ++when +while -write -x diff --git a/regen/op_private b/regen/op_private index 7085f5bf42..eb53edf43a 100644 --- a/regen/op_private +++ b/regen/op_private @@ -626,6 +626,7 @@ addbits('rv2gv', addbits('enteriter', 1 => qw(OPpITER_REVERSED REVERSED),# for (reverse ...) + 3 => qw(OPpITER_DEF DEF), # 'for $_' ); addbits('iter', 1 => qw(OPpITER_REVERSED REVERSED)); diff --git a/regen/opcodes b/regen/opcodes index 476279b100..5aa8a94fa5 100644 --- a/regen/opcodes +++ b/regen/opcodes @@ -179,7 +179,7 @@ ncomplement numeric 1's complement (~) ck_bitop fsT1 S # warning is gone, this can change to ck_null. scomplement string 1's complement (~) ck_bitop fsT1 S -smartmatch smart match ck_null ifs2 S S +smartmatch smart match ck_smartmatch s2 # High falutin' math. @@ -328,9 +328,11 @@ method_super super with known name ck_null d. method_redir redirect method with known name ck_null d. method_redir_super redirect super method with known name ck_null d. -entergiven given() ck_null d{ -enterwhereso whereso() ck_null d| -leavewhereso leave whereso block ck_null 1 +entergiven given() ck_null d| +leavegiven leave given block ck_null 1 +enterwhen when() ck_null d| +leavewhen leave when block ck_null 1 +break break ck_null 0 continue continue ck_null 0 # I/O. @@ -1530,7 +1530,6 @@ Perl_cx_dump(pTHX_ PERL_CONTEXT *cx) PTR2UV(cx->blk_eval.retop)); break; - case CXt_LOOP_GIVEN: case CXt_LOOP_PLAIN: case CXt_LOOP_LAZYIV: case CXt_LOOP_LAZYSV: @@ -14495,7 +14495,6 @@ Perl_cx_dup(pTHX_ PERL_CONTEXT *cxs, I32 ix, I32 max, CLONE_PARAMS* param) /* FALLTHROUGH */ case CXt_LOOP_LIST: case CXt_LOOP_LAZYIV: - case CXt_LOOP_GIVEN: /* code common to all 'for' CXt_LOOP_* types */ ncx->blk_loop.itersave = sv_dup_inc(ncx->blk_loop.itersave, param); @@ -14528,9 +14527,13 @@ Perl_cx_dup(pTHX_ PERL_CONTEXT *cxs, I32 ix, I32 max, CLONE_PARAMS* param) ncx->blk_format.dfoutgv = gv_dup_inc(ncx->blk_format.dfoutgv, param); break; + case CXt_GIVEN: + ncx->blk_givwhen.defsv_save = + sv_dup_inc(ncx->blk_givwhen.defsv_save, param); + break; case CXt_BLOCK: case CXt_NULL: - case CXt_WHERESO: + case CXt_WHEN: break; } } diff --git a/t/lib/croak/pp_ctl b/t/lib/croak/pp_ctl index 5c98769913..2943bf7551 100644 --- a/t/lib/croak/pp_ctl +++ b/t/lib/croak/pp_ctl @@ -28,8 +28,14 @@ dump $label; EXPECT Can't find label foo at - line 3. ######## -# NAME whereso outside given +# NAME when outside given use 5.01; no warnings 'experimental::smartmatch'; -whereso(!defined){} +when(undef){} EXPECT -Can't leave "whereso" outside a loop block at - line 2. +Can't "when" outside a topicalizer at - line 2. +######## +# NAME default outside given +use 5.01; +default{} +EXPECT +Can't "default" outside a topicalizer at - line 2. diff --git a/t/lib/feature/switch b/t/lib/feature/switch index 5e6269ff0e..0dee7f51cf 100644 --- a/t/lib/feature/switch +++ b/t/lib/feature/switch @@ -9,17 +9,31 @@ EXPECT Unquoted string "given" may clash with future reserved word at - line 3. given ######## -# No switch; whereso should be a bareword. +# No switch; when should be a bareword. use warnings; no warnings 'experimental::smartmatch'; -print STDOUT whereso; +print STDOUT when; EXPECT -Unquoted string "whereso" may clash with future reserved word at - line 3. -whereso +Unquoted string "when" may clash with future reserved word at - line 3. +when +######## +# No switch; default should be a bareword. +use warnings; no warnings 'experimental::smartmatch'; +print STDOUT default; +EXPECT +Unquoted string "default" may clash with future reserved word at - line 3. +default +######## +# No switch; break should be a bareword. +use warnings; no warnings 'experimental::smartmatch'; +print STDOUT break; +EXPECT +Unquoted string "break" may clash with future reserved word at - line 3. +break ######## # No switch; but continue is still a keyword print STDOUT continue; EXPECT -Can't "continue" outside a whereso block at - line 2. +Can't "continue" outside a when block at - line 2. ######## # Use switch; so given is a keyword use feature 'switch'; no warnings 'experimental::smartmatch'; @@ -27,12 +41,24 @@ given("okay\n") { print } EXPECT okay ######## -# Use switch; so whereso is a keyword +# Use switch; so when is a keyword +use feature 'switch'; no warnings 'experimental::smartmatch'; +given(1) { when(1) { print "okay" } } +EXPECT +okay +######## +# Use switch; so default is a keyword use feature 'switch'; no warnings 'experimental::smartmatch'; -given(1) { whereso(1) { print "okay" } } +given(1) { default { print "okay" } } EXPECT okay ######## +# Use switch; so break is a keyword +use feature 'switch'; +break; +EXPECT +Can't "break" outside a given block at - line 3. +######## # switch out of scope; given should be a bareword. use warnings; no warnings 'experimental::smartmatch'; { use feature 'switch'; @@ -44,35 +70,73 @@ Unquoted string "given" may clash with future reserved word at - line 6. Okay here given ######## -# switch out of scope; whereso should be a bareword. +# switch out of scope; when should be a bareword. use warnings; no warnings 'experimental::smartmatch'; { use feature 'switch'; - given (1) { whereso(1) {print "Okay here\n";} } + given (1) { when(1) {print "Okay here\n";} } } -print STDOUT whereso; +print STDOUT when; EXPECT -Unquoted string "whereso" may clash with future reserved word at - line 6. +Unquoted string "when" may clash with future reserved word at - line 6. Okay here -whereso +when +######## +# switch out of scope; default should be a bareword. +use warnings; no warnings 'experimental::smartmatch'; +{ use feature 'switch'; + given (1) { default {print "Okay here\n";} } +} +print STDOUT default; +EXPECT +Unquoted string "default" may clash with future reserved word at - line 6. +Okay here +default +######## +# switch out of scope; break should be a bareword. +use warnings; no warnings 'experimental::smartmatch'; +{ use feature 'switch'; + given (1) { break } +} +print STDOUT break; +EXPECT +Unquoted string "break" may clash with future reserved word at - line 6. +break ######## # C<no feature 'switch'> should work use warnings; no warnings 'experimental::smartmatch'; use feature 'switch'; -given (1) { whereso(1) {print "Okay here\n";} } +given (1) { when(1) {print "Okay here\n";} } no feature 'switch'; -print STDOUT whereso; +print STDOUT when; EXPECT -Unquoted string "whereso" may clash with future reserved word at - line 6. +Unquoted string "when" may clash with future reserved word at - line 6. Okay here -whereso +when ######## # C<no feature> should work too use warnings; no warnings 'experimental::smartmatch'; use feature 'switch'; -given (1) { whereso(1) {print "Okay here\n";} } +given (1) { when(1) {print "Okay here\n";} } no feature; -print STDOUT whereso; +print STDOUT when; EXPECT -Unquoted string "whereso" may clash with future reserved word at - line 6. +Unquoted string "when" may clash with future reserved word at - line 6. Okay here -whereso +when +######## +# Without the feature, no 'Unambiguous use of' warning: +use warnings; no warnings 'experimental::smartmatch'; +@break = ($break = "break"); +print ${break}, ${break[0]}; +EXPECT +breakbreak +######## +# With the feature, we get an 'Unambiguous use of' warning: +use warnings; no warnings 'experimental::smartmatch'; +use feature 'switch'; +@break = ($break = "break"); +print ${break}, ${break[0]}; +EXPECT +Ambiguous use of ${break} resolved to $break at - line 5. +Ambiguous use of ${break[...]} resolved to $break[...] at - line 5. +breakbreak diff --git a/t/lib/warnings/9uninit b/t/lib/warnings/9uninit index 3963d66e39..774c6ee432 100644 --- a/t/lib/warnings/9uninit +++ b/t/lib/warnings/9uninit @@ -1943,6 +1943,13 @@ $v = 1 + prototype $fn; EXPECT Use of uninitialized value in addition (+) at - line 4. ######## +use warnings 'uninitialized'; no warnings 'experimental::smartmatch'; +my $v; +my $fn = sub {}; +$v = 1 + (1 ~~ $fn); +EXPECT +Use of uninitialized value in addition (+) at - line 4. +######## use warnings 'uninitialized'; my $v; my $f = ""; diff --git a/t/lib/warnings/op b/t/lib/warnings/op index 52ef3781cd..a6434ff6be 100644 --- a/t/lib/warnings/op +++ b/t/lib/warnings/op @@ -421,7 +421,7 @@ eval { getgrgid 1 }; # OP_GGRGID eval { getpwnam 1 }; # OP_GPWNAM eval { getpwuid 1 }; # OP_GPWUID prototype "foo"; # OP_PROTOTYPE -$a ~~ $b if rand(1)>2; # OP_SMARTMATCH +$a ~~ $b; # OP_SMARTMATCH $a <=> $b; # OP_NCMP "dsatrewq"; "diatrewq"; diff --git a/t/lib/warnings/utf8 b/t/lib/warnings/utf8 index 2ac8ac97f6..a9a6388d31 100644 --- a/t/lib/warnings/utf8 +++ b/t/lib/warnings/utf8 @@ -779,6 +779,7 @@ BEGIN{ } no warnings; use warnings 'utf8'; -pack("UXc",168) eq "\xaa"; +for(uc 0..t){0~~pack"UXc",exp} EXPECT -Malformed UTF-8 character: \xc2\x00 (unexpected non-continuation byte 0x00, immediately after start byte 0xc2; need 2 bytes, got 1) in string eq at - line 9. +OPTIONS regex +Malformed UTF-8 character: \\x([[:xdigit:]]{2})\\x([[:xdigit:]]{2}) \(unexpected non-continuation byte 0x\2, immediately after start byte 0x\1; need 2 bytes, got 1\) in smart match at - line 9. diff --git a/t/op/coreamp.t b/t/op/coreamp.t index c2b53a6176..7231d66e81 100644 --- a/t/op/coreamp.t +++ b/t/op/coreamp.t @@ -370,6 +370,18 @@ like join(" ", &CORE::bless([],'parcel')), qr/^parcel=ARRAY(?!.* )/, "&bless in list context"; like &mybless([]), qr/^main=ARRAY/, '&bless with one arg'; +test_proto 'break'; +{ $tests ++; + my $tmp; + CORE::given(1) { + CORE::when(1) { + &mybreak; + $tmp = 'bad'; + } + } + is $tmp, undef, '&break'; +} + test_proto 'caller'; $tests += 4; sub caller_test { @@ -450,7 +462,7 @@ SKIP: test_proto 'continue'; $tests ++; CORE::given(1) { - CORE::whereso(1) { + CORE::when(1) { &mycontinue(); } pass "&continue"; @@ -1152,12 +1164,12 @@ like $@, qr'^Undefined format "STDOUT" called', if (m?__END__?..${\0} and /^[-+](.*)/) { my $word = $1; next if - $word =~ /^(?:s(?:tate|ort|ay|ub)?|d(?:ump|o)|p(?:rintf?|ackag + $word =~ /^(?:s(?:tate|ort|ay|ub)?|d(?:ef + ault|ump|o)|p(?:rintf?|ackag 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|ere(?:is|so)) + AUTOLOA|EN)D|n(?:e(?:xt)?|o)|C(?:HECK|ORE)|wh(?:ile|en) |(?: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 69464961b3..62210b576d 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 - whereis whereso while x xor y + when while x xor y ); my %args_for = ( dbmopen => '%1,$2,$3', diff --git a/t/op/cproto.t b/t/op/cproto.t index 11cd9ad778..fec9fe6ba9 100644 --- a/t/op/cproto.t +++ b/t/op/cproto.t @@ -7,7 +7,7 @@ BEGIN { set_up_inc('../lib'); } -plan tests => 253; +plan tests => 254; while (<DATA>) { chomp; @@ -51,6 +51,7 @@ atan2 ($$) bind (*$) binmode (*;$) bless ($;$) +break () caller (;$) chdir (;$) chmod (@) @@ -68,6 +69,7 @@ cos (_) crypt ($$) dbmclose (\%) dbmopen (\%$$) +default undef defined undef delete undef die (@) @@ -276,8 +278,7 @@ wait () waitpid ($$) wantarray () warn (@) -whereis undef -whereso undef +when undef while undef write (;*) x undef diff --git a/t/op/given.t b/t/op/given.t deleted file mode 100644 index 1187171fc3..0000000000 --- a/t/op/given.t +++ /dev/null @@ -1,238 +0,0 @@ -#!./perl - -BEGIN { - chdir 't' if -d 't'; - require './test.pl'; - set_up_inc('../lib'); -} - -use strict; -use warnings; -no warnings 'experimental::smartmatch'; - -plan tests => 55; - -CORE::given(3) { - pass "CORE::given without feature flag"; -} - -use feature 'switch'; - -CORE::given(3) { - pass "CORE::given with feature flag"; -} - -given(3) { - pass "given with feature flag"; -} - -{ - my $x = "foo"; - is($x, "foo", "given lexical scope not started yet"); - given(my $x = "bar") { - is($x, "bar", "given lexical scope starts"); - } - is($x, "foo", "given lexical scope ends"); -} - -sub topic_is ($@) { is $_, shift, @_ } -{ - local $_ = "foo"; - is $_, "foo", "given dynamic scope not started yet"; - topic_is "foo", "given dynamic scope not started yet"; - given("bar") { - is $_, "bar", "given dynamic scope starts"; - topic_is "bar", "given dynamic scope starts"; - } - is $_, "foo", "given dynamic scope ends"; - topic_is "foo", "given dynamic scope ends"; -} - -given(undef) { - is $_, undef, "folded undef topic value"; - is \$_, \undef, "folded undef topic identity"; -} -given(1 < 3) { - is $_, !!1, "folded true topic value"; - is \$_, \!!1, "folded true topic identity"; -} -given(1 > 3) { - is $_, !!0, "folded false topic value"; - is \$_, \!!0, "folded false topic identity"; -} -my $one = 1; -given($one && undef) { - is $_, undef, "computed undef topic value"; - is \$_, \undef, "computed undef topic identity"; -} -given($one < 3) { - is $_, !!1, "computed true topic value"; - is \$_, \!!1, "computed true topic identity"; -} -given($one > 3) { - is $_, !!0, "computed false topic value"; - is \$_, \!!0, "computed false topic identity"; -} - -sub which_context { - return wantarray ? "list" : defined(wantarray) ? "scalar" : "void"; -} -given(which_context) { - is $_, "scalar", "topic sub called without parens"; -} -given(which_context()) { - is $_, "scalar", "topic sub called with parens"; -} - -my $ps = "foo"; -given($ps) { - is $_, "foo", "padsv topic value"; - is \$_, \$ps, "padsv topic identity"; -} -our $gs = "bar"; -given($gs) { - is $_, "bar", "gvsv topic value"; - is \$_, \$gs, "gvsv topic identity"; -} -my @pa = qw(a b c d e); -given(@pa) { - is $_, 5, "padav topic"; -} -our @ga = qw(x y z); -given(@ga) { - is $_, 3, "gvav topic"; -} -my %ph = qw(a b c d e f g h i j); -given(%ph) { - is $_, 5, "padhv topic"; -} -our %gh = qw(u v w x y z); -given(%gh) { - is $_, 3, "gvhv topic"; -} - -given($one + 3) { - is $_, 4, "general computed topic"; -} - -is join(",", 111, 222, - do { - no warnings "void"; - given($one, 22, $one, 33) { - is $_, 33, "list topic"; - (1111, 2222); - } - }, - 333, 444, -), "111,222,1111,2222,333,444", "stack discipline"; - -given(()) { - is $_, undef, "stub topic value"; - is \$_, \undef, "stub topic identity"; -} - -foreach my $test ( - [ "no", "[aA][bB][cB][dA]" ], - [ "last", "[aA][bB][dA]" ], - [ "next", "[aA][bB][dA]" ], - [ "redo", "[aA][bB][bB][cB][dA]" ], -) { - my($loopex, $expect_act) = @$test; - my $act = ""; - my $i = 0; - { - local $_ = "A"; - $act .= "[a$_]"; - given("B") { - $act .= "[b$_]"; - $i++; - if($i < 2) { - if($loopex eq "last") { - last; - } elsif($loopex eq "next") { - next; - } elsif($loopex eq "redo") { - redo; - } - } - $act .= "[c$_]"; - } - $act .= "[d$_]"; - } - is $act, $expect_act, "given unlabelled $loopex loop exit"; - $act = ""; - $i = 0; - { - local $_ = "A"; - $act .= "[a$_]"; - G: given("B") { - $act .= "[b$_]"; - { - $i++; - if($i < 2) { - if($loopex eq "last") { - last G; - } elsif($loopex eq "next") { - next G; - } elsif($loopex eq "redo") { - redo G; - } - } - } - $act .= "[c$_]"; - } - $act .= "[d$_]"; - } - is $act, $expect_act, "given labelled $loopex loop exit"; - $act = ""; - $i = 0; - { - local $_ = "A"; - $act .= "[a$_]"; - given("B") { - $act .= "[b$_]"; - { - $i++; - if($i < 2) { - if($loopex eq "last") { - last; - } elsif($loopex eq "next") { - next; - } elsif($loopex eq "redo") { - redo; - } - } - } - $act .= "[c$_]"; - } - $act .= "[d$_]"; - } - is $act, "[aA][bB][cB][dA]", "interior $loopex loop exit"; - $act = ""; - $i = 0; - { - local $_ = "A"; - $act .= "[a$_]"; - B: { - local $_ = "B"; - $act .= "[b$_]"; - given("C") { - $i++; - if($i < 2) { - if($loopex eq "last") { - last B; - } elsif($loopex eq "next") { - next B; - } elsif($loopex eq "redo") { - redo B; - } - } - } - $act .= "[c$_]"; - } - $act .= "[d$_]"; - } - is $act, $expect_act, "exterior $loopex loop exit"; -} - -1; diff --git a/t/op/smartmatch.t b/t/op/smartmatch.t index 8b48fce1a3..10d35390d7 100644 --- a/t/op/smartmatch.t +++ b/t/op/smartmatch.t @@ -7,105 +7,586 @@ BEGIN { } use strict; use warnings; -no warnings qw(uninitialized experimental::smartmatch); - -my @notov = ( - undef, - 0, - 1, - "", - "abc", - *foo, - ${qr/./}, - \undef, - \0, - \1, - \"", - \"abc", - \*foo, - [], - {}, - sub { 1 }, - \*STDIN, - bless({}, "NotOverloaded"), -); - -package MatchAbc { use overload "~~" => sub { $_[1] eq "abc" }, fallback => 1; } -my $matchabc = bless({}, "MatchAbc"); -my $regexpabc = qr/\Aabc\z/; - -plan tests => (2+@notov)*@notov + 4*(2+@notov) + 15; - -foreach my $matcher (@notov) { - foreach my $matchee ($matchabc, $regexpabc, @notov) { - my $res = eval { $matchee ~~ $matcher }; - like $@, qr/\ACannot smart match without a matcher object /; - } +no warnings 'uninitialized'; +no warnings 'experimental::smartmatch'; + +++$|; + +use Tie::Array; +use Tie::Hash; + +# Predeclare vars used in the tests: +my @empty; +my %empty; +my @sparse; $sparse[2] = 2; + +my $deep1 = []; push @$deep1, $deep1; +my $deep2 = []; push @$deep2, $deep2; + +my @nums = (1..10); +tie my @tied_nums, 'Tie::StdArray'; +@tied_nums = (1..10); + +my %hash = (foo => 17, bar => 23); +tie my %tied_hash, 'Tie::StdHash'; +%tied_hash = %hash; + +{ + package Test::Object::NoOverload; + sub new { bless { key => 1 } } } -foreach my $matchee ($matchabc, $regexpabc, @notov) { - my $res = eval { $matchee ~~ $matchabc }; - is $@, ""; - is $res, $matchee eq "abc"; - $res = eval { $matchee ~~ $regexpabc }; - is $@, ""; - is $res, $matchee eq "abc"; + +{ + package Test::Object::StringOverload; + use overload '""' => sub { "object" }, fallback => 1; + sub new { bless { key => 1 } } } -ok "abc" ~~ qr/\Aabc/; -ok "abcd" ~~ qr/\Aabc/; -ok !("xabc" ~~ qr/\Aabc/); - -package MatchRef { use overload "~~" => sub { ref($_[1]) }; } -my $matchref = bless({}, "MatchRef"); -package MatchThree { use overload "~~" => sub { !ref($_[1]) && $_[1] == 3 }; } -my $matchthree = bless({}, "MatchThree"); - -my @a = qw(x y z); -ok @a ~~ $matchthree; -ok !(@a ~~ $matchref); -my %h = qw(a b c d); -ok !(%h ~~ $matchref); -my $res = eval { "abc" ~~ %$matchabc }; -like $@, qr/\ACannot smart match without a matcher object /; - -package MatchDie { use overload "~~" => sub { die "wibble" }; } -my $matchdie = bless({}, "MatchDie"); - -$res = eval { "abc" ~~ $matchdie }; -like $@, qr/\Awibble /; - -package MatchScalarContextCheck { - use overload "~~" => sub { - die "array context" if wantarray; - die "void context" unless defined wantarray; - 1; +{ + package Test::Object::WithOverload; + sub new { bless { key => ($_[1] // 'magic') } } + use overload '~~' => sub { + my %hash = %{ $_[0] }; + if ($_[2]) { # arguments reversed ? + return $_[1] eq reverse $hash{key}; + } + else { + return $_[1] eq $hash{key}; + } }; + use overload '""' => sub { "stringified" }; + use overload 'eq' => sub {"$_[0]" eq "$_[1]"}; } -my $matchscalarcontextcheck = bless({}, "MatchScalarContextCheck"); -package MatchVoidContextCheck { - use overload "~~" => sub { - die "array context" if wantarray; - die "scalar context" if defined wantarray; - 1; - }; + +our $ov_obj = Test::Object::WithOverload->new; +our $ov_obj_2 = Test::Object::WithOverload->new("object"); +our $obj = Test::Object::NoOverload->new; +our $str_obj = Test::Object::StringOverload->new; + +my %refh; +unless (is_miniperl()) { + require Tie::RefHash; + tie %refh, 'Tie::RefHash'; + $refh{$ov_obj} = 1; +} + +my @keyandmore = qw(key and more); +my @fooormore = qw(foo or more); +my %keyandmore = map { $_ => 0 } @keyandmore; +my %fooormore = map { $_ => 0 } @fooormore; + +# Load and run the tests +plan tests => 349+4; + +while (<DATA>) { + SKIP: { + next if /^#/ || !/\S/; + chomp; + my ($yn, $left, $right, $note) = split /\t+/; + + local $::TODO = $note =~ /TODO/; + + die "Bad test spec: ($yn, $left, $right)" if $yn =~ /[^!@=]/; + + my $tstr = "$left ~~ $right"; + + test_again: + my $res; + if ($note =~ /NOWARNINGS/) { + $res = eval "no warnings; $tstr"; + } + else { + skip_if_miniperl("Doesn't work with miniperl", $yn =~ /=/ ? 2 : 1) + if $note =~ /MINISKIP/; + $res = eval $tstr; + } + + chomp $@; + + if ( $yn =~ /@/ ) { + ok( $@ ne '', "$tstr dies" ) + and print "# \$\@ was: $@\n"; + } else { + my $test_name = $tstr . ($yn =~ /!/ ? " does not match" : " matches"); + if ( $@ ne '' ) { + fail($test_name); + print "# \$\@ was: $@\n"; + } else { + ok( ($yn =~ /!/ xor $res), $test_name ); + } + } + + if ( $yn =~ s/=// ) { + $tstr = "$right ~~ $left"; + goto test_again; + } + } +} + +sub foo {} +sub bar {42} +sub gorch {42} +sub fatal {die "fatal sub\n"} + +# to test constant folding +sub FALSE() { 0 } +sub TRUE() { 1 } +sub NOT_DEF() { undef } + +{ + # [perl #123860] + # this can but might not crash + # This can but might not crash + # + # The second smartmatch would leave a &PL_sv_no on the stack for + # each key it checked in %!, this could then cause various types of + # crash or assertion failure. + # + # This isn't guaranteed to crash, but if the stack issue is + # re-introduced it will probably crash in one of the many smoke + # builds. + fresh_perl_is('print (q(x) ~~ q(x)) | (/x/ ~~ %!)', "1", + { switches => [ "-MErrno", "-M-warnings=experimental::smartmatch" ] }, + "don't fill the stack with rubbish"); +} + +{ + # [perl #123860] continued; + # smartmatch was failing to SPAGAIN after pushing an SV and calling + # pp_match, which may have resulted in the stack being realloced + # in the meantime. Test this by filling the stack with pregressively + # larger amounts of data. At some point the stack will get realloced. + my @a = qw(x); + my %h = qw(x 1); + my @args; + my $x = 1; + my $bad = -1; + for (1..1000) { + push @args, $_; + my $exp_n = join '-', (@args, $x == 0); + my $exp_y = join '-', (@args, $x == 1); + + my $got_an = join '-', (@args, (/X/ ~~ @a)); + my $got_ay = join '-', (@args, (/x/ ~~ @a)); + my $got_hn = join '-', (@args, (/X/ ~~ %h)); + my $got_hy = join '-', (@args, (/x/ ~~ %h)); + + if ( $exp_n ne $got_an || $exp_n ne $got_hn + || $exp_y ne $got_ay || $exp_y ne $got_hy + ) { + $bad = $_; + last; + } + } + is($bad, -1, "RT 123860: stack realloc"); +} + + +{ + # [perl #130705] + # Perl_ck_smartmatch would turn the match in: + # 0 =~ qr/1/ ~~ 0 # parsed as (0 =~ qr/1/) ~~ 0 + # into a qr, leaving the initial 0 on the stack after execution + # + # Similarly for: 0 ~~ (0 =~ qr/1/) + # + # Either caused an assertion failure in the context of warn (or print) + # if there was some other operator's arguments left on the stack, as with + # the test cases. + fresh_perl_is('print(0->[0 =~ qr/1/ ~~ 0])', '', + { switches => [ "-M-warnings=experimental::smartmatch" ] }, + "don't qr-ify left-side match against a stacked argument"); + fresh_perl_is('print(0->[0 ~~ (0 =~ qr/1/)])', '', + { switches => [ "-M-warnings=experimental::smartmatch" ] }, + "don't qr-ify right-side match against a stacked argument"); } -my $matchvoidcontextcheck = bless({}, "MatchVoidContextCheck"); -ok scalar("abc" ~~ $matchscalarcontextcheck); -ok ["abc" ~~ $matchscalarcontextcheck]->[0]; -ok do { no warnings "void"; "abc" ~~ $matchvoidcontextcheck; 1 }; +# Prefix character : +# - expected to match +# ! - expected to not match +# @ - expected to be a compilation failure +# = - expected to match symmetrically (runs test twice) +# Data types to test : +# undef +# Object-overloaded +# Object +# Coderef +# Hash +# Hashref +# Array +# Arrayref +# Tied arrays and hashes +# Arrays that reference themselves +# Regex (// and qr//) +# Range +# Num +# Str +# Other syntactic items of interest: +# Constants +# Values returned by a sub call +__DATA__ +# Any ~~ undef +! $ov_obj undef +! $obj undef +! sub {} undef +! %hash undef +! \%hash undef +! {} undef +! @nums undef +! \@nums undef +! [] undef +! %tied_hash undef +! @tied_nums undef +! $deep1 undef +! /foo/ undef +! qr/foo/ undef +! 21..30 undef +! 189 undef +! "foo" undef +! "" undef +! !1 undef + undef undef + (my $u) undef + NOT_DEF undef + &NOT_DEF undef + +# Any ~~ object overloaded +! \&fatal $ov_obj + 'cigam' $ov_obj +! 'cigam on' $ov_obj +! ['cigam'] $ov_obj +! ['stringified'] $ov_obj +! { cigam => 1 } $ov_obj +! { stringified => 1 } $ov_obj +! $obj $ov_obj +! undef $ov_obj + +# regular object +@ $obj $obj +@ $ov_obj $obj +=@ \&fatal $obj +@ \&FALSE $obj +@ \&foo $obj +@ sub { 1 } $obj +@ sub { 0 } $obj +@ %keyandmore $obj +@ {"key" => 1} $obj +@ @fooormore $obj +@ ["key" => 1] $obj +@ /key/ $obj +@ qr/key/ $obj +@ "key" $obj +@ FALSE $obj + +# regular object with "" overload +@ $obj $str_obj +=@ \&fatal $str_obj +@ \&FALSE $str_obj +@ \&foo $str_obj +@ sub { 1 } $str_obj +@ sub { 0 } $str_obj +@ %keyandmore $str_obj +@ {"object" => 1} $str_obj +@ @fooormore $str_obj +@ ["object" => 1] $str_obj +@ /object/ $str_obj +@ qr/object/ $str_obj +@ "object" $str_obj +@ FALSE $str_obj +# Those will treat the $str_obj as a string because of fallback: + +# object (overloaded or not) ~~ Any + $obj qr/NoOverload/ + $ov_obj qr/^stringified$/ += "$ov_obj" "stringified" += "$str_obj" "object" +!= $ov_obj "stringified" + $str_obj "object" + $ov_obj 'magic' +! $ov_obj 'not magic' + +# ~~ Coderef + sub{0} sub { ref $_[0] eq "CODE" } + %fooormore sub { $_[0] =~ /^(foo|or|more)$/ } +! %fooormore sub { $_[0] =~ /^(foo|or|less)$/ } + \%fooormore sub { $_[0] =~ /^(foo|or|more)$/ } +! \%fooormore sub { $_[0] =~ /^(foo|or|less)$/ } + +{%fooormore} sub { $_[0] =~ /^(foo|or|more)$/ } +! +{%fooormore} sub { $_[0] =~ /^(foo|or|less)$/ } + @fooormore sub { $_[0] =~ /^(foo|or|more)$/ } +! @fooormore sub { $_[0] =~ /^(foo|or|less)$/ } + \@fooormore sub { $_[0] =~ /^(foo|or|more)$/ } +! \@fooormore sub { $_[0] =~ /^(foo|or|less)$/ } + [@fooormore] sub { $_[0] =~ /^(foo|or|more)$/ } +! [@fooormore] sub { $_[0] =~ /^(foo|or|less)$/ } + %fooormore sub{@_==1} + @fooormore sub{@_==1} + "foo" sub { $_[0] =~ /^(foo|or|more)$/ } +! "more" sub { $_[0] =~ /^(foo|or|less)$/ } + /fooormore/ sub{ref $_[0] eq 'Regexp'} + qr/fooormore/ sub{ref $_[0] eq 'Regexp'} + 1 sub{shift} +! 0 sub{shift} +! undef sub{shift} + undef sub{not shift} + NOT_DEF sub{not shift} + &NOT_DEF sub{not shift} + FALSE sub{not shift} + [1] \&bar + {a=>1} \&bar + qr// \&bar +! [1] \&foo +! {a=>1} \&foo + $obj sub { ref($_[0]) =~ /NoOverload/ } + $ov_obj sub { ref($_[0]) =~ /WithOverload/ } +# empty stuff matches, because the sub is never called: + [] \&foo + {} \&foo + @empty \&foo + %empty \&foo +! qr// \&foo +! undef \&foo + undef \&bar +@ undef \&fatal +@ 1 \&fatal +@ [1] \&fatal +@ {a=>1} \&fatal +@ "foo" \&fatal +@ qr// \&fatal +# sub is not called on empty hashes / arrays + [] \&fatal + +{} \&fatal + @empty \&fatal + %empty \&fatal +# sub is not special on the left + sub {0} qr/^CODE/ + sub {0} sub { ref shift eq "CODE" } + +# HASH ref against: +# - another hash ref + {} {} +=! {} {1 => 2} + {1 => 2} {1 => 2} + {1 => 2} {1 => 3} +=! {1 => 2} {2 => 3} += \%main:: {map {$_ => 'x'} keys %main::} + +# - tied hash ref += \%hash \%tied_hash + \%tied_hash \%tied_hash +!= {"a"=>"b"} \%tied_hash += %hash %tied_hash + %tied_hash %tied_hash +!= {"a"=>"b"} %tied_hash + $ov_obj %refh MINISKIP +! "$ov_obj" %refh MINISKIP + [$ov_obj] %refh MINISKIP +! ["$ov_obj"] %refh MINISKIP + %refh %refh MINISKIP + +# - an array ref +# (since this is symmetrical, tests as well hash~~array) += [keys %main::] \%:: += [qw[STDIN STDOUT]] \%:: +=! [] \%:: +=! [""] {} +=! [] {} +=! @empty {} += [undef] {"" => 1} += [""] {"" => 1} += ["foo"] { foo => 1 } += ["foo", "bar"] { foo => 1 } += ["foo", "bar"] \%hash += ["foo"] \%hash +=! ["quux"] \%hash += [qw(foo quux)] \%hash += @fooormore { foo => 1, or => 2, more => 3 } += @fooormore %fooormore += @fooormore \%fooormore += \@fooormore %fooormore + +# - a regex += qr/^(fo[ox])$/ {foo => 1} += /^(fo[ox])$/ %fooormore +=! qr/[13579]$/ +{0..99} +=! qr/a*/ {} += qr/a*/ {b=>2} += qr/B/i {b=>2} += /B/i {b=>2} +=! qr/a+/ {b=>2} += qr/^à / {"à "=>2} + +# - a scalar + "foo" +{foo => 1, bar => 2} + "foo" %fooormore +! "baz" +{foo => 1, bar => 2} +! "boz" %fooormore +! 1 +{foo => 1, bar => 2} +! 1 %fooormore + 1 { 1 => 3 } + 1.0 { 1 => 3 } +! "1.0" { 1 => 3 } +! "1.0" { 1.0 => 3 } + "1.0" { "1.0" => 3 } + "à " { "à " => "À" } + +# - undef +! undef { hop => 'zouu' } +! undef %hash +! undef +{"" => "empty key"} +! undef {} + +# ARRAY ref against: +# - another array ref + [] [] +=! [] [1] + [["foo"], ["bar"]] [qr/o/, qr/a/] +! [["foo"], ["bar"]] [qr/ARRAY/, qr/ARRAY/] + ["foo", "bar"] [qr/o/, qr/a/] +! [qr/o/, qr/a/] ["foo", "bar"] + ["foo", "bar"] [["foo"], ["bar"]] +! ["foo", "bar"] [qr/o/, "foo"] + ["foo", undef, "bar"] [qr/o/, undef, "bar"] +! ["foo", undef, "bar"] [qr/o/, "", "bar"] +! ["foo", "", "bar"] [qr/o/, undef, "bar"] + $deep1 $deep1 + @$deep1 @$deep1 +! $deep1 $deep2 + += \@nums \@tied_nums += @nums \@tied_nums += \@nums @tied_nums += @nums @tied_nums + +# - an object +! $obj @fooormore + $obj [sub{ref shift}] + +# - a regex += qr/x/ [qw(foo bar baz quux)] +=! qr/y/ [qw(foo bar baz quux)] += /x/ [qw(foo bar baz quux)] +=! /y/ [qw(foo bar baz quux)] += /FOO/i @fooormore +=! /bar/ @fooormore + +# - a number + 2 [qw(1.00 2.00)] + 2 [qw(foo 2)] + 2.0_0e+0 [qw(foo 2)] +! 2 [qw(1foo bar2)] + +# - a string +! "2" [qw(1foo 2bar)] + "2bar" [qw(1foo 2bar)] + +# - undef + undef [1, 2, undef, 4] +! undef [1, 2, [undef], 4] +! undef @fooormore + undef @sparse + undef [undef] +! 0 [undef] +! "" [undef] +! undef [0] +! undef [""] + +# - nested arrays and ~~ distributivity + 11 [[11]] +! 11 [[12]] + "foo" [{foo => "bar"}] +! "bar" [{foo => "bar"}] + +# Number against number + 2 2 + 20 2_0 +! 2 3 + 0 FALSE + 3-2 TRUE +! undef 0 +! (my $u) 0 + +# Number against string += 2 "2" += 2 "2.0" +! 2 "2bananas" +!= 2_3 "2_3" NOWARNINGS + FALSE "0" +! undef "0" +! undef "" + +# Regex against string + "x" qr/x/ +! "x" qr/y/ + +# Regex against number + 12345 qr/3/ +! 12345 qr/7/ + +# array/hash against string + @fooormore "".\@fooormore +! @keyandmore "".\@fooormore + %fooormore "".\%fooormore +! %keyandmore "".\%fooormore + +# Test the implicit referencing + 7 @nums + @nums \@nums +! @nums \\@nums + @nums [1..10] +! @nums [0..9] + + "foo" %hash + /bar/ %hash + [qw(bar)] %hash +! [qw(a b c)] %hash + %hash %hash + %hash +{%hash} + %hash \%hash + %hash %tied_hash + %tied_hash %tied_hash + %hash { foo => 5, bar => 10 } +! %hash { foo => 5, bar => 10, quux => 15 } + + @nums { 1, '', 2, '' } + @nums { 1, '', 12, '' } +! @nums { 11, '', 12, '' } + +# array slices + @nums[0..-1] [] + @nums[0..0] [1] +! @nums[0..1] [0..2] + @nums[0..4] [1..5] + +! undef @nums[0..-1] + 1 @nums[0..0] + 2 @nums[0..1] +! @nums[0..1] 2 -package MatchYieldUndef { use overload "~~" => sub { undef }; } -my $matchyieldundef = bless({}, "MatchYieldUndef"); -package MatchYieldFive { use overload "~~" => sub { 5 }; } -my $matchyieldfive = bless({}, "MatchYieldFive"); + @nums[0..1] @nums[0..1] -is +("abc" ~~ $matchyieldundef), !!0; -is +("abc" ~~ $matchyieldfive), !!1; +# hash slices + @keyandmore{qw(not)} [undef] + @keyandmore{qw(key)} [0] -package MatchCheckSwap { use overload "~~" => sub { ::ok $_[2]; 1 }; } -my $matchcheckswap = bless({}, "MatchCheckSwap"); + undef @keyandmore{qw(not)} + 0 @keyandmore{qw(key and more)} +! 2 @keyandmore{qw(key and)} -ok "abc" ~~ $matchcheckswap; + @fooormore{qw(foo)} @keyandmore{qw(key)} + @fooormore{qw(foo or more)} @keyandmore{qw(key and more)} -1; +# UNDEF +! 3 undef +! 1 undef +! [] undef +! {} undef +! \%::main undef +! [1,2] undef +! %hash undef +! @nums undef +! "foo" undef +! "" undef +! !1 undef +! \&foo undef +! sub { } undef diff --git a/t/op/state.t b/t/op/state.t index 7345814fc8..4fe67e13c5 100644 --- a/t/op/state.t +++ b/t/op/state.t @@ -342,8 +342,8 @@ my @spam = qw [spam ham bacon beans]; foreach my $spam (@spam) { no warnings 'experimental::smartmatch'; given (state $spam = $spam) { - whereso ($spam [0]) {ok 1, "given"} - ok 0, "given"; + when ($spam [0]) {ok 1, "given"} + default {ok 0, "given"} } } diff --git a/t/op/switch.t b/t/op/switch.t index 6d756afa86..e5385df0b4 100644 --- a/t/op/switch.t +++ b/t/op/switch.t @@ -10,7 +10,7 @@ use strict; use warnings; no warnings 'experimental::smartmatch'; -plan tests => 161; +plan tests => 195; # The behaviour of the feature pragma should be tested by lib/feature.t # using the tests in t/lib/feature/*. This file tests the behaviour of @@ -19,8 +19,8 @@ plan tests => 161; # Before loading feature, test the switch ops with CORE:: CORE::given(3) { - CORE::whereso(3) { pass "CORE::given and CORE::whereso"; continue } - pass "continue (without feature)"; + CORE::when(3) { pass "CORE::given and CORE::when"; continue } + CORE::default { pass "continue (without feature) and CORE::default" } } @@ -29,6 +29,9 @@ use feature 'switch'; eval { continue }; like($@, qr/^Can't "continue" outside/, "continue outside"); +eval { break }; +like($@, qr/^Can't "break" outside/, "break outside"); + # Scoping rules { @@ -42,7 +45,7 @@ like($@, qr/^Can't "continue" outside/, "continue outside"); sub be_true {1} given(my $x = "foo") { - whereso(be_true(my $x = "bar")) { + when(be_true(my $x = "bar")) { is($x, "bar", "given scope starts"); } is($x, "foo", "given scope ends"); @@ -57,10 +60,10 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } { my $ok; given(3) { - whereso($_ == 2) { $ok = 'two'; } - whereso($_ == 3) { $ok = 'three'; } - whereso($_ == 4) { $ok = 'four'; } - $ok = 'd'; + when(2) { $ok = 'two'; } + when(3) { $ok = 'three'; } + when(4) { $ok = 'four'; } + default { $ok = 'd'; } } is($ok, 'three', "numeric comparison"); } @@ -69,10 +72,10 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } my $ok; use integer; given(3.14159265) { - whereso($_ == 2) { $ok = 'two'; } - whereso($_ == 3) { $ok = 'three'; } - whereso($_ == 4) { $ok = 'four'; } - $ok = 'd'; + when(2) { $ok = 'two'; } + when(3) { $ok = 'three'; } + when(4) { $ok = 'four'; } + default { $ok = 'd'; } } is($ok, 'three', "integer comparison"); } @@ -80,10 +83,10 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } { my ($ok1, $ok2); given(3) { - whereso($_ == 3.1) { $ok1 = 'n'; } - whereso($_ == 3.0) { $ok1 = 'y'; continue } - whereso($_ == "3.0") { $ok2 = 'y'; } - $ok2 = 'n'; + when(3.1) { $ok1 = 'n'; } + when(3.0) { $ok1 = 'y'; continue } + when("3.0") { $ok2 = 'y'; } + default { $ok2 = 'n'; } } is($ok1, 'y', "more numeric (pt. 1)"); is($ok2, 'y', "more numeric (pt. 2)"); @@ -92,10 +95,10 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } { my $ok; given("c") { - whereso($_ eq "b") { $ok = 'B'; } - whereso($_ eq "c") { $ok = 'C'; } - whereso($_ eq "d") { $ok = 'D'; } - $ok = 'def'; + when("b") { $ok = 'B'; } + when("c") { $ok = 'C'; } + when("d") { $ok = 'D'; } + default { $ok = 'def'; } } is($ok, 'C', "string comparison"); } @@ -103,10 +106,10 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } { my $ok; given("c") { - whereso($_ eq "b") { $ok = 'B'; } - whereso($_ eq "c") { $ok = 'C'; continue } - whereso($_ eq "c") { $ok = 'CC'; } - $ok = 'D'; + when("b") { $ok = 'B'; } + when("c") { $ok = 'C'; continue } + when("c") { $ok = 'CC'; } + default { $ok = 'D'; } } is($ok, 'CC', "simple continue"); } @@ -114,45 +117,82 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } # Definedness { my $ok = 1; - given (0) { whereso(!defined) {$ok = 0} } - is($ok, 1, "Given(0) whereso(!defined)"); + given (0) { when(undef) {$ok = 0} } + is($ok, 1, "Given(0) when(undef)"); +} +{ + my $undef; + my $ok = 1; + given (0) { when($undef) {$ok = 0} } + is($ok, 1, 'Given(0) when($undef)'); +} +{ + my $undef; + my $ok = 0; + given (0) { when($undef++) {$ok = 1} } + is($ok, 1, "Given(0) when($undef++)"); } { no warnings "uninitialized"; my $ok = 1; - given (undef) { whereso(0) {$ok = 0} } - is($ok, 1, "Given(undef) whereso(0)"); + given (undef) { when(0) {$ok = 0} } + is($ok, 1, "Given(undef) when(0)"); } { no warnings "uninitialized"; my $undef; my $ok = 1; - given ($undef) { whereso(0) {$ok = 0} } - is($ok, 1, 'Given($undef) whereso(0)'); + given ($undef) { when(0) {$ok = 0} } + is($ok, 1, 'Given($undef) when(0)'); } ######## { my $ok = 1; - given ("") { whereso(!defined) {$ok = 0} } - is($ok, 1, 'Given("") whereso(!defined)'); + given ("") { when(undef) {$ok = 0} } + is($ok, 1, 'Given("") when(undef)'); +} +{ + my $undef; + my $ok = 1; + given ("") { when($undef) {$ok = 0} } + is($ok, 1, 'Given("") when($undef)'); +} +{ + no warnings "uninitialized"; + my $ok = 1; + given (undef) { when("") {$ok = 0} } + is($ok, 1, 'Given(undef) when("")'); } { no warnings "uninitialized"; + my $undef; my $ok = 1; - given (undef) { whereso(0) {$ok = 0} } - is($ok, 1, 'Given(undef) whereso(0)'); + given ($undef) { when("") {$ok = 0} } + is($ok, 1, 'Given($undef) when("")'); } ######## { my $ok = 0; - given (undef) { whereso(!defined) {$ok = 1} } - is($ok, 1, "Given(undef) whereso(!defined)"); + given (undef) { when(undef) {$ok = 1} } + is($ok, 1, "Given(undef) when(undef)"); +} +{ + my $undef; + my $ok = 0; + given (undef) { when($undef) {$ok = 1} } + is($ok, 1, 'Given(undef) when($undef)'); +} +{ + my $undef; + my $ok = 0; + given ($undef) { when(undef) {$ok = 1} } + is($ok, 1, 'Given($undef) when(undef)'); } { my $undef; my $ok = 0; - given ($undef) { whereso(!defined) {$ok = 1} } - is($ok, 1, 'Given($undef) whereso(!defined)'); + given ($undef) { when($undef) {$ok = 1} } + is($ok, 1, 'Given($undef) when($undef)'); } @@ -160,13 +200,13 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } { my ($ok1, $ok2); given("Hello, world!") { - whereso(/lo/) + when(/lo/) { $ok1 = 'y'; continue} - whereso(/no/) + when(/no/) { $ok1 = 'n'; continue} - whereso(/^(Hello,|Goodbye cruel) world[!.?]/) + when(/^(Hello,|Goodbye cruel) world[!.?]/) { $ok2 = 'Y'; continue} - whereso(/^(Hello cruel|Goodbye,) world[!.?]/) + when(/^(Hello cruel|Goodbye,) world[!.?]/) { $ok2 = 'n'; continue} } is($ok1, 'y', "regex 1"); @@ -179,11 +219,11 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } my $twenty_five = 25; my $ok; given($twenty_five) { - whereso ($_ < 10) { $ok = "ten" } - whereso ($_ < 20) { $ok = "twenty" } - whereso ($_ < 30) { $ok = "thirty" } - whereso ($_ < 40) { $ok = "forty" } - $ok = "default"; + when ($_ < 10) { $ok = "ten" } + when ($_ < 20) { $ok = "twenty" } + when ($_ < 30) { $ok = "thirty" } + when ($_ < 40) { $ok = "forty" } + default { $ok = "default" } } is($ok, "thirty", $test); } @@ -194,11 +234,11 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } my $twenty_five = 25; my $ok; given($twenty_five) { - whereso ($_ < 10) { $ok = "ten" } - whereso ($_ < 20) { $ok = "twenty" } - whereso ($_ < 30) { $ok = "thirty" } - whereso ($_ < 40) { $ok = "forty" } - $ok = "default"; + when ($_ < 10) { $ok = "ten" } + when ($_ < 20) { $ok = "twenty" } + when ($_ < 30) { $ok = "thirty" } + when ($_ < 40) { $ok = "forty" } + default { $ok = "default" } } is($ok, "thirty", $test); } @@ -208,11 +248,11 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } my $twenty_five = 25; my $ok; given($twenty_five) { - whereso ($_ <= 10) { $ok = "ten" } - whereso ($_ <= 20) { $ok = "twenty" } - whereso ($_ <= 30) { $ok = "thirty" } - whereso ($_ <= 40) { $ok = "forty" } - $ok = "default"; + when ($_ <= 10) { $ok = "ten" } + when ($_ <= 20) { $ok = "twenty" } + when ($_ <= 30) { $ok = "thirty" } + when ($_ <= 40) { $ok = "forty" } + default { $ok = "default" } } is($ok, "thirty", $test); } @@ -223,11 +263,11 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } my $twenty_five = 25; my $ok; given($twenty_five) { - whereso ($_ <= 10) { $ok = "ten" } - whereso ($_ <= 20) { $ok = "twenty" } - whereso ($_ <= 30) { $ok = "thirty" } - whereso ($_ <= 40) { $ok = "forty" } - $ok = "default"; + when ($_ <= 10) { $ok = "ten" } + when ($_ <= 20) { $ok = "twenty" } + when ($_ <= 30) { $ok = "thirty" } + when ($_ <= 40) { $ok = "forty" } + default { $ok = "default" } } is($ok, "thirty", $test); } @@ -238,11 +278,11 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } my $twenty_five = 25; my $ok; given($twenty_five) { - whereso ($_ > 40) { $ok = "forty" } - whereso ($_ > 30) { $ok = "thirty" } - whereso ($_ > 20) { $ok = "twenty" } - whereso ($_ > 10) { $ok = "ten" } - $ok = "default"; + when ($_ > 40) { $ok = "forty" } + when ($_ > 30) { $ok = "thirty" } + when ($_ > 20) { $ok = "twenty" } + when ($_ > 10) { $ok = "ten" } + default { $ok = "default" } } is($ok, "twenty", $test); } @@ -252,11 +292,11 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } my $twenty_five = 25; my $ok; given($twenty_five) { - whereso ($_ >= 40) { $ok = "forty" } - whereso ($_ >= 30) { $ok = "thirty" } - whereso ($_ >= 20) { $ok = "twenty" } - whereso ($_ >= 10) { $ok = "ten" } - $ok = "default"; + when ($_ >= 40) { $ok = "forty" } + when ($_ >= 30) { $ok = "thirty" } + when ($_ >= 20) { $ok = "twenty" } + when ($_ >= 10) { $ok = "ten" } + default { $ok = "default" } } is($ok, "twenty", $test); } @@ -267,11 +307,11 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } my $twenty_five = 25; my $ok; given($twenty_five) { - whereso ($_ > 40) { $ok = "forty" } - whereso ($_ > 30) { $ok = "thirty" } - whereso ($_ > 20) { $ok = "twenty" } - whereso ($_ > 10) { $ok = "ten" } - $ok = "default"; + when ($_ > 40) { $ok = "forty" } + when ($_ > 30) { $ok = "thirty" } + when ($_ > 20) { $ok = "twenty" } + when ($_ > 10) { $ok = "ten" } + default { $ok = "default" } } is($ok, "twenty", $test); } @@ -282,11 +322,11 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } my $twenty_five = 25; my $ok; given($twenty_five) { - whereso ($_ >= 40) { $ok = "forty" } - whereso ($_ >= 30) { $ok = "thirty" } - whereso ($_ >= 20) { $ok = "twenty" } - whereso ($_ >= 10) { $ok = "ten" } - $ok = "default"; + when ($_ >= 40) { $ok = "forty" } + when ($_ >= 30) { $ok = "thirty" } + when ($_ >= 20) { $ok = "twenty" } + when ($_ >= 10) { $ok = "ten" } + default { $ok = "default" } } is($ok, "twenty", $test); } @@ -297,11 +337,11 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } my $twenty_five = "25"; my $ok; given($twenty_five) { - whereso ($_ lt "10") { $ok = "ten" } - whereso ($_ lt "20") { $ok = "twenty" } - whereso ($_ lt "30") { $ok = "thirty" } - whereso ($_ lt "40") { $ok = "forty" } - $ok = "default"; + when ($_ lt "10") { $ok = "ten" } + when ($_ lt "20") { $ok = "twenty" } + when ($_ lt "30") { $ok = "thirty" } + when ($_ lt "40") { $ok = "forty" } + default { $ok = "default" } } is($ok, "thirty", $test); } @@ -311,11 +351,11 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } my $twenty_five = "25"; my $ok; given($twenty_five) { - whereso ($_ le "10") { $ok = "ten" } - whereso ($_ le "20") { $ok = "twenty" } - whereso ($_ le "30") { $ok = "thirty" } - whereso ($_ le "40") { $ok = "forty" } - $ok = "default"; + when ($_ le "10") { $ok = "ten" } + when ($_ le "20") { $ok = "twenty" } + when ($_ le "30") { $ok = "thirty" } + when ($_ le "40") { $ok = "forty" } + default { $ok = "default" } } is($ok, "thirty", $test); } @@ -325,11 +365,11 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } my $twenty_five = 25; my $ok; given($twenty_five) { - whereso ($_ ge "40") { $ok = "forty" } - whereso ($_ ge "30") { $ok = "thirty" } - whereso ($_ ge "20") { $ok = "twenty" } - whereso ($_ ge "10") { $ok = "ten" } - $ok = "default"; + when ($_ ge "40") { $ok = "forty" } + when ($_ ge "30") { $ok = "thirty" } + when ($_ ge "20") { $ok = "twenty" } + when ($_ ge "10") { $ok = "ten" } + default { $ok = "default" } } is($ok, "twenty", $test); } @@ -339,11 +379,11 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } my $twenty_five = 25; my $ok; given($twenty_five) { - whereso ($_ ge "40") { $ok = "forty" } - whereso ($_ ge "30") { $ok = "thirty" } - whereso ($_ ge "20") { $ok = "twenty" } - whereso ($_ ge "10") { $ok = "ten" } - $ok = "default"; + when ($_ ge "40") { $ok = "forty" } + when ($_ ge "30") { $ok = "thirty" } + when ($_ ge "20") { $ok = "twenty" } + when ($_ ge "10") { $ok = "ten" } + default { $ok = "default" } } is($ok, "twenty", $test); } @@ -352,8 +392,8 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } { my $ok; given(23) { - whereso (2 + 2 == 4) { $ok = 'y'; continue } - whereso (2 + 2 == 5) { $ok = 'n' } + when (2 + 2 == 4) { $ok = 'y'; continue } + when (2 + 2 == 5) { $ok = 'n' } } is($ok, 'y', "Optimized-away comparison"); } @@ -361,8 +401,8 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } { my $ok; given(23) { - whereso ($_ == scalar 24) { $ok = 'n'; continue } - $ok = 'y'; + when (scalar 24) { $ok = 'n'; continue } + default { $ok = 'y' } } is($ok,'y','scalar()'); } @@ -375,9 +415,9 @@ sub check_outside1 { is($_, "inside", "\$_ is not lexically scoped") } { my ($ok_d, $ok_f, $ok_r); given("op") { - whereso(-d) {$ok_d = 1; continue} - whereso(!-f) {$ok_f = 1; continue} - whereso(-r) {$ok_r = 1; continue} + when(-d) {$ok_d = 1; continue} + when(!-f) {$ok_f = 1; continue} + when(-r) {$ok_r = 1; continue} } ok($ok_d, "Filetest -d"); ok($ok_f, "Filetest -f"); @@ -389,7 +429,7 @@ sub notfoo {"bar"} { my $ok = 0; given("foo") { - whereso(notfoo()) {$ok = 1} + when(notfoo()) {$ok = 1} } ok($ok, "Sub call acts as boolean") } @@ -397,7 +437,7 @@ sub notfoo {"bar"} { my $ok = 0; given("foo") { - whereso(main->notfoo()) {$ok = 1} + when(main->notfoo()) {$ok = 1} } ok($ok, "Class-method call acts as boolean") } @@ -406,7 +446,7 @@ sub notfoo {"bar"} my $ok = 0; my $obj = bless []; given("foo") { - whereso($obj->notfoo()) {$ok = 1} + when($obj->notfoo()) {$ok = 1} } ok($ok, "Object-method call acts as boolean") } @@ -415,7 +455,7 @@ sub notfoo {"bar"} { my $ok = 0; given(12) { - whereso( /(\d+)/ and ( 1 <= $1 and $1 <= 12 ) ) { + when( /(\d+)/ and ( 1 <= $1 and $1 <= 12 ) ) { $ok = 1; } } @@ -425,7 +465,7 @@ sub notfoo {"bar"} { my $ok = 0; given(0) { - whereso(eof(DATA)) { + when(eof(DATA)) { $ok = 1; } } @@ -436,7 +476,7 @@ sub notfoo {"bar"} my $ok = 0; my %foo = ("bar", 0); given(0) { - whereso(exists $foo{bar}) { + when(exists $foo{bar}) { $ok = 1; } } @@ -446,7 +486,7 @@ sub notfoo {"bar"} { my $ok = 0; given(0) { - whereso(defined $ok) { + when(defined $ok) { $ok = 1; } } @@ -456,12 +496,12 @@ sub notfoo {"bar"} { my $ok = 1; given("foo") { - whereso((1 == 1) && "bar") { - $ok = 2; - } - whereso((1 == 1) && $_ eq "foo") { + when((1 == 1) && "bar") { $ok = 0; } + when((1 == 1) && $_ eq "foo") { + $ok = 2; + } } is($ok, 2, "((1 == 1) && \"bar\") not smartmatched"); } @@ -470,10 +510,10 @@ sub notfoo {"bar"} my $n = 0; for my $l (qw(a b c d)) { given ($l) { - whereso ($_ eq "b" .. $_ eq "c") { $n = 1 } - $n = 0; + when ($_ eq "b" .. $_ eq "c") { $n = 1 } + default { $n = 0 } } - ok(($n xor $l =~ /[ad]/), 'whereso(E1..E2) evaluates in boolean context'); + ok(($n xor $l =~ /[ad]/), 'when(E1..E2) evaluates in boolean context'); } } @@ -481,31 +521,31 @@ sub notfoo {"bar"} my $n = 0; for my $l (qw(a b c d)) { given ($l) { - whereso ($_ eq "b" ... $_ eq "c") { $n = 1 } - $n = 0; + when ($_ eq "b" ... $_ eq "c") { $n = 1 } + default { $n = 0 } } - ok(($n xor $l =~ /[ad]/), 'whereso(E1...E2) evaluates in boolean context'); + ok(($n xor $l =~ /[ad]/), 'when(E1...E2) evaluates in boolean context'); } } { my $ok = 0; given("foo") { - whereso((1 == $ok) || "foo") { + when((1 == $ok) || "foo") { $ok = 1; } } - ok($ok, '((1 == $ok) || "foo")'); + ok($ok, '((1 == $ok) || "foo") smartmatched'); } { my $ok = 0; given("foo") { - whereso((1 == $ok || undef) // "foo") { + when((1 == $ok || undef) // "foo") { $ok = 1; } } - ok($ok, '((1 == $ok || undef) // "foo")'); + ok($ok, '((1 == $ok || undef) // "foo") smartmatched'); } # Make sure we aren't invoking the get-magic more than once @@ -538,44 +578,60 @@ my $f = tie my $v, "FetchCounter"; { my $test_name = "Multiple FETCHes in given, due to aliasing"; my $ok; given($v = 23) { - whereso(!defined) {} - whereso(sub{0}->()) {} - whereso($_ == 21) {} - whereso($_ == "22") {} - whereso($_ == 23) {$ok = 1} - whereso(/24/) {$ok = 0} + when(undef) {} + when(sub{0}->()) {} + when(21) {} + when("22") {} + when(23) {$ok = 1} + when(/24/) {$ok = 0} } is($ok, 1, "precheck: $test_name"); is($f->count(), 4, $test_name); } -{ my $test_name = "Only one FETCH (numeric whereso)"; +{ my $test_name = "Only one FETCH (numeric when)"; my $ok; $v = 23; is($f->count(), 0, "Sanity check: $test_name"); given(23) { - whereso(!defined) {} - whereso(sub{0}->()) {} - whereso($_ == 21) {} - whereso($_ == "22") {} - whereso($_ == $v) {$ok = 1} - whereso(/24/) {$ok = 0} + when(undef) {} + when(sub{0}->()) {} + when(21) {} + when("22") {} + when($v) {$ok = 1} + when(/24/) {$ok = 0} } is($ok, 1, "precheck: $test_name"); is($f->count(), 1, $test_name); } -{ my $test_name = "Only one FETCH (string whereso)"; +{ my $test_name = "Only one FETCH (string when)"; my $ok; $v = "23"; is($f->count(), 0, "Sanity check: $test_name"); given("23") { - whereso(!defined) {} - whereso(sub{0}->()) {} - whereso($_ eq "21") {} - whereso($_ eq "22") {} - whereso($_ eq $v) {$ok = 1} - whereso(/24/) {$ok = 0} + when(undef) {} + when(sub{0}->()) {} + when("21") {} + when("22") {} + when($v) {$ok = 1} + when(/24/) {$ok = 0} + } + is($ok, 1, "precheck: $test_name"); + is($f->count(), 1, $test_name); +} + +{ my $test_name = "Only one FETCH (undef)"; + my $ok; + $v = undef; + is($f->count(), 0, "Sanity check: $test_name"); + no warnings "uninitialized"; + given(my $undef) { + when(sub{0}->()) {} + when("21") {} + when("22") {} + when($v) {$ok = 1} + when(undef) {$ok = 0} } is($ok, 1, "precheck: $test_name"); is($f->count(), 1, $test_name); @@ -585,12 +641,16 @@ my $f = tie my $v, "FetchCounter"; { my $first = 1; for (1, "two") { - whereso ($_ eq "two") { + when ("two") { is($first, 0, "Loop: second"); + eval {break}; + like($@, qr/^Can't "break" in a loop topicalizer/, + q{Can't "break" in a loop topicalizer}); } - whereso ($_ == 1) { + when (1) { is($first, 1, "Loop: first"); $first = 0; + # Implicit break is okay } } } @@ -598,12 +658,16 @@ my $f = tie my $v, "FetchCounter"; { my $first = 1; for $_ (1, "two") { - whereso ($_ eq "two") { + when ("two") { is($first, 0, "Explicit \$_: second"); + eval {break}; + like($@, qr/^Can't "break" in a loop topicalizer/, + q{Can't "break" in a loop topicalizer}); } - whereso ($_ == 1) { + when (1) { is($first, 1, "Explicit \$_: first"); $first = 0; + # Implicit break is okay } } } @@ -617,8 +681,8 @@ my $f = tie my $v, "FetchCounter"; sub bar {$called_bar = 1; "@_" eq "bar"} my ($matched_foo, $matched_bar) = (0, 0); given("foo") { - whereso((\&bar)->($_)) {$matched_bar = 1} - whereso((\&foo)->($_)) {$matched_foo = 1} + when(\&bar) {$matched_bar = 1} + when(\&foo) {$matched_foo = 1} } is($called_foo, 1, "foo() was called"); is($called_bar, 1, "bar() was called"); @@ -633,72 +697,148 @@ sub contains_x { { my ($ok1, $ok2) = (0,0); given("foxy!") { - whereso(contains_x($_)) + when(contains_x($_)) { $ok1 = 1; continue } - whereso((\&contains_x)->($_)) + when(\&contains_x) { $ok2 = 1; continue } } is($ok1, 1, "Calling sub directly (true)"); is($ok2, 1, "Calling sub indirectly (true)"); given("foggy") { - whereso(contains_x($_)) + when(contains_x($_)) { $ok1 = 2; continue } - whereso((\&contains_x)->($_)) + when(\&contains_x) { $ok2 = 2; continue } } is($ok1, 1, "Calling sub directly (false)"); is($ok2, 1, "Calling sub indirectly (false)"); } -{ - my($ea, $eb, $ec) = (0, 0, 0); - my $r; - given(3) { - whereso(do { $ea++; $_ == 2 }) { $r = "two"; } - whereso(do { $eb++; $_ == 3 }) { $r = "three"; } - whereso(do { $ec++; $_ == 4 }) { $r = "four"; } +SKIP: { + skip_if_miniperl("no dynamic loading on miniperl, no Scalar::Util", 14); + # Test overloading + { package OverloadTest; + + use overload '""' => sub{"string value of obj"}; + use overload 'eq' => sub{"$_[0]" eq "$_[1]"}; + + use overload "~~" => sub { + my ($self, $other, $reversed) = @_; + if ($reversed) { + $self->{left} = $other; + $self->{right} = $self; + $self->{reversed} = 1; + } else { + $self->{left} = $self; + $self->{right} = $other; + $self->{reversed} = 0; + } + $self->{called} = 1; + return $self->{retval}; + }; + + sub new { + my ($pkg, $retval) = @_; + bless { + called => 0, + retval => $retval, + }, $pkg; + } + } + + { + my $test = "Overloaded obj in given (true)"; + my $obj = OverloadTest->new(1); + my $matched; + given($obj) { + when ("other arg") {$matched = 1} + default {$matched = 0} + } + + is($obj->{called}, 1, "$test: called"); + ok($matched, "$test: matched"); + } + + { + my $test = "Overloaded obj in given (false)"; + my $obj = OverloadTest->new(0); + my $matched; + given($obj) { + when ("other arg") {$matched = 1} + } + + is($obj->{called}, 1, "$test: called"); + ok(!$matched, "$test: not matched"); + } + + { + my $test = "Overloaded obj in when (true)"; + my $obj = OverloadTest->new(1); + my $matched; + given("topic") { + when ($obj) {$matched = 1} + default {$matched = 0} + } + + is($obj->{called}, 1, "$test: called"); + ok($matched, "$test: matched"); + is($obj->{left}, "topic", "$test: left"); + is($obj->{right}, "string value of obj", "$test: right"); + ok($obj->{reversed}, "$test: reversed"); + } + + { + my $test = "Overloaded obj in when (false)"; + my $obj = OverloadTest->new(0); + my $matched; + given("topic") { + when ($obj) {$matched = 1} + default {$matched = 0} + } + + is($obj->{called}, 1, "$test: called"); + ok(!$matched, "$test: not matched"); + is($obj->{left}, "topic", "$test: left"); + is($obj->{right}, "string value of obj", "$test: right"); + ok($obj->{reversed}, "$test: reversed"); } - is $r, "three", "evaluation count"; - is $ea, 1, "evaluation count"; - is $eb, 1, "evaluation count"; - is $ec, 0, "evaluation count"; } -# Postfix whereso +# Postfix when { my $ok; given (undef) { - $ok = 1 whereso !defined; + $ok = 1 when undef; } - is($ok, 1, "postfix !defined"); + is($ok, 1, "postfix undef"); } { my $ok; given (2) { - $ok += 1 whereso $_ == 7; - $ok += 2 whereso $_ == 9.1685; - $ok += 4 whereso $_ > 4; - $ok += 8 whereso $_ < 2.5; + $ok += 1 when 7; + $ok += 2 when 9.1685; + $ok += 4 when $_ > 4; + $ok += 8 when $_ < 2.5; } is($ok, 8, "postfix numeric"); } { my $ok; given ("apple") { - $ok = 1, continue whereso $_ eq "apple"; + $ok = 1, continue when $_ eq "apple"; $ok += 2; - $ok = 0 whereso $_ eq "banana"; + $ok = 0 when "banana"; } is($ok, 3, "postfix string"); } { my $ok; given ("pear") { - do { $ok = 1; continue } whereso /pea/; + do { $ok = 1; continue } when /pea/; $ok += 2; - $ok = 0 whereso /pie/; - $ok += 4; next; + $ok = 0 when /pie/; + default { $ok += 4 } $ok = 0; } is($ok, 7, "postfix regex"); @@ -708,50 +848,70 @@ sub contains_x { my $x = "what"; given(my $x = "foo") { do { - is($x, "foo", "scope inside ... whereso my \$x = ..."); + is($x, "foo", "scope inside ... when my \$x = ..."); continue; - } whereso be_true(my $x = "bar"); - is($x, "bar", "scope after ... whereso my \$x = ..."); + } when be_true(my $x = "bar"); + is($x, "bar", "scope after ... when my \$x = ..."); } } { my $x = 0; given(my $x = 1) { - my $x = 2, continue whereso be_true(); - is($x, undef, "scope after my \$x = ... whereso ..."); + my $x = 2, continue when be_true(); + is($x, undef, "scope after my \$x = ... when ..."); } } -# Tests for last and next in whereso clauses +# Tests for last and next in when clauses my $letter; $letter = ''; +for ("a".."e") { + given ($_) { + $letter = $_; + when ("b") { last } + } + $letter = "z"; +} +is($letter, "b", "last in when"); + +$letter = ''; LETTER1: for ("a".."e") { given ($_) { $letter = $_; - whereso ($_ eq "b") { last LETTER1 } + when ("b") { last LETTER1 } } $letter = "z"; } -is($letter, "b", "last LABEL in whereso"); +is($letter, "b", "last LABEL in when"); + +$letter = ''; +for ("a".."e") { + given ($_) { + when (/b|d/) { next } + $letter .= $_; + } + $letter .= ','; +} +is($letter, "a,c,e,", "next in when"); $letter = ''; LETTER2: for ("a".."e") { given ($_) { - whereso (/b|d/) { next LETTER2 } + when (/b|d/) { next LETTER2 } $letter .= $_; } $letter .= ','; } -is($letter, "a,c,e,", "next LABEL in whereso"); +is($letter, "a,c,e,", "next LABEL in when"); -# Test goto with given/whereso +# Test goto with given/when { my $flag = 0; goto GIVEN1; $flag = 1; GIVEN1: given ($flag) { - whereso ($_ == 0) { next; } + when (0) { break; } $flag = 2; } is($flag, 0, "goto GIVEN1"); @@ -759,7 +919,7 @@ is($letter, "a,c,e,", "next LABEL in whereso"); { my $flag = 0; given ($flag) { - whereso ($_ == 0) { $flag = 1; } + when (0) { $flag = 1; } goto GIVEN2; $flag = 2; } @@ -769,32 +929,39 @@ GIVEN2: { my $flag = 0; given ($flag) { - whereso ($_ == 0) { $flag = 1; goto GIVEN3; $flag = 2; } + when (0) { $flag = 1; goto GIVEN3; $flag = 2; } $flag = 3; } GIVEN3: - is($flag, 1, "goto inside given and whereso"); + is($flag, 1, "goto inside given and when"); } { my $flag = 0; for ($flag) { - whereso ($_ == 0) { $flag = 1; goto GIVEN4; $flag = 2; } + when (0) { $flag = 1; goto GIVEN4; $flag = 2; } $flag = 3; } GIVEN4: - is($flag, 1, "goto inside for and whereso"); + is($flag, 1, "goto inside for and when"); } { my $flag = 0; GIVEN5: given ($flag) { - whereso ($_ == 0) { $flag = 1; goto GIVEN5; $flag = 2; } - whereso ($_ == 1) { next; } + when (0) { $flag = 1; goto GIVEN5; $flag = 2; } + when (1) { break; } $flag = 3; } - is($flag, 1, "goto inside given and whereso to the given stmt"); + is($flag, 1, "goto inside given and when to the given stmt"); } +# test with unreified @_ in smart match [perl #71078] +sub unreified_check { ok([@_] ~~ \@_) } # should always match +unreified_check(1,2,"lala"); +unreified_check(1,2,undef); +unreified_check(undef); +unreified_check(undef,""); + # Test do { given } as a rvalue { @@ -805,8 +972,8 @@ GIVEN5: no warnings 'void'; for (0, 1, 2) { my $scalar = do { given ($_) { - whereso ($_ == 0) { $lexical } - whereso ($_ == 2) { 'void'; 8, 9 } + when (0) { $lexical } + when (2) { 'void'; 8, 9 } @things; } }; is($scalar, shift(@exp), "rvalue given - simple scalar [$_]"); @@ -819,8 +986,8 @@ GIVEN5: for (0, 1, 2) { no warnings 'void'; my $scalar = do { given ($_) { - $lexical whereso $_ == 0; - 8, 9 whereso $_ == 2; + $lexical when 0; + 8, 9 when 2; 6, 7; } }; is($scalar, shift(@exp), "rvalue given - postfix scalar [$_]"); @@ -832,8 +999,9 @@ GIVEN5: for (0, 1, 2) { my $scalar = do { given ($_) { no warnings 'void'; - whereso ($_ == 0) { 5 } - 8, 9; + when (0) { 5 } + default { 8, 9 } + 6, 7; } }; is($scalar, shift(@exp), "rvalue given - default scalar [$_]"); } @@ -844,8 +1012,8 @@ GIVEN5: my @exp = ('3 4 5', '11 12 13', '8 9'); for (0, 1, 2) { my @list = do { given ($_) { - whereso ($_ == 0) { 3 .. 5 } - whereso ($_ == 2) { my $fake = 'void'; 8, 9 } + when (0) { 3 .. 5 } + when (2) { my $fake = 'void'; 8, 9 } @things; } }; is("@list", shift(@exp), "rvalue given - simple list [$_]"); @@ -857,8 +1025,8 @@ GIVEN5: my @exp = ('3 4 5', '6 7', '12'); for (0, 1, 2) { my @list = do { given ($_) { - 3 .. 5 whereso $_ == 0; - @things whereso $_ == 2; + 3 .. 5 when 0; + @things when 2; 6, 7; } }; is("@list", shift(@exp), "rvalue given - postfix list [$_]"); @@ -870,8 +1038,9 @@ GIVEN5: my @exp = ('m o o', '8 10', '8 10'); for (0, 1, 2) { my @list = do { given ($_) { - whereso ($_ == 0) { "moo" =~ /(.)/g } - 8, scalar(@things); + when (0) { "moo" =~ /(.)/g } + default { 8, scalar(@things) } + 6, 7; } }; is("@list", shift(@exp), "rvalue given - default list [$_]"); } @@ -879,11 +1048,11 @@ GIVEN5: { # Switch control my @exp = ('6 7', '', '6 7'); - F: for (0, 1, 2, 3) { + for (0, 1, 2, 3) { my @list = do { given ($_) { - continue whereso $_ <= 1; - next whereso $_ == 1; - next F whereso $_ == 2; + continue when $_ <= 1; + break when 1; + next when 2; 6, 7; } }; is("@list", shift(@exp), "rvalue given - default list [$_]"); @@ -893,9 +1062,9 @@ GIVEN5: # Context propagation my $smart_hash = sub { do { given ($_[0]) { - 'undef' whereso !defined; - whereso ($_ >= 1 && $_ <= 3) { 1 .. 3 } - whereso ($_ == 4) { my $fake; do { 4, 5 } } + 'undef' when undef; + when ([ 1 .. 3 ]) { 1 .. 3 } + when (4) { my $fake; do { 4, 5 } } } }; }; @@ -924,6 +1093,44 @@ GIVEN5: @list = $smart_hash->(999); is("@list", '', "rvalue given - list context propagation [999]"); } +{ + # Array slices + my @list = 10 .. 15; + my @in_list; + my @in_slice; + for (5, 10, 15) { + given ($_) { + when (@list) { + push @in_list, $_; + continue; + } + when (@list[0..2]) { + push @in_slice, $_; + } + } + } + is("@in_list", "10 15", "when(array)"); + is("@in_slice", "10", "when(array slice)"); +} +{ + # Hash slices + my %list = map { $_ => $_ } "a" .. "f"; + my @in_list; + my @in_slice; + for ("a", "e", "i") { + given ($_) { + when (%list) { + push @in_list, $_; + continue; + } + when (@list{"a".."c"}) { + push @in_slice, $_; + } + } + } + is("@in_list", "a e", "when(hash)"); + is("@in_slice", "a", "when(hash slice)"); +} { # RT#84526 - Handle magical TARG my $x = my $y = "aaa"; @@ -954,19 +1161,19 @@ GIVEN5: our $given_glob = 5; local $given_loc = 6; - whereso ($_ == 0) { 0 } + when (0) { 0 } - whereso ($_ == 1) { my $when_lex = 1 } - whereso ($_ == 2) { our $when_glob = 2 } - whereso ($_ == 3) { local $when_loc = 3 } + when (1) { my $when_lex = 1 } + when (2) { our $when_glob = 2 } + when (3) { local $when_loc = 3 } - whereso ($_ == 4) { $given_lex } - whereso ($_ == 5) { $given_glob } - whereso ($_ == 6) { $given_loc } + when (4) { $given_lex } + when (5) { $given_glob } + when (6) { $given_loc } - whereso ($_ == 7) { $ext_lex } - whereso ($_ == 8) { $ext_glob } - whereso ($_ == 9) { $ext_loc } + when (7) { $ext_lex } + when (8) { $ext_glob } + when (9) { $ext_loc } 'fallback'; } @@ -975,9 +1182,9 @@ GIVEN5: my @descriptions = qw< constant - whereso-lexical - whereso-global - whereso-local + when-lexical + when-global + when-local given-lexical given-global @@ -998,20 +1205,23 @@ GIVEN5: my $id_plus_1 = $id + 1; given ($id_plus_1) { do { - whereso (/\d/) { + when (/\d/) { --$id_plus_1; continue; 456; } }; - $tester->($id_plus_1); + default { + $tester->($id_plus_1); + } + 'XXX'; } }; is $res, $id, "across continue and default - $desc"; } } -# Check that values returned from given/whereso are destroyed at the right time. +# Check that values returned from given/when are destroyed at the right time. { { package Fmurrr; @@ -1029,8 +1239,8 @@ GIVEN5: } my @descriptions = qw< - whereso - next + when + break continue default >; @@ -1045,34 +1255,34 @@ GIVEN5: my $res = do { given ($id) { my $x; - whereso ($_ == 0) { Fmurrr->new($destroyed, 0) } - whereso ($_ == 1) { my $y = Fmurrr->new($destroyed, 1); next } - whereso ($_ == 2) { $x = Fmurrr->new($destroyed, 2); continue } - whereso ($_ == 2) { $x } - Fmurrr->new($destroyed, 3); + when (0) { Fmurrr->new($destroyed, 0) } + when (1) { my $y = Fmurrr->new($destroyed, 1); break } + when (2) { $x = Fmurrr->new($destroyed, 2); continue } + when (2) { $x } + default { Fmurrr->new($destroyed, 3) } } }; $res_id = $res->{id}; } - $res_id = $id if $id == 1; # next doesn't return anything + $res_id = $id if $id == 1; # break doesn't return anything - is $res_id, $id, "given/whereso returns the right object - $desc"; - is $destroyed, 1, "given/whereso does not leak - $desc"; + is $res_id, $id, "given/when returns the right object - $desc"; + is $destroyed, 1, "given/when does not leak - $desc"; }; } -# next() must reset the stack +# break() must reset the stack { my @res = (1, do { given ("x") { 2, 3, do { - whereso (/[a-z]/) { - 4, 5, 6, next + when (/[a-z]/) { + 4, 5, 6, break } } } }); - is "@res", "1", "next resets the stack"; + is "@res", "1", "break resets the stack"; } # RT #94682: @@ -1095,49 +1305,58 @@ GIVEN5: f2(); } -# check that 'whereso' handles all 'for' loop types +# check that 'when' handles all 'for' loop types { my $i; $i = 0; for (1..3) { - whereso ($_ == 1) {$i += 1 } - whereso ($_ == 2) {$i += 10 } - whereso ($_ == 3) {$i += 100 } - $i += 1000; + when (1) {$i += 1 } + when (2) {$i += 10 } + when (3) {$i += 100 } + default { $i += 1000 } } - is($i, 111, "whereso in for 1..3"); + is($i, 111, "when in for 1..3"); $i = 0; for ('a'..'c') { - whereso ($_ eq 'a') {$i += 1 } - whereso ($_ eq 'b') {$i += 10 } - whereso ($_ eq 'c') {$i += 100 } - $i += 1000; + when ('a') {$i += 1 } + when ('b') {$i += 10 } + when ('c') {$i += 100 } + default { $i += 1000 } } - is($i, 111, "whereso in for a..c"); + is($i, 111, "when in for a..c"); $i = 0; for (1,2,3) { - whereso ($_ == 1) {$i += 1 } - whereso ($_ == 2) {$i += 10 } - whereso ($_ == 3) {$i += 100 } - $i += 1000; + when (1) {$i += 1 } + when (2) {$i += 10 } + when (3) {$i += 100 } + default { $i += 1000 } } - is($i, 111, "whereso in for 1,2,3"); + is($i, 111, "when in for 1,2,3"); $i = 0; my @a = (1,2,3); for (@a) { - whereso ($_ == 1) {$i += 1 } - whereso ($_ == 2) {$i += 10 } - whereso ($_ == 3) {$i += 100 } - $i += 1000; + when (1) {$i += 1 } + when (2) {$i += 10 } + when (3) {$i += 100 } + default { $i += 1000 } } - is($i, 111, 'whereso in for @a'); + is($i, 111, 'when in for @a'); } +given("xyz") { + no warnings "void"; + my @a = (qw(a b c), do { when(/abc/) { qw(x y) } }, qw(d e f)); + is join(",", map { $_ // "u" } @a), "a,b,c,d,e,f", + "list value of false when"; + @a = (qw(a b c), scalar do { when(/abc/) { qw(x y) } }, qw(d e f)); + is join(",", map { $_ // "u" } @a), "a,b,c,u,d,e,f", + "scalar value of false when"; +} # Okay, that'll do for now. The intricacies of the smartmatch # semantics are tested in t/op/smartmatch.t. Taintedness of diff --git a/t/op/taint.t b/t/op/taint.t index e5a47996c5..9edaa55b03 100644 --- a/t/op/taint.t +++ b/t/op/taint.t @@ -17,7 +17,7 @@ BEGIN { use strict; use Config; -plan tests => 1039; +plan tests => 1041; $| = 1; @@ -2400,7 +2400,7 @@ end use feature 'switch'; no warnings 'experimental::smartmatch'; - my @descriptions = ('whereso', 'given end', 'default'); + my @descriptions = ('when', 'given end', 'default'); for (qw<x y z>) { my $letter = "$_$TAINT"; @@ -2409,8 +2409,9 @@ end my $res = do { given ($_) { - whereso ('x') { $letter } - whereso ('y') { goto leavegiven } + when ('x') { $letter } + when ('y') { goto leavegiven } + default { $letter } leavegiven: $letter } }; @@ -2431,6 +2432,14 @@ end ok(!tainted "", "tainting still works after index() of the constant"); } +# Tainted values with smartmatch +# [perl #93590] S_do_smartmatch stealing its own string buffers +{ +no warnings 'experimental::smartmatch'; +ok "M$TAINT" ~~ ['m', 'M'], '$tainted ~~ ["whatever", "match"]'; +ok !("M$TAINT" ~~ ['m', undef]), '$tainted ~~ ["whatever", undef]'; +} + # Tainted values and ref() for(1,2) { my $x = bless \"M$TAINT", ref(bless[], "main"); diff --git a/t/op/tie_fetch_count.t b/t/op/tie_fetch_count.t index 2b79f34e5e..d8b906d7ab 100644 --- a/t/op/tie_fetch_count.t +++ b/t/op/tie_fetch_count.t @@ -9,7 +9,7 @@ BEGIN { set_up_inc('../lib'); } -plan (tests => 342); +plan (tests => 343); use strict; use warnings; @@ -164,6 +164,10 @@ $dummy = -e -e -e $var ; check_count '-e -e'; $_ = "foo"; $dummy = $var =~ m/ / ; check_count 'm//'; $dummy = $var =~ s/ //; check_count 's///'; +{ + no warnings 'experimental::smartmatch'; + $dummy = $var ~~ 1 ; check_count '~~'; +} $dummy = $var =~ y/ //; check_count 'y///'; $var = \1; $dummy = $var =~y/ /-/; check_count '$ref =~ y///'; diff --git a/t/op/whereis.t b/t/op/whereis.t deleted file mode 100644 index c5bc778334..0000000000 --- a/t/op/whereis.t +++ /dev/null @@ -1,88 +0,0 @@ -#!./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 => 21; - -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"; - } -} - -foreach("xyz") { - no warnings "void"; - my @a = (qw(a b c), do { whereis($matchabc) { qw(x y) } }, qw(d e f)); - is join(",", map { $_ // "u" } @a), "a,b,c,d,e,f", - "list value of false whereis"; - @a = (qw(a b c), scalar do { whereis($matchabc) { qw(x y) } }, qw(d e f)); - is join(",", map { $_ // "u" } @a), "a,b,c,u,d,e,f", - "scalar value of false whereis"; -} - -1; diff --git a/t/op/whereso.t b/t/op/whereso.t deleted file mode 100644 index 992ecf740e..0000000000 --- a/t/op/whereso.t +++ /dev/null @@ -1,217 +0,0 @@ -#!./perl - -BEGIN { - chdir 't' if -d 't'; - require './test.pl'; - set_up_inc('../lib'); -} - -use strict; -use warnings; -no warnings 'experimental::smartmatch'; - -plan tests => 44; - -foreach(3) { - CORE::whereso(3) { - pass "CORE::whereso without feature flag"; - } -} - -use feature 'switch'; - -foreach(3) { - CORE::whereso(3) { - pass "CORE::whereso with feature flag"; - } -} - -foreach(3) { - whereso(3) { - pass "whereso with feature flag"; - } -} - -foreach(0, 1) { - my $x = "foo"; - is($x, "foo", "whereso lexical scope not started yet"); - whereso(my $x = ($_ && "bar")) { - is($x, "bar", "whereso lexical scope starts"); - } - is($x, "foo", "whereso lexical scope ends"); -} - -foreach(3) { - whereso($_ == 2) { fail; } - pass; -} - -foreach(3) { - whereso($_ == 3) { pass; } - fail; -} - -foreach(3) { - whereso($_ == 2) { fail; } - whereso($_ == 3) { pass; } - whereso($_ == 4) { fail; } - whereso($_ == 3) { fail; } -} - -foreach(undef, 3) { - whereso(undef) { fail; } - pass; -} - -foreach(undef, 1, 3) { - whereso(0) { fail; } - pass; -} - -foreach(undef, 1, 3) { - whereso(1) { pass; } - fail; -} - -sub is_list_context { wantarray } -sub is_scalar_context { !wantarray && defined(wantarray) } -sub is_void_context { !defined(wantarray) } -foreach(3) { - whereso(is_list_context()) { fail; } - pass; -} -foreach(3) { - whereso(is_scalar_context()) { pass; } - fail; -} -foreach(3) { - whereso(is_void_context()) { fail; } - pass; -} -foreach(3) { - whereso(is_list_context) { fail; } - pass; -} -foreach(3) { - whereso(is_scalar_context) { pass; } - fail; -} -foreach(3) { - whereso(is_void_context) { fail; } - pass; -} - -my $ps = "foo"; -foreach(3) { - whereso($ps) { pass; } - fail; -} -$ps = ""; -foreach(3) { - whereso($ps) { fail; } - pass; -} -our $gs = "bar"; -foreach(3) { - whereso($gs) { pass; } - fail; -} -$gs = ""; -foreach(3) { - whereso($gs) { fail; } - pass; -} -my @pa = qw(a b c d e); -foreach(3) { - whereso(@pa) { pass; } - fail; -} -@pa = (); -foreach(3) { - whereso(@pa) { fail; } - pass; -} -our @ga = qw(a b c d e); -foreach(3) { - whereso(@ga) { pass; } - fail; -} -@ga = (); -foreach(3) { - whereso(@ga) { fail; } - pass; -} -my %ph = qw(a b c d e f g h i j); -foreach(3) { - whereso(%ph) { pass; } - fail; -} -%ph = (); -foreach(3) { - whereso(%ph) { fail; } - pass; -} -our %gh = qw(a b c d e f g h i j); -foreach(3) { - whereso(%gh) { pass; } - fail; -} -%gh = (); -foreach(3) { - whereso(%gh) { fail; } - pass; -} - -my $one = 1; -foreach(3) { - whereso($one + 3) { pass; } - fail; -} -foreach(3) { - whereso($one - 1) { fail; } - pass; -} - -foreach(3) { - whereso(()) { fail; } - pass; -} - -foreach my $z (3) { - whereso(1) { pass; } - fail; -} - -my @a = qw(x y z); -my $act = ""; -while(@a) { - $act .= "[a@{[0+@a]}]"; - whereso(shift(@a) eq "y") { - $act .= "[b]"; - } - $act .= "[c]"; -} -is $act, "[a3][c][a2][b][a1][c]"; - -$act = ""; -{ - $act .= "[a]"; - whereso(0) { $act .= "[b]"; } - $act .= "[c]"; - whereso(1) { $act .= "[d]"; } - $act .= "[e]"; - whereso(1) { $act .= "[f]"; } -} -is $act, "[a][c][d]"; - -{ - no warnings "void"; - my @a = (qw(a b c), do { whereso(0) { qw(x y) } }, qw(d e f)); - is join(",", map { $_ // "u" } @a), "a,b,c,d,e,f", - "list value of false whereso"; - @a = (qw(a b c), scalar do { whereso(0) { qw(x y) } }, qw(d e f)); - is join(",", map { $_ // "u" } @a), "a,b,c,u,d,e,f", - "scalar value of false whereso"; -} - -1; diff --git a/t/run/switches.t b/t/run/switches.t index a9c49ae171..1b1f596374 100644 --- a/t/run/switches.t +++ b/t/run/switches.t @@ -12,7 +12,7 @@ BEGIN { BEGIN { require "./test.pl"; require "./loc_tools.pl"; } -plan(tests => 136); +plan(tests => 137); use Config; @@ -651,7 +651,12 @@ is( $r, "Hello, world!\n", "-E say" ); $r = runperl( - switches => [ '-E', '"no warnings q{experimental::smartmatch}; given(undef) {whereso(!defined) { say q(Hello, world!)"}}'] + switches => [ '-E', '"no warnings q{experimental::smartmatch}; undef ~~ undef and say q(Hello, world!)"'] +); +is( $r, "Hello, world!\n", "-E ~~" ); + +$r = runperl( + switches => [ '-E', '"no warnings q{experimental::smartmatch}; given(undef) {when(undef) { say q(Hello, world!)"}}'] ); is( $r, "Hello, world!\n", "-E given" ); @@ -316,6 +316,7 @@ static struct debug_tokens { { BITOROP, TOKENTYPE_OPNUM, "BITOROP" }, { COLONATTR, TOKENTYPE_NONE, "COLONATTR" }, { CONTINUE, TOKENTYPE_NONE, "CONTINUE" }, + { DEFAULT, TOKENTYPE_NONE, "DEFAULT" }, { DO, TOKENTYPE_NONE, "DO" }, { DOLSHARP, TOKENTYPE_NONE, "DOLSHARP" }, { DORDOR, TOKENTYPE_NONE, "DORDOR" }, @@ -374,7 +375,7 @@ static struct debug_tokens { { UNLESS, TOKENTYPE_IVAL, "UNLESS" }, { UNTIL, TOKENTYPE_IVAL, "UNTIL" }, { USE, TOKENTYPE_IVAL, "USE" }, - { WHERESO, TOKENTYPE_IVAL, "WHERESO" }, + { WHEN, TOKENTYPE_IVAL, "WHEN" }, { WHILE, TOKENTYPE_IVAL, "WHILE" }, { BAREWORD, TOKENTYPE_OPVAL, "BAREWORD" }, { YADAYADA, TOKENTYPE_IVAL, "YADAYADA" }, @@ -7777,6 +7778,9 @@ Perl_yylex(pTHX) case KEY_bless: LOP(OP_BLESS,XTERM); + case KEY_break: + FUN0(OP_BREAK); + case KEY_chop: UNI(OP_CHOP); @@ -7838,6 +7842,9 @@ Perl_yylex(pTHX) case KEY_chroot: UNI(OP_CHROOT); + case KEY_default: + PREBLOCK(DEFAULT); + case KEY_do: s = skipspace(s); if (*s == '{') @@ -8839,16 +8846,14 @@ Perl_yylex(pTHX) case KEY_vec: LOP(OP_VEC,XTERM); - case KEY_whereis: - case KEY_whereso: + case KEY_when: if (!PL_lex_allbrackets && PL_lex_fakeeof >= LEX_FAKEEOF_NONEXPR) return REPORT(0); - pl_yylval.ival = tmp == KEY_whereis; - /* diag_listed_as: whereso is experimental */ + pl_yylval.ival = CopLINE(PL_curcop); Perl_ck_warner_d(aTHX_ packWARN(WARN_EXPERIMENTAL__SMARTMATCH), - "%" UTF8f " is experimental", UTF8fARG(UTF, len, PL_tokenbuf)); - OPERATOR(WHERESO); + "when is experimental"); + OPERATOR(WHEN); case KEY_while: if (!PL_lex_allbrackets && PL_lex_fakeeof >= LEX_FAKEEOF_NONEXPR) diff --git a/universal.c b/universal.c index 30b70ac2f6..2262939b8d 100644 --- a/universal.c +++ b/universal.c @@ -986,34 +986,6 @@ XS(XS_re_regexp_pattern) NOT_REACHED; /* NOTREACHED */ } -XS(XS_Regexp_smartmatch); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Regexp_smartmatch) -{ - dXSARGS; - SV *regexp_sv, *matchee_sv; - REGEXP *rx; - regexp *prog; - const char *strstart, *strend; - STRLEN len; - - if (items != 3) - croak_xs_usage(cv, "regexp, matchee, swap"); - matchee_sv = SP[-1]; - regexp_sv = SP[-2]; - SP -= 2; - PUTBACK; - assert(SvROK(regexp_sv)); - rx = (REGEXP*)SvRV(regexp_sv); - assert(SvTYPE((SV*)rx) == SVt_REGEXP); - prog = ReANY(rx); - strstart = SvPV_const(matchee_sv, len); - assert(strstart); - strend = strstart + len; - TOPs = boolSV((RXp_MINLEN(prog) < 0 || len >= (STRLEN)RXp_MINLEN(prog)) && - CALLREGEXEC(rx, (char*)strstart, (char *)strend, - (char*)strstart, 0, matchee_sv, NULL, 0)); -} - #include "vutil.h" #include "vxs.inc" @@ -1048,9 +1020,6 @@ static const struct xsub_details details[] = { {"re::regnames", XS_re_regnames, ";$"}, {"re::regnames_count", XS_re_regnames_count, ""}, {"re::regexp_pattern", XS_re_regexp_pattern, "$"}, - {"Regexp::((", XS_Regexp_smartmatch, NULL}, - {"Regexp::()", XS_Regexp_smartmatch, NULL}, - {"Regexp::(~~", XS_Regexp_smartmatch, NULL}, }; STATIC OP* @@ -1139,9 +1108,6 @@ Perl_boot_core_UNIVERSAL(pTHX) *cvfile = (char *)file; Safefree(oldfile); } - - /* overload fallback flag for Regexp */ - sv_setiv(get_sv("Regexp::()", GV_ADD), 1); } /* |