From 7896dde7482a2851e73f0ac2c32d1c71f6e97dca Mon Sep 17 00:00:00 2001 From: Zefram Date: Fri, 29 Dec 2017 12:39:31 +0000 Subject: [PATCH] revert smartmatch to 5.27.6 behaviour The pumpking has determined that the CPAN breakage caused by changing smartmatch [perl #132594] is too great for the smartmatch changes to stay in for 5.28. This reverts most of the merge in commit da4e040f42421764ef069371d77c008e6b801f45. All core behaviour and documentation is reverted. The removal of use of smartmatch from a couple of tests (that aren't testing smartmatch) remains. Customisation of a couple of CPAN modules to make them portable across smartmatch types remains. A small bugfix in scope.c also remains. --- MANIFEST | 3 - cop.h | 24 +- dump.c | 4 +- embed.fnc | 24 +- embed.h | 20 +- ext/B/B.pm | 2 +- ext/B/t/f_map.t | 4 +- ext/B/t/optree_samples.t | 20 +- ext/Opcode/Opcode.pm | 8 +- ext/Pod-Functions/Functions_pm.PL | 2 +- ext/Pod-Functions/t/Functions.t | 2 +- gv.c | 5 +- inline.h | 47 +- keywords.c | 181 ++-- keywords.h | 467 +++++------ lib/B/Deparse-core.t | 6 +- lib/B/Deparse.pm | 65 +- lib/B/Deparse.t | 54 +- lib/B/Op_private.pm | 10 +- lib/feature.pm | 4 +- lib/overload.pm | 31 +- lib/overload.t | 12 +- op.c | 302 +++++-- op.h | 3 + opcode.h | 280 ++++--- opnames.h | 358 ++++---- perl.h | 11 +- perly.act | 838 ++++++++++--------- perly.h | 93 +-- perly.tab | 1640 +++++++++++++++++++------------------ perly.y | 24 +- pod/perldiag.pod | 80 +- pod/perlexperiment.pod | 8 +- pod/perlfunc.pod | 56 +- pod/perlintro.pod | 4 +- pod/perlop.pod | 298 ++++++- pod/perlrun.pod | 1 + pod/perlsyn.pod | 529 +++++++++--- pod/perltrap.pod | 5 +- pp_ctl.c | 689 ++++++++++++++-- pp_proto.h | 6 +- proto.h | 64 +- regen/feature.pl | 4 +- regen/keywords.pl | 10 +- regen/op_private | 1 + regen/opcodes | 10 +- scope.c | 1 - sv.c | 7 +- t/lib/croak/pp_ctl | 12 +- t/lib/feature/switch | 104 ++- t/lib/warnings/9uninit | 7 + t/lib/warnings/op | 2 +- t/lib/warnings/utf8 | 5 +- t/op/coreamp.t | 20 +- t/op/coresubs.t | 2 +- t/op/cproto.t | 7 +- t/op/given.t | 238 ------ t/op/smartmatch.t | 661 +++++++++++++-- t/op/state.t | 4 +- t/op/switch.t | 765 +++++++++++------ t/op/taint.t | 17 +- t/op/tie_fetch_count.t | 6 +- t/op/whereis.t | 88 -- t/op/whereso.t | 217 ----- t/run/switches.t | 9 +- toke.c | 19 +- universal.c | 34 - 67 files changed, 5146 insertions(+), 3388 deletions(-) delete mode 100644 t/op/given.t delete mode 100644 t/op/whereis.t delete mode 100644 t/op/whereso.t diff --git a/MANIFEST b/MANIFEST index f34c9ee..e152251 100644 --- a/MANIFEST +++ b/MANIFEST @@ -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 diff --git a/cop.h b/cop.h index f685357..5c66752 100644 --- a/cop.h +++ b/cop.h @@ -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)) \ diff --git a/dump.c b/dump.c index 2636ad8..b2f0fc5 100644 --- a/dump.c +++ b/dump.c @@ -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"); diff --git a/embed.fnc b/embed.fnc index 6af7e76..ecec8cd 100644 --- a/embed.fnc +++ b/embed.fnc @@ -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 diff --git a/embed.h b/embed.h index b491b76..2f2f93a 100644 --- a/embed.h +++ b/embed.h @@ -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 86d24a5..ce061e4 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 893d010..221f292 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 a791889..15b5799 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 e8f429e..9d97ef1 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 bd0e3da..04b1a90 100644 --- a/ext/Pod-Functions/Functions_pm.PL +++ b/ext/Pod-Functions/Functions_pm.PL @@ -207,7 +207,7 @@ L 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 2330114..2beccc1 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 diff --git a/gv.c b/gv.c index 9fd4a8e..00adb89 100644 --- a/gv.c +++ b/gv.c @@ -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: diff --git a/inline.h b/inline.h index 18926d3..40c3f89 100644 --- a/inline.h +++ b/inline.h @@ -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 23e6145..9fa30e6 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 d65879a..2b1d598 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 4071e5e..6ee935f 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 d10e6a0..86f262a 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 576cd74..00fbb01 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 1bf9c57..25e9a8c 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 e9cf2f7..70df619 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 tells the compiler to enable the +C tells the compiler to enable the Perl 6 given/when construct. See L for details. diff --git a/lib/overload.pm b/lib/overload.pm index 45c4895..b19c5a5 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 The key C<"~~"> allows you to override the smart matching logic used by -the C<~~> operator. See L. -Unusually, the overloaded only takes effect for the right-hand operand. +the C<~~> operator and the switch construct (C/C). See +L and L. + +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 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 for +details of when overloading is invoked. =item * I diff --git a/lib/overload.t b/lib/overload.t index 99f5b64..2afa6cf 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)) :' diff --git a/op.c b/op.c index d988648..b59433c 100644 --- a/op.c +++ b/op.c @@ -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 block. -C supplies the expression to whose value C<$_> will be locally +C supplies the expression to whose value C<$_> will be locally aliased, and C supplies the body of the C construct; they are consumed by this function and become part of the constructed op tree. C must be zero (it used to identity the pad slot of lexical $_). @@ -8804,64 +8990,49 @@ C 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 block. +Constructs, checks, and returns an op tree expressing a C block. C supplies the test expression, and C 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 +will be interpreted DWIMically, often as a comparison against C<$_>, +and may be null to generate a C 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) diff --git a/op.h b/op.h index efafcf3..eb62c94 100644 --- a/op.h +++ b/op.h @@ -129,6 +129,9 @@ Deprecated. Use C 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, diff --git a/opcode.h b/opcode.h index ae54c3a..2556a01 100644 --- a/opcode.h +++ b/opcode.h @@ -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), diff --git a/opnames.h b/opnames.h index b6a63fd..d87ba88 100644 --- a/opnames.h +++ b/opnames.h @@ -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 diff --git a/perl.h b/perl.h index de44f91..f82efb7 100644 --- a/perl.h +++ b/perl.h @@ -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", diff --git a/perly.act b/perly.act index 42c9c02..610963f 100644 --- a/perly.act +++ b/perly.act @@ -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: */ diff --git a/perly.h b/perly.h index 02561f7..765d07c 100644 --- a/perly.h +++ b/perly.h @@ -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: */ diff --git a/perly.tab b/perly.tab index 001de77..f4be1fc 100644 --- a/perly.tab +++ b/perly.tab @@ -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: */ diff --git a/perly.y b/perly.y index 4ef8478..8f3e303 100644 --- a/perly.y +++ b/perly.y @@ -53,7 +53,7 @@ %token LABEL %token FORMAT SUB ANONSUB PACKAGE USE %token WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR -%token GIVEN WHERESO +%token GIVEN WHEN DEFAULT %token LOOPEX DOTDOT YADAYADA %token FUNC0 FUNC1 FUNC UNIOP LSTOP %token 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 c977924..cca35e8 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 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 on an array that does not @@ -759,6 +752,15 @@ to compress something else. See L. (F) Only hard references may be blessed. This is how Perl "enforces" encapsulation of objects. See L. +=item Can't "break" in a loop topicalizer + +(F) You called C, but you're in a C block rather than +a C block. You probably meant to use C or C. + +=item Can't "break" outside a given block + +(F) You called C, but you're not inside a C 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, but you're not inside a C or -C block. +(F) You called C, but you're not inside a C +or C 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 block that is neither inside a +C loop nor a C block. (Note that this error is +issued on exit from the C block, so you won't get the +error if you use an explicit C.) + =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. -=item Can't leave "whereso" outside a loop block - -(F) Control reached the end of a C or C block that -isn't inside any loop (including a C block). An implicit C -occurs here, which requires a loop to jump to. You probably wanted the -C or C to be inside a C block. Note that you -won't get this error if the match controlling the C or C -fails, or if you use an explicit C to avoid reaching the end -of the block. But if you rely on not reaching the implicit C -then you probably didn't want C or C, but rather C. - =item Can't linearize anonymous symbol table (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 +loop nor a C block. (Note that this error is issued on exit +from the C block, so you won't get the error if the match fails, +or if you use an explicit C.) + =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. =item given is experimental -(S experimental::smartmatch) C is experimental, and its behavior -may change or it may even be removed in any future release of perl. -See the explanation under L. +(S experimental::smartmatch) C 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. =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 is experimental, and its behavior -may change or it may even be removed in any future release of perl. -See the explanation under L. - -=item whereso is experimental +=item when is experimental -(S experimental::smartmatch) C is experimental, and its behavior -may change or it may even be removed in any future release of perl. -See the explanation under L. +(S experimental::smartmatch) C 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. =item Wide character in %s diff --git a/pod/perlexperiment.pod b/pod/perlexperiment.pod index 57be588..3918080 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. @@ -28,10 +28,6 @@ C. 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/C/C). - =item Pluggable keywords The ticket for this feature is diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod index 901d5c8..c13e533 100644 --- a/pod/perlfunc.pod +++ b/pod/perlfunc.pod @@ -256,7 +256,7 @@ X =for Pod::Functions =Flow -L|/caller EXPR>, +L|/break>, L|/caller EXPR>, L|/continue BLOCK>, L|/die LIST>, L|/do BLOCK>, L|/dump LABEL>, L|/eval EXPR>, L|/evalbytes EXPR>, L|/exit EXPR>, @@ -267,9 +267,16 @@ L|/redo LABEL>, L|/return EXPR>, L|/sub NAME BLOCK>, L|/__SUB__>, L|/wantarray> -In Perl v5.14 and earlier, L|/continue BLOCK> -required the L feature|feature/The 'switch' feature> to -be enabled. +L|/break> is available only if you enable the experimental +L feature|feature/The 'switch' feature> or use the C +prefix. The L feature|feature/The 'switch' feature> also +enables the C, C and C statements, which are +documented in L. +The L feature|feature/The 'switch' feature> is enabled +automatically with a C (or higher) declaration in the current +scope. In Perl v5.14 and earlier, L|/continue BLOCK> +required the L feature|feature/The 'switch' feature>, like +the other keywords. L|/evalbytes EXPR> is only available with the L feature|feature/The 'unicode_eval' and 'evalbytes' features> @@ -420,10 +427,10 @@ L|/time>, L|/times> =for Pod::Functions =!Non-functions C, C, C, C, C, C, C<__DATA__>, -C, C, C, C, C, C<__END__>, +C, C, C, C, C, C, C<__END__>, C, C, C, C, C, C, C, C, C, -C, C, C, C, C, C, C, -C, C, C, C, C +C, C, C, C, C, C, C, C, +C, C, C =back @@ -905,6 +912,19 @@ uses the result of L|/ref EXPR> as a truth value. See L. +=item break + +=for Pod::Functions +switch break out of a C block + +Break out of a C block. + +L|/break> is available only if the +L feature|feature/The 'switch' feature> is enabled or if it +is prefixed with C. The +L feature|feature/The 'switch' feature> is enabled +automatically with a C (or higher) declaration in the current +scope. + =item caller EXPR X X X X @@ -1322,10 +1342,9 @@ using an empty one, logically enough, so L|/next LABEL> goes directly back to check the condition at the top of the loop. When there is no BLOCK, L|/continue BLOCK> is a function -that exits the current C or C block, -avoiding the implicit C -that happens when execution reaches the end of such a block. -In Perl 5.14 and earlier, this form of +that falls through the current C or C block instead of +iterating a dynamically enclosing C or exiting a lexically +enclosing C. In Perl 5.14 and earlier, this form of L|/continue BLOCK> was only available when the L feature|feature/The 'switch' feature> was enabled. See L and L for more information. @@ -3810,8 +3829,7 @@ value such as C, C, or C, and should not be used to exit a L|/grep BLOCK LIST> or L|/map BLOCK LIST> operation. -Note that a block by itself or a C construct -is semantically identical to a loop +Note that a block by itself is semantically identical to a loop that executes once. Thus L|/last LABEL> can be used to effect an early exit out of such a block. @@ -4341,8 +4359,7 @@ value such as C, C, or C, and should not be used to exit a L|/grep BLOCK LIST> or L|/map BLOCK LIST> operation. -Note that a block by itself or a C construct -is semantically identical to a loop +Note that a block by itself is semantically identical to a loop that executes once. Thus L|/next LABEL> will exit such a block early. @@ -6306,8 +6323,7 @@ value such as C, C, or C, and should not be used to exit a L|/grep BLOCK LIST> or L|/map BLOCK LIST> operation. -Note that a block by itself or a C construct -is semantically identical to a loop +Note that a block by itself is semantically identical to a loop that executes once. Thus L|/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. diff --git a/pod/perlintro.pod b/pod/perlintro.pod index f0ab70a..5c168c1 100644 --- a/pod/perlintro.pod +++ b/pod/perlintro.pod @@ -326,8 +326,8 @@ running the program. Using C 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/C). 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/C). See L 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 82e9e75..023353c 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 construct described in L, although +not all C clauses call the smartmatch operator. Unique among all of +Perl's operators, the smartmatch operator can recurse. The smartmatch operator is L 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 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 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 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> and C> entries apply in those cases. +For blessed references, the C> 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 does +not. Also, C 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 +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>, 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 clause. See the section on "Switch Statements" in L. + +=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". 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. + +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 operator returns. That +means that + + $object ~~ X + +does I invoke the overload method with C> as an argument. +Instead the above table is consulted as normal, and based on the type of +C>, 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 X X<&> diff --git a/pod/perlrun.pod b/pod/perlrun.pod index 20080db..a50ebe2 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 a081242..74e228d 100644 --- a/pod/perlsyn.pod +++ b/pod/perlsyn.pod @@ -118,7 +118,7 @@ as the last item in a statement. =head2 Statement Modifiers X X X X X -X X X X X +X X X X Any simple statement may optionally be followed by a I modifier, just before the terminating semicolon (or block ending). The possible @@ -130,8 +130,7 @@ modifiers are: until EXPR for LIST foreach LIST - whereis EXPR - whereso EXPR + when EXPR The C 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 -The C and C modifiers are an experimental feature -that first appeared with this spelling in Perl 5.28. To use them, you -should include a C declaration, or a declaration -that implies it. They behave like the full C or C -statement with block, described in L below. -They executes the statement only if the I is true for C, -or C<$_> smartmatches the I for C. If the statement -executes, control then implicitly jumps to the end of the dynamically -enclosing loop (usually a C block). +The C modifier is an experimental feature that first appeared in Perl +5.14. To use it, you should include a C declaration. +(Technically, it requires only the C feature, but that aspect of it +was not available before 5.14.) Operative only from within a C +loop or a C block, it executes the statement only if the smartmatch +C<< $_ ~~ I >> is true. If the statement executes, it is followed by +a C from inside a C and C from inside a C. + +Under the current implementation, the C loop can be +anywhere within the C modifier's dynamic scope, but must be +within the C block's lexical scope. This restriction may +be relaxed in a future release. See L below. =head2 Compound Statements X X X X X @@ -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, C, and C statements are I; see L below for how to do -so, and the attendant caveats. +The experimental C statement is I; see +L 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--no @@ -610,8 +608,8 @@ The BLOCK construct can be used to emulate case structures. $nothing = 1; } -You'll also find the C loop used to establish a topic for -a switch: +You'll also find that C 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 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 X X X X +X X X X X -C, C, and related keywords make up an experimental feature -that first appeared in Perl 5.10, but behaved quite differently from -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, -C, and C. Starting from Perl 5.16, one can -prefix the switch keywords with C to access the feature without -a C statement. - -The "switch" feature is considered highly experimental; it is subject -to change with little notice. Uses of the C, C, and -C keywords will by default warn about their experimental status. -These warnings are in the same category as warnings about the C<~~> -(smartmatch) operator being experimental. - -The keywords C and C or C -are analogous to C and C -in C. They're meant to be used together, but can actually be used -independently and mixed with other kinds of compound statement. - -C 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 loop that always has -exactly one item to iterate over. -A C construct even counts as a one-iteration loop for the purposes -of loop control, so the C operator can be used to restart its block, -and C or C can be used to exit the block early. - -C 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, jumping to the end of the closest -dynamically enclosing C block or other kind of loop. - -C evaluates its argument and uses it as a smartmatch object, -checking whether C<$_> matches it. If C<$_> did not match then it does -not execute its block, and proceeds to the following statement. If C<$_> -did match, it executes the block, then implicitly performs a C, -jumping to the end of the closest dynamically enclosing C block -or other kind of loop. This is exactly like C, except for the -implicit use of smartmatch. - -Putting this together, the code in the previous section could be -rewritten as +Under the "switch" feature, Perl gains the experimental keywords +C, C, C, C, and C. +Starting from Perl 5.16, one can prefix the switch +keywords with C to access the feature without a C +statement. The keywords C and +C are analogous to C and +C in other languages -- though C 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, it can be written with -less punctuation as +The C is the non-experimental way to set a topicalizer. +If you wish to use the highly experimental C, 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 keyword to exit a C or C -block, proceeding to the following statement. This is most commonly -done last thing inside the block, to override the implicit C. -For example +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 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 or C is encountered. - -=item * - -The value of the last evaluated expression of the successful -C or C clause, if there happens to be one. - -=item * - -The value of the last evaluated expression of the C 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 block. -Note that, unlike C and C, -failed C/C 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 and the related keywords -behave quite differently from their present behaviour. If your code needs -to run on older versions, avoid C, C, and C. +The arguments to C and C are in scalar context, +and C assigns the C<$_> variable its topic value. + +Exactly what the I argument to C does is hard to describe +precisely, but in general, it tries to guess what you want done. Sometimes +it is interpreted as C<< $_ ~~ I >>, and sometimes it is not. It +also behaves differently when lexically enclosed by a C block than +it does when dynamically enclosed by a C loop. The rules are far +too difficult to understand to be described here. See L later on. + +Due to an unfortunate bug in how C was implemented between Perl 5.10 +and 5.16, under those implementations the version of C<$_> governed by +C 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 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 for your topicalizer and +you will be less unhappy. =head2 Goto X @@ -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 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 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: + + 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 assigned the value of I to +merely a lexically scoped I> (!) of C<$_>, not a dynamically +scoped alias the way C does. That made it similar to + + do { my $_ = EXPR; ... } + +except that the block was automatically broken out of by a successful +C or an explicit C. 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 loop. In particular, +it did not work for arbitrary function calls if those functions might try +to access $_. Best stick to C for that. + +Most of the power comes from the implicit smartmatching that can +sometimes apply. Most of the time, C is treated as an +implicit smartmatch of C<$_>, that is, C<$_ ~~ EXPR>. (See +L for more information on smartmatching.) +But when I 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, C<$foo =~ /REGEX/>, +or C<$foo =~ EXPR>. Also, a negated regular expression match in +the form C, C<$foo !~ /REGEX/>, or C<$foo !~ EXPR>. + +=item Z<>3. + +A smart match that uses an explicit C<~~> operator, such as C. + +B 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 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, C, C, C, C, and C). + +=item Z<>5. + +At least the three builtin functions C, C, and +C. We might someday add more of these later if we think of them. + +=item Z<>6. + +A negated expression, whether C or C, 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 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 or C, the test is applied +I to both EXPR1 and EXPR2. +Only if I operands also pass the +test, I, will the expression be treated as boolean. Otherwise, +smartmatching is used. + +=item Z<>10. + +If EXPR is C, C, or C, the +test is applied I 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 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 fallthrough +functionality--see below), wherein the same block is used for several +C statements. + +Another useful shortcut is that, if you use a literal array or hash as the +argument to C, it is turned into a reference. So C is +the same as C, for example. + +C behaves exactly like C, which is +to say that it always matches. + +=head3 Breaking out + +You can use the C keyword to break out of the enclosing +C block. Every C block is implicitly ended with +a C. + +=head3 Fall-through + +You can use the C keyword to fall through from one +case to the next immediate C or C: + + 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 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 is encountered. + +=item * + +The value of the last evaluated expression of the successful +C/C clause, if there happens to be one. + +=item * + +The value of the last evaluated expression of the C 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 block. + +Note that, unlike C and C, failed C 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 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, you can use a C 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 blocks, there is an implicit C. +You can override that with an explicit C if you're +interested in only the first match alone. + +This doesn't work if you explicitly specify a loop variable, as +in C. You have to use the default variable C<$_>. + +=head3 Differences from Perl 6 + +The Perl 5 smartmatch and C/C 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 and C (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, C, or C; 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 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 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 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 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 7830b72..acb4392 100644 --- a/pod/perltrap.pod +++ b/pod/perltrap.pod @@ -170,9 +170,8 @@ C construct. See L. =item * -The switch statement is called C/C and only available -in its current form in perl 5.28 or newer. See L. +The switch statement is called C/C and only available in +perl 5.10 or newer. See L. =item * diff --git a/pp_ctl.c b/pp_ctl.c index a97761d..e6d39f2 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -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 304e0f2..407cbd1 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); diff --git a/proto.h b/proto.h index 18ba0a1..9c50197 100644 --- a/proto.h +++ b/proto.h @@ -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 8cad2c4..3ce2a6d 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 tells the compiler to enable the +C tells the compiler to enable the Perl 6 given/when construct. See L for details. diff --git a/regen/keywords.pl b/regen/keywords.pl index b794a6b..9619d86 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 7085f5b..eb53edf 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 476279b..5aa8a94 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. diff --git a/scope.c b/scope.c index b09a25d..83a7b76 100644 --- a/scope.c +++ b/scope.c @@ -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: diff --git a/sv.c b/sv.c index 278bd6f..5d3290d 100644 --- a/sv.c +++ b/sv.c @@ -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 5c98769..2943bf7 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 5e6269f..0dee7f5 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 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 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 3963d66..774c6ee 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 52ef378..a6434ff 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 2ac8ac9..a9a6388 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 c2b53a6..7231d66 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 6946496..62210b5 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 11cd9ad..fec9fe6 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 () { 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 1187171..0000000 --- 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 8b48fce..10d3539 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 () { + 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 7345814..4fe67e1 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 6d756af..e5385df 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 e5a4799..9edaa55 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) { 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 2b79f34..d8b906d 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 c5bc778..0000000 --- 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 992ecf7..0000000 --- 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 a9c49ae..1b1f596 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" ); diff --git a/toke.c b/toke.c index 1519d41..6e27427 100644 --- a/toke.c +++ b/toke.c @@ -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 30b70ac..2262939 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); } /* -- 1.8.3.1