summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MANIFEST10
-rw-r--r--cop.h22
-rw-r--r--embed.fnc15
-rw-r--r--embed.h46
-rw-r--r--ext/B/B/Deparse.pm49
-rw-r--r--ext/B/t/concise-xs.t1
-rw-r--r--ext/B/t/f_map.t4
-rw-r--r--ext/B/t/optree_samples.t20
-rw-r--r--ext/IO/lib/IO/Handle.pm11
-rw-r--r--ext/Opcode/Opcode.pm7
-rw-r--r--global.sym2
-rw-r--r--keywords.h457
-rwxr-xr-xkeywords.pl5
-rw-r--r--lib/feature.pm116
-rw-r--r--lib/feature.t10
-rw-r--r--lib/overload.pm7
-rw-r--r--lib/warnings.t198
-rw-r--r--op.c226
-rw-r--r--op.h9
-rw-r--r--opcode.h40
-rwxr-xr-xopcode.pl11
-rw-r--r--opnames.h12
-rw-r--r--perl.h14
-rw-r--r--perl_keyword.pl71
-rw-r--r--perly.act767
-rw-r--r--perly.h172
-rw-r--r--perly.tab1458
-rw-r--r--perly.y29
-rw-r--r--pod/perldiag.pod17
-rw-r--r--pod/perlfunc.pod38
-rw-r--r--pod/perlop.pod8
-rw-r--r--pod/perlsyn.pod231
-rw-r--r--pp.sym10
-rw-r--r--pp_ctl.c666
-rw-r--r--pp_proto.h10
-rw-r--r--proto.h44
-rw-r--r--t/io/say.t49
-rw-r--r--t/lib/feature/nonesuch12
-rw-r--r--t/lib/feature/say64
-rw-r--r--t/lib/feature/smartmatch45
-rw-r--r--t/lib/feature/switch158
-rw-r--r--t/op/cproto.t2
-rw-r--r--t/op/smartmatch.t163
-rw-r--r--t/op/switch.t801
-rw-r--r--toke.c147
45 files changed, 4485 insertions, 1769 deletions
diff --git a/MANIFEST b/MANIFEST
index 8c53662d5c..7260b76028 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1540,6 +1540,8 @@ lib/ExtUtils/xsubpp External subroutine preprocessor
lib/fastcwd.pl a faster but more dangerous getcwd
lib/Fatal.pm Make errors in functions/builtins fatal
lib/Fatal.t See if Fatal works
+lib/feature.pm Pragma to enable new syntax
+lib/feature.t See if features work
lib/fields.pm Set up object field names for pseudo-hash-using classes
lib/File/Basename.pm Emulate the basename program
lib/File/Basename.t See if File::Basename works
@@ -2937,12 +2939,14 @@ t/io/open.t See if open works
t/io/pipe.t See if secure pipes work
t/io/print.t See if print commands work
t/io/read.t See if read works
+t/io/say.t See if say works
t/io/tell.t See if file seeking works
t/io/through.t See if pipe passes data intact
t/io/utf8.t See if file seeking works
t/japh/abigail.t Obscure tests
t/lib/1_compile.t See if the various libraries and extensions compile
t/lib/commonsense.t See if configuration meets basic needs
+t/lib/common.pl Helper for lib/{warnings,feature}.t
t/lib/compmod.pl Helper for 1_compile.t
t/lib/contains_pod.xr Pod-Parser test file
t/lib/cygwin.t Builtin cygwin function tests
@@ -2965,6 +2969,10 @@ t/lib/dprof/test7_v Perl code profiler tests
t/lib/dprof/test8_t Perl code profiler tests
t/lib/dprof/test8_v Perl code profiler tests
t/lib/dprof/V.pm Perl code profiler tests
+t/lib/feature/nonesuch Tests for enabling/disabling nonexistent feature
+t/lib/feature/say Tests for enabling/disabling say feature
+t/lib/feature/smartmatch Tests for enabling/disabling smartmatch feature
+t/lib/feature/switch Tests for enabling/disabling switch feature
t/lib/Filter/Simple/ExportTest.pm Helper file for Filter::Simple tests
t/lib/Filter/Simple/FilterOnlyTest.pm Helper file for Filter::Simple tests
t/lib/Filter/Simple/FilterTest.pm Helper file for Filter::Simple tests
@@ -3183,6 +3191,7 @@ t/op/re_tests Regular expressions for regexp.t
t/op/reverse.t See if reverse operator works
t/op/runlevel.t See if die() works from perl_call_*()
t/op/sleep.t See if sleep works
+t/op/smartmatch.t See if the ~~ operator works
t/op/sort.t See if sort works
t/op/splice.t See if splice works
t/op/split.t See if split works
@@ -3199,6 +3208,7 @@ t/op/substr.t See if substr works
t/op/subst.t See if substitution works
t/op/subst_wamp.t See if substitution works with $& present
t/op/sub.t See if subroutines work
+t/op/switch.t See if switches (given/when) work
t/op/sysio.t See if sysread and syswrite work
t/op/taint.t See if tainting works
t/op/threads.t Misc. tests for perl features with threads
diff --git a/cop.h b/cop.h
index eccb7958c0..2444a756fd 100644
--- a/cop.h
+++ b/cop.h
@@ -419,6 +419,16 @@ struct block_loop {
if (cx->blk_loop.iterary && cx->blk_loop.iterary != PL_curstack)\
SvREFCNT_dec(cx->blk_loop.iterary);
+/* given/when context */
+struct block_givwhen {
+ OP *leave_op;
+};
+
+#define PUSHGIVEN(cx) \
+ cx->blk_givwhen.leave_op = cLOGOP->op_other;
+
+#define PUSHWHEN PUSHGIVEN
+
/* context common to subroutines, evals and loops */
struct block {
I32 blku_oldsp; /* stack pointer to copy stuff down to */
@@ -432,6 +442,7 @@ struct block {
struct block_sub blku_sub;
struct block_eval blku_eval;
struct block_loop blku_loop;
+ struct block_givwhen blku_givwhen;
} blk_u;
};
#define blk_oldsp cx_u.cx_blk.blku_oldsp
@@ -443,6 +454,7 @@ struct block {
#define blk_sub cx_u.cx_blk.blk_u.blku_sub
#define blk_eval cx_u.cx_blk.blk_u.blku_eval
#define blk_loop cx_u.cx_blk.blk_u.blku_loop
+#define blk_givwhen cx_u.cx_blk.blk_u.blku_givwhen
/* Enter a block. */
#define PUSHBLOCK(cx,t,sp) CXINC, cx = &cxstack[cxstack_ix], \
@@ -545,6 +557,8 @@ struct context {
#define CXt_SUBST 4
#define CXt_BLOCK 5
#define CXt_FORMAT 6
+#define CXt_GIVEN 7
+#define CXt_WHEN 8
/* private flags for CXt_SUB and CXt_NULL */
#define CXp_MULTICALL 0x00000400 /* part of a multicall (so don't
@@ -554,8 +568,10 @@ struct context {
#define CXp_REAL 0x00000100 /* truly eval'', not a lookalike */
#define CXp_TRYBLOCK 0x00000200 /* eval{}, not eval'' or similar */
-#ifdef USE_ITHREADS
/* private flags for CXt_LOOP */
+#define CXp_FOREACH 0x00000200 /* a foreach loop */
+#define CXp_FOR_DEF 0x00000400 /* foreach using $_ */
+#ifdef USE_ITHREADS
# define CXp_PADVAR 0x00000100 /* itervar lives on pad, iterdata
has pad offset; if not set,
iterdata holds GV* */
@@ -570,6 +586,10 @@ struct context {
== (CXt_EVAL|CXp_REAL))
#define CxTRYBLOCK(c) (((c)->cx_type & (CXt_EVAL|CXp_TRYBLOCK)) \
== (CXt_EVAL|CXp_TRYBLOCK))
+#define CxFOREACH(c) (((c)->cx_type & (CXt_LOOP|CXp_FOREACH)) \
+ == (CXt_LOOP|CXp_FOREACH))
+#define CxFOREACHDEF(c) (((c)->cx_type & (CXt_LOOP|CXp_FOREACH|CXp_FOR_DEF))\
+ == (CXt_LOOP|CXp_FOREACH|CXp_FOR_DEF))
#define CXINC (cxstack_ix < cxstack_max ? ++cxstack_ix : (cxstack_ix = cxinc()))
diff --git a/embed.fnc b/embed.fnc
index 958672dbc8..eb19e98dcd 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -509,6 +509,7 @@ Apd |CV* |newCONSTSUB |NULLOK HV* stash|NULLOK const char* name|NULLOK SV* sv
Ap |void |newFORM |I32 floor|NULLOK OP* o|NULLOK OP* block
Apa |OP* |newFOROP |I32 flags|NULLOK char* label|line_t forline \
|NULLOK OP* sv|NN OP* expr|NULLOK OP* block|NULLOK OP* cont
+Apa |OP* |newGIVENOP |NN OP* cond|NN OP* block|PADOFFSET defsv_off
Apa |OP* |newLOGOP |I32 optype|I32 flags|NN OP* left|NN OP* right
Apa |OP* |newLOOPEX |I32 type|NN OP* label
Apa |OP* |newLOOPOP |I32 flags|I32 debuggable|NULLOK OP* expr|NULLOK OP* block
@@ -552,6 +553,7 @@ Apa |SV* |vnewSVpvf |NN const char* pat|NULLOK va_list* args
Apda |SV* |newSVrv |NN SV* rv|NULLOK const char* classname
Apda |SV* |newSVsv |NULLOK SV* old
Apa |OP* |newUNOP |I32 type|I32 flags|NULLOK OP* first
+Apa |OP* |newWHENOP |NULLOK OP* cond|NN OP* block
Apa |OP* |newWHILEOP |I32 flags|I32 debuggable|NULLOK LOOP* loop \
|I32 whileline|NULLOK OP* expr|NULLOK OP* block|NULLOK OP* cont \
|I32 has_my
@@ -1084,6 +1086,7 @@ pR |OP* |ck_return |NN OP *o
pR |OP* |ck_rfun |NN OP *o
pR |OP* |ck_rvconst |NN OP *o
pR |OP* |ck_sassign |NN OP *o
+pR |OP* |ck_say |NN OP *o
pR |OP* |ck_select |NN OP *o
pR |OP* |ck_shift |NN OP *o
pR |OP* |ck_sort |NN OP *o
@@ -1113,6 +1116,11 @@ s |void |no_bareword_allowed|NN const OP *o
sR |OP* |no_fh_allowed|NN OP *o
sR |OP* |too_few_arguments|NN OP *o|NN const char* name
sR |OP* |too_many_arguments|NN OP *o|NN const char* name
+s |bool |looks_like_bool|NN 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
#endif
#if defined(PL_OP_SLAB_ALLOC)
Apa |void* |Slab_Alloc |int m|size_t sz
@@ -1172,16 +1180,22 @@ sR |OP* |dofindlabel |NN OP *o|NN const char *label|NN OP **opstack|NN OP **opli
sR |OP* |doparseform |NN SV *sv
snR |bool |num_overflow |NV value|I32 fldsize|I32 frcsize
sR |I32 |dopoptoeval |I32 startingblock
+sR |I32 |dopoptogiven |I32 startingblock
sR |I32 |dopoptolabel |NN const char *label
sR |I32 |dopoptoloop |I32 startingblock
sR |I32 |dopoptosub |I32 startingblock
sR |I32 |dopoptosub_at |NN const PERL_CONTEXT* cxstk|I32 startingblock
+sR |I32 |dopoptowhen |I32 startingblock
s |void |save_lines |NULLOK AV *array|NN SV *sv
sR |OP* |doeval |int gimme|NULLOK OP** startop|NULLOK CV* outside|U32 seq
sR |PerlIO *|check_type_and_open|NN const char *name|NN const char *mode
sR |PerlIO *|doopen_pm |NN const char *name|NN const char *mode
sR |bool |path_is_absolute|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
#endif
#if defined(PERL_IN_PP_HOT_C) || defined(PERL_DECL_PROT)
@@ -1338,6 +1352,7 @@ s |char* |scan_word |NN char *s|NN char *dest|STRLEN destlen \
sR |char* |skipspace |NN char *s
sR |char* |swallow_bom |NN U8 *s
s |void |checkcomma |NN char *s|NN const char *name|NN const char *what
+s |bool |feature_is_enabled|NN char* name|STRLEN namelen
s |void |force_ident |NN const char *s|int kind
s |void |incline |NN char *s
s |int |intuit_method |NN char *s|NULLOK GV *gv
diff --git a/embed.h b/embed.h
index 5b1916a3aa..9788e82ecd 100644
--- a/embed.h
+++ b/embed.h
@@ -520,6 +520,7 @@
#define newCONSTSUB Perl_newCONSTSUB
#define newFORM Perl_newFORM
#define newFOROP Perl_newFOROP
+#define newGIVENOP Perl_newGIVENOP
#define newLOGOP Perl_newLOGOP
#define newLOOPEX Perl_newLOOPEX
#define newLOOPOP Perl_newLOOPOP
@@ -563,6 +564,7 @@
#define newSVrv Perl_newSVrv
#define newSVsv Perl_newSVsv
#define newUNOP Perl_newUNOP
+#define newWHENOP Perl_newWHENOP
#define newWHILEOP Perl_newWHILEOP
#define new_stackinfo Perl_new_stackinfo
#define scan_vstring Perl_scan_vstring
@@ -1097,6 +1099,7 @@
#define ck_rfun Perl_ck_rfun
#define ck_rvconst Perl_ck_rvconst
#define ck_sassign Perl_ck_sassign
+#define ck_say Perl_ck_say
#define ck_select Perl_ck_select
#define ck_shift Perl_ck_shift
#define ck_sort Perl_ck_sort
@@ -1126,6 +1129,9 @@
#define no_fh_allowed S_no_fh_allowed
#define too_few_arguments S_too_few_arguments
#define too_many_arguments S_too_many_arguments
+#define looks_like_bool S_looks_like_bool
+#define newGIVWHENOP S_newGIVWHENOP
+#define ref_array_or_hash S_ref_array_or_hash
#endif
#endif
#if defined(PL_OP_SLAB_ALLOC)
@@ -1192,16 +1198,22 @@
#define doparseform S_doparseform
#define num_overflow S_num_overflow
#define dopoptoeval S_dopoptoeval
+#define dopoptogiven S_dopoptogiven
#define dopoptolabel S_dopoptolabel
#define dopoptoloop S_dopoptoloop
#define dopoptosub S_dopoptosub
#define dopoptosub_at S_dopoptosub_at
+#define dopoptowhen S_dopoptowhen
#define save_lines S_save_lines
#define doeval S_doeval
#define check_type_and_open S_check_type_and_open
#define doopen_pm S_doopen_pm
#define path_is_absolute S_path_is_absolute
#define run_user_filter S_run_user_filter
+#define make_matcher S_make_matcher
+#define matcher_matches_sv S_matcher_matches_sv
+#define destroy_matcher S_destroy_matcher
+#define do_smartmatch S_do_smartmatch
#endif
#endif
#if defined(PERL_IN_PP_HOT_C) || defined(PERL_DECL_PROT)
@@ -1368,6 +1380,7 @@
#define skipspace S_skipspace
#define swallow_bom S_swallow_bom
#define checkcomma S_checkcomma
+#define feature_is_enabled S_feature_is_enabled
#define force_ident S_force_ident
#define incline S_incline
#define intuit_method S_intuit_method
@@ -1707,8 +1720,10 @@
#define ck_rfun Perl_ck_rfun
#define ck_rvconst Perl_ck_rvconst
#define ck_sassign Perl_ck_sassign
+#define ck_say Perl_ck_say
#define ck_select Perl_ck_select
#define ck_shift Perl_ck_shift
+#define ck_smartmatch Perl_ck_smartmatch
#define ck_sort Perl_ck_sort
#define ck_spair Perl_ck_spair
#define ck_split Perl_ck_split
@@ -1739,6 +1754,7 @@
#define pp_bit_or Perl_pp_bit_or
#define pp_bit_xor Perl_pp_bit_xor
#define pp_bless Perl_pp_bless
+#define pp_break Perl_pp_break
#define pp_caller Perl_pp_caller
#define pp_chdir Perl_pp_chdir
#define pp_chmod Perl_pp_chmod
@@ -1754,6 +1770,7 @@
#define pp_cond_expr Perl_pp_cond_expr
#define pp_connect Perl_pp_connect
#define pp_const Perl_pp_const
+#define pp_continue Perl_pp_continue
#define pp_cos Perl_pp_cos
#define pp_crypt Perl_pp_crypt
#define pp_dbmclose Perl_pp_dbmclose
@@ -1773,10 +1790,12 @@
#define pp_enetent Perl_pp_enetent
#define pp_enter Perl_pp_enter
#define pp_entereval Perl_pp_entereval
+#define pp_entergiven Perl_pp_entergiven
#define pp_enteriter Perl_pp_enteriter
#define pp_enterloop Perl_pp_enterloop
#define pp_entersub Perl_pp_entersub
#define pp_entertry Perl_pp_entertry
+#define pp_enterwhen Perl_pp_enterwhen
#define pp_enterwrite Perl_pp_enterwrite
#define pp_eof Perl_pp_eof
#define pp_eprotoent Perl_pp_eprotoent
@@ -1886,10 +1905,12 @@
#define pp_le Perl_pp_le
#define pp_leave Perl_pp_leave
#define pp_leaveeval Perl_pp_leaveeval
+#define pp_leavegiven Perl_pp_leavegiven
#define pp_leaveloop Perl_pp_leaveloop
#define pp_leavesub Perl_pp_leavesub
#define pp_leavesublv Perl_pp_leavesublv
#define pp_leavetry Perl_pp_leavetry
+#define pp_leavewhen Perl_pp_leavewhen
#define pp_leavewrite Perl_pp_leavewrite
#define pp_left_shift Perl_pp_left_shift
#define pp_length Perl_pp_length
@@ -1979,6 +2000,7 @@
#define pp_rv2hv Perl_pp_rv2hv
#define pp_rv2sv Perl_pp_rv2sv
#define pp_sassign Perl_pp_sassign
+#define pp_say Perl_pp_say
#define pp_scalar Perl_pp_scalar
#define pp_schomp Perl_pp_schomp
#define pp_schop Perl_pp_schop
@@ -2009,6 +2031,7 @@
#define pp_sle Perl_pp_sle
#define pp_sleep Perl_pp_sleep
#define pp_slt Perl_pp_slt
+#define pp_smartmatch Perl_pp_smartmatch
#define pp_sne Perl_pp_sne
#define pp_snetent Perl_pp_snetent
#define pp_socket Perl_pp_socket
@@ -2542,6 +2565,7 @@
#define newCONSTSUB(a,b,c) Perl_newCONSTSUB(aTHX_ a,b,c)
#define newFORM(a,b,c) Perl_newFORM(aTHX_ a,b,c)
#define newFOROP(a,b,c,d,e,f,g) Perl_newFOROP(aTHX_ a,b,c,d,e,f,g)
+#define newGIVENOP(a,b,c) Perl_newGIVENOP(aTHX_ a,b,c)
#define newLOGOP(a,b,c,d) Perl_newLOGOP(aTHX_ a,b,c,d)
#define newLOOPEX(a,b) Perl_newLOOPEX(aTHX_ a,b)
#define newLOOPOP(a,b,c,d) Perl_newLOOPOP(aTHX_ a,b,c,d)
@@ -2584,6 +2608,7 @@
#define newSVrv(a,b) Perl_newSVrv(aTHX_ a,b)
#define newSVsv(a) Perl_newSVsv(aTHX_ a)
#define newUNOP(a,b,c) Perl_newUNOP(aTHX_ a,b,c)
+#define newWHENOP(a,b) Perl_newWHENOP(aTHX_ a,b)
#define newWHILEOP(a,b,c,d,e,f,g,h) Perl_newWHILEOP(aTHX_ a,b,c,d,e,f,g,h)
#define new_stackinfo(a,b) Perl_new_stackinfo(aTHX_ a,b)
#define scan_vstring(a,b) Perl_scan_vstring(aTHX_ a,b)
@@ -3108,6 +3133,7 @@
#define ck_rfun(a) Perl_ck_rfun(aTHX_ a)
#define ck_rvconst(a) Perl_ck_rvconst(aTHX_ a)
#define ck_sassign(a) Perl_ck_sassign(aTHX_ a)
+#define ck_say(a) Perl_ck_say(aTHX_ a)
#define ck_select(a) Perl_ck_select(aTHX_ a)
#define ck_shift(a) Perl_ck_shift(aTHX_ a)
#define ck_sort(a) Perl_ck_sort(aTHX_ a)
@@ -3137,6 +3163,9 @@
#define no_fh_allowed(a) S_no_fh_allowed(aTHX_ a)
#define too_few_arguments(a,b) S_too_few_arguments(aTHX_ a,b)
#define too_many_arguments(a,b) S_too_many_arguments(aTHX_ a,b)
+#define looks_like_bool(a) S_looks_like_bool(aTHX_ a)
+#define newGIVWHENOP(a,b,c,d,e) S_newGIVWHENOP(aTHX_ a,b,c,d,e)
+#define ref_array_or_hash(a) S_ref_array_or_hash(aTHX_ a)
#endif
#endif
#if defined(PL_OP_SLAB_ALLOC)
@@ -3203,16 +3232,22 @@
#define doparseform(a) S_doparseform(aTHX_ a)
#define num_overflow S_num_overflow
#define dopoptoeval(a) S_dopoptoeval(aTHX_ a)
+#define dopoptogiven(a) S_dopoptogiven(aTHX_ a)
#define dopoptolabel(a) S_dopoptolabel(aTHX_ a)
#define dopoptoloop(a) S_dopoptoloop(aTHX_ a)
#define dopoptosub(a) S_dopoptosub(aTHX_ a)
#define dopoptosub_at(a,b) S_dopoptosub_at(aTHX_ a,b)
+#define dopoptowhen(a) S_dopoptowhen(aTHX_ a)
#define save_lines(a,b) S_save_lines(aTHX_ a,b)
#define doeval(a,b,c,d) S_doeval(aTHX_ a,b,c,d)
#define check_type_and_open(a,b) S_check_type_and_open(aTHX_ a,b)
#define doopen_pm(a,b) S_doopen_pm(aTHX_ a,b)
#define path_is_absolute(a) S_path_is_absolute(aTHX_ a)
#define run_user_filter(a,b,c) S_run_user_filter(aTHX_ a,b,c)
+#define make_matcher(a) S_make_matcher(aTHX_ a)
+#define matcher_matches_sv(a,b) S_matcher_matches_sv(aTHX_ a,b)
+#define destroy_matcher(a) S_destroy_matcher(aTHX_ a)
+#define do_smartmatch(a,b) S_do_smartmatch(aTHX_ a,b)
#endif
#endif
#if defined(PERL_IN_PP_HOT_C) || defined(PERL_DECL_PROT)
@@ -3380,6 +3415,7 @@
#define skipspace(a) S_skipspace(aTHX_ a)
#define swallow_bom(a) S_swallow_bom(aTHX_ a)
#define checkcomma(a,b,c) S_checkcomma(aTHX_ a,b,c)
+#define feature_is_enabled(a,b) S_feature_is_enabled(aTHX_ a,b)
#define force_ident(a,b) S_force_ident(aTHX_ a,b)
#define incline(a) S_incline(aTHX_ a)
#define intuit_method(a,b) S_intuit_method(aTHX_ a,b)
@@ -3719,8 +3755,10 @@
#define ck_rfun(a) Perl_ck_rfun(aTHX_ a)
#define ck_rvconst(a) Perl_ck_rvconst(aTHX_ a)
#define ck_sassign(a) Perl_ck_sassign(aTHX_ a)
+#define ck_say(a) Perl_ck_say(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)
@@ -3751,6 +3789,7 @@
#define pp_bit_or() Perl_pp_bit_or(aTHX)
#define pp_bit_xor() Perl_pp_bit_xor(aTHX)
#define pp_bless() Perl_pp_bless(aTHX)
+#define pp_break() Perl_pp_break(aTHX)
#define pp_caller() Perl_pp_caller(aTHX)
#define pp_chdir() Perl_pp_chdir(aTHX)
#define pp_chmod() Perl_pp_chmod(aTHX)
@@ -3766,6 +3805,7 @@
#define pp_cond_expr() Perl_pp_cond_expr(aTHX)
#define pp_connect() Perl_pp_connect(aTHX)
#define pp_const() Perl_pp_const(aTHX)
+#define pp_continue() Perl_pp_continue(aTHX)
#define pp_cos() Perl_pp_cos(aTHX)
#define pp_crypt() Perl_pp_crypt(aTHX)
#define pp_dbmclose() Perl_pp_dbmclose(aTHX)
@@ -3785,10 +3825,12 @@
#define pp_enetent() Perl_pp_enetent(aTHX)
#define pp_enter() Perl_pp_enter(aTHX)
#define pp_entereval() Perl_pp_entereval(aTHX)
+#define pp_entergiven() Perl_pp_entergiven(aTHX)
#define pp_enteriter() Perl_pp_enteriter(aTHX)
#define pp_enterloop() Perl_pp_enterloop(aTHX)
#define pp_entersub() Perl_pp_entersub(aTHX)
#define pp_entertry() Perl_pp_entertry(aTHX)
+#define pp_enterwhen() Perl_pp_enterwhen(aTHX)
#define pp_enterwrite() Perl_pp_enterwrite(aTHX)
#define pp_eof() Perl_pp_eof(aTHX)
#define pp_eprotoent() Perl_pp_eprotoent(aTHX)
@@ -3898,10 +3940,12 @@
#define pp_le() Perl_pp_le(aTHX)
#define pp_leave() Perl_pp_leave(aTHX)
#define pp_leaveeval() Perl_pp_leaveeval(aTHX)
+#define pp_leavegiven() Perl_pp_leavegiven(aTHX)
#define pp_leaveloop() Perl_pp_leaveloop(aTHX)
#define pp_leavesub() Perl_pp_leavesub(aTHX)
#define pp_leavesublv() Perl_pp_leavesublv(aTHX)
#define pp_leavetry() Perl_pp_leavetry(aTHX)
+#define pp_leavewhen() Perl_pp_leavewhen(aTHX)
#define pp_leavewrite() Perl_pp_leavewrite(aTHX)
#define pp_left_shift() Perl_pp_left_shift(aTHX)
#define pp_length() Perl_pp_length(aTHX)
@@ -3991,6 +4035,7 @@
#define pp_rv2hv() Perl_pp_rv2hv(aTHX)
#define pp_rv2sv() Perl_pp_rv2sv(aTHX)
#define pp_sassign() Perl_pp_sassign(aTHX)
+#define pp_say() Perl_pp_say(aTHX)
#define pp_scalar() Perl_pp_scalar(aTHX)
#define pp_schomp() Perl_pp_schomp(aTHX)
#define pp_schop() Perl_pp_schop(aTHX)
@@ -4021,6 +4066,7 @@
#define pp_sle() Perl_pp_sle(aTHX)
#define pp_sleep() Perl_pp_sleep(aTHX)
#define pp_slt() Perl_pp_slt(aTHX)
+#define pp_smartmatch() Perl_pp_smartmatch(aTHX)
#define pp_sne() Perl_pp_sne(aTHX)
#define pp_snetent() Perl_pp_snetent(aTHX)
#define pp_socket() Perl_pp_socket(aTHX)
diff --git a/ext/B/B/Deparse.pm b/ext/B/B/Deparse.pm
index 218ab9c869..958b137a49 100644
--- a/ext/B/B/Deparse.pm
+++ b/ext/B/B/Deparse.pm
@@ -19,7 +19,7 @@ use B qw(class main_root main_start main_cv svref_2object opnumber perlstring
CVf_METHOD CVf_LOCKED CVf_LVALUE CVf_ASSERTION
PMf_KEEP PMf_GLOBAL PMf_CONTINUE PMf_EVAL PMf_ONCE PMf_SKIPWHITE
PMf_MULTILINE PMf_SINGLELINE PMf_FOLD PMf_EXTENDED);
-$VERSION = 0.72;
+$VERSION = 0.73;
use strict;
use vars qw/$AUTOLOAD/;
use warnings ();
@@ -116,6 +116,11 @@ use warnings ();
# - option to use Data::Dumper for constants
# - more bug fixes
# - discovered lots more bugs not yet fixed
+#
+# ...
+#
+# Changes between 0.72 and 0.73
+# - support new switch constructs
# Todo:
# (See also BUGS section at the end of this file)
@@ -1632,6 +1637,38 @@ sub pp_ggrgid { unop(@_, "getgrgid") }
sub pp_lock { unop(@_, "lock") }
+sub pp_continue { unop(@_, "continue"); }
+sub pp_break {
+ my ($self, $op) = @_;
+ return "" if $op->flags & OPf_SPECIAL;
+ unop(@_, "break");
+}
+
+sub givwhen {
+ my $self = shift;
+ my($op, $cx, $givwhen) = @_;
+
+ my $enterop = $op->first;
+ my ($head, $block);
+ if ($enterop->flags & OPf_SPECIAL) {
+ $head = "default";
+ $block = $self->deparse($enterop->first, 0);
+ }
+ 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(@_, "given"); }
+sub pp_leavewhen { givwhen(@_, "when"); }
+
sub pp_exists {
my $self = shift;
my($op, $cx) = @_;
@@ -2008,6 +2045,16 @@ sub pp_scmp { 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) {
+ return $self->deparse($op->first, $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.
diff --git a/ext/B/t/concise-xs.t b/ext/B/t/concise-xs.t
index acce386165..fe45773e03 100644
--- a/ext/B/t/concise-xs.t
+++ b/ext/B/t/concise-xs.t
@@ -94,6 +94,7 @@ use Getopt::Std;
use Carp;
use Test::More tests => ( 1 * !!$Config::Config{useithreads}
+ 3 * ($] > 5.009)
+ + 12 * ($] >= 5.009003)
+ 777 );
require_ok("B::Concise");
diff --git a/ext/B/t/f_map.t b/ext/B/t/f_map.t
index 25bed73d2a..8e614a6ba9 100644
--- a/ext/B/t/f_map.t
+++ b/ext/B/t/f_map.t
@@ -176,7 +176,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) lKS
+# f <{> enteriter(next->q last->t redo->g) lKS/8
# r <0> iter s
# s <|> and(other->g) K/1
# g <;> nextstate(main 475 (eval 10):1) v
@@ -209,7 +209,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) lKS
+# f <{> enteriter(next->q last->t redo->g) lKS/8
# 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 4f0d782710..c7a8152aaa 100644
--- a/ext/B/t/optree_samples.t
+++ b/ext/B/t/optree_samples.t
@@ -259,7 +259,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->d last->g redo->7) lKS
+# 6 <{> enteriter(next->d last->g redo->7) lKS/8
# e <0> iter s
# f <|> and(other->7) K/1
# 7 <;> nextstate(main 442 optree.t:158) v
@@ -278,7 +278,7 @@ EOT_EOT
# 3 <$> const(IV 1) s
# 4 <$> const(IV 10) s
# 5 <$> gv(*_) s
-# 6 <{> enteriter(next->d last->g redo->7) lKS
+# 6 <{> enteriter(next->d last->g redo->7) lKS/8
# e <0> iter s
# f <|> and(other->7) K/1
# 7 <;> nextstate(main 443 optree_samples.t:182) v
@@ -302,7 +302,7 @@ checkOptree ( name => '-basic sub { print "foo $_" foreach (1..10) }',
# 1 <;> nextstate(main 445 optree.t:167) v ->2
# 2 <;> nextstate(main 445 optree.t:167) v ->3
# g <2> leaveloop K/2 ->h
-# 7 <{> enteriter(next->d last->g redo->8) lKS ->e
+# 7 <{> enteriter(next->d last->g redo->8) lKS/8 ->e
# - <0> ex-pushmark s ->3
# - <1> ex-list lK ->6
# 3 <0> pushmark s ->4
@@ -328,7 +328,7 @@ EOT_EOT
# 1 <;> nextstate(main 446 optree_samples.t:192) v ->2
# 2 <;> nextstate(main 446 optree_samples.t:192) v ->3
# g <2> leaveloop K/2 ->h
-# 7 <{> enteriter(next->d last->g redo->8) lKS ->e
+# 7 <{> enteriter(next->d last->g redo->8) lKS/8 ->e
# - <0> ex-pushmark s ->3
# - <1> ex-list lK ->6
# 3 <0> pushmark s ->4
@@ -360,7 +360,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->e last->h redo->8) lKS
+# 7 <{> enteriter(next->e last->h redo->8) lKS/8
# f <0> iter s
# g <|> and(other->8) vK/1
# 8 <;> nextstate(main 1 -e:1) v
@@ -380,7 +380,7 @@ EOT_EOT
# 4 <$> const(IV 1) s
# 5 <$> const(IV 10) s
# 6 <$> gv(*_) s
-# 7 <{> enteriter(next->e last->h redo->8) lKS
+# 7 <{> enteriter(next->e last->h redo->8) lKS/8
# f <0> iter s
# g <|> and(other->8) vK/1
# 8 <;> nextstate(main 1 -e:1) v
@@ -405,7 +405,7 @@ checkOptree ( name => '-exec sub { print "foo $_" foreach (1..10) }',
# 4 <$> const[IV 1] s
# 5 <$> const[IV 10] s
# 6 <#> gv[*_] s
-# 7 <{> enteriter(next->d last->g redo->8) lKS
+# 7 <{> enteriter(next->d last->g redo->8) lKS/8
# e <0> iter s
# f <|> and(other->8) K/1
# 8 <0> pushmark s
@@ -424,7 +424,7 @@ EOT_EOT
# 4 <$> const(IV 1) s
# 5 <$> const(IV 10) s
# 6 <$> gv(*_) s
-# 7 <{> enteriter(next->d last->g redo->8) lKS
+# 7 <{> enteriter(next->d last->g redo->8) lKS/8
# e <0> iter s
# f <|> and(other->8) K/1
# 8 <0> pushmark s
@@ -549,7 +549,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) lKS
+# d <{> enteriter(next->o last->r redo->e) lKS/8
# p <0> iter s
# q <|> and(other->e) K/1
# e <;> nextstate(main 505 (eval 24):1) v
@@ -579,7 +579,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) lKS
+# d <{> enteriter(next->o last->r redo->e) lKS/8
# p <0> iter s
# q <|> and(other->e) K/1
# e <;> nextstate(main 505 (eval 24):1) v
diff --git a/ext/IO/lib/IO/Handle.pm b/ext/IO/lib/IO/Handle.pm
index 329d26ad19..551988bae5 100644
--- a/ext/IO/lib/IO/Handle.pm
+++ b/ext/IO/lib/IO/Handle.pm
@@ -69,6 +69,7 @@ corresponding built-in functions:
$io->read ( BUF, LEN, [OFFSET] )
$io->print ( ARGS )
$io->printf ( FMT, [ARGS] )
+ $io->say ( ARGS )
$io->stat
$io->sysread ( BUF, LEN, [OFFSET] )
$io->syswrite ( BUF, [LEN, [OFFSET]] )
@@ -264,7 +265,7 @@ use IO (); # Load the XS module
require Exporter;
@ISA = qw(Exporter);
-$VERSION = "1.25";
+$VERSION = "1.26";
$VERSION = eval $VERSION;
@EXPORT_OK = qw(
@@ -284,6 +285,7 @@ $VERSION = eval $VERSION;
print
printf
+ say
getline
getlines
@@ -407,6 +409,13 @@ sub printf {
printf $this @_;
}
+sub say {
+ @_ or croak 'usage: $io->say(ARGS)';
+ my $this = shift;
+ use feature 'say';
+ say $this @_;
+}
+
sub getline {
@_ == 1 or croak 'usage: $io->getline()';
my $this = shift;
diff --git a/ext/Opcode/Opcode.pm b/ext/Opcode/Opcode.pm
index 9394734192..9a1c92b2b0 100644
--- a/ext/Opcode/Opcode.pm
+++ b/ext/Opcode/Opcode.pm
@@ -382,7 +382,7 @@ account the magical open of ARGV.
formline enterwrite leavewrite
- print sysread syswrite send recv
+ print say sysread syswrite send recv
eof tell seek sysseek
@@ -416,6 +416,11 @@ These are a hotchpotch of opcodes still waiting to be considered
entertry leavetry -- can be used to 'hide' fatal errors
+ entergiven leavegiven
+ enterwhen leavewhen
+ break continue
+ smartmatch
+
custom -- where should this go
=item :base_math
diff --git a/global.sym b/global.sym
index 1d862729e1..eb734052a4 100644
--- a/global.sym
+++ b/global.sym
@@ -282,6 +282,7 @@ Perl_newCONDOP
Perl_newCONSTSUB
Perl_newFORM
Perl_newFOROP
+Perl_newGIVENOP
Perl_newLOGOP
Perl_newLOOPEX
Perl_newLOOPOP
@@ -325,6 +326,7 @@ Perl_vnewSVpvf
Perl_newSVrv
Perl_newSVsv
Perl_newUNOP
+Perl_newWHENOP
Perl_newWHILEOP
Perl_new_stackinfo
Perl_scan_vstring
diff --git a/keywords.h b/keywords.h
index 3af51b8c9d..c4834acb54 100644
--- a/keywords.h
+++ b/keywords.h
@@ -33,231 +33,236 @@
#define KEY_bind 18
#define KEY_binmode 19
#define KEY_bless 20
-#define KEY_caller 21
-#define KEY_chdir 22
-#define KEY_chmod 23
-#define KEY_chomp 24
-#define KEY_chop 25
-#define KEY_chown 26
-#define KEY_chr 27
-#define KEY_chroot 28
-#define KEY_close 29
-#define KEY_closedir 30
-#define KEY_cmp 31
-#define KEY_connect 32
-#define KEY_continue 33
-#define KEY_cos 34
-#define KEY_crypt 35
-#define KEY_dbmclose 36
-#define KEY_dbmopen 37
-#define KEY_defined 38
-#define KEY_delete 39
-#define KEY_die 40
-#define KEY_do 41
-#define KEY_dump 42
-#define KEY_each 43
-#define KEY_else 44
-#define KEY_elsif 45
-#define KEY_endgrent 46
-#define KEY_endhostent 47
-#define KEY_endnetent 48
-#define KEY_endprotoent 49
-#define KEY_endpwent 50
-#define KEY_endservent 51
-#define KEY_eof 52
-#define KEY_eq 53
-#define KEY_err 54
-#define KEY_eval 55
-#define KEY_exec 56
-#define KEY_exists 57
-#define KEY_exit 58
-#define KEY_exp 59
-#define KEY_fcntl 60
-#define KEY_fileno 61
-#define KEY_flock 62
-#define KEY_for 63
-#define KEY_foreach 64
-#define KEY_fork 65
-#define KEY_format 66
-#define KEY_formline 67
-#define KEY_ge 68
-#define KEY_getc 69
-#define KEY_getgrent 70
-#define KEY_getgrgid 71
-#define KEY_getgrnam 72
-#define KEY_gethostbyaddr 73
-#define KEY_gethostbyname 74
-#define KEY_gethostent 75
-#define KEY_getlogin 76
-#define KEY_getnetbyaddr 77
-#define KEY_getnetbyname 78
-#define KEY_getnetent 79
-#define KEY_getpeername 80
-#define KEY_getpgrp 81
-#define KEY_getppid 82
-#define KEY_getpriority 83
-#define KEY_getprotobyname 84
-#define KEY_getprotobynumber 85
-#define KEY_getprotoent 86
-#define KEY_getpwent 87
-#define KEY_getpwnam 88
-#define KEY_getpwuid 89
-#define KEY_getservbyname 90
-#define KEY_getservbyport 91
-#define KEY_getservent 92
-#define KEY_getsockname 93
-#define KEY_getsockopt 94
-#define KEY_glob 95
-#define KEY_gmtime 96
-#define KEY_goto 97
-#define KEY_grep 98
-#define KEY_gt 99
-#define KEY_hex 100
-#define KEY_if 101
-#define KEY_index 102
-#define KEY_int 103
-#define KEY_ioctl 104
-#define KEY_join 105
-#define KEY_keys 106
-#define KEY_kill 107
-#define KEY_last 108
-#define KEY_lc 109
-#define KEY_lcfirst 110
-#define KEY_le 111
-#define KEY_length 112
-#define KEY_link 113
-#define KEY_listen 114
-#define KEY_local 115
-#define KEY_localtime 116
-#define KEY_lock 117
-#define KEY_log 118
-#define KEY_lstat 119
-#define KEY_lt 120
-#define KEY_m 121
-#define KEY_map 122
-#define KEY_mkdir 123
-#define KEY_msgctl 124
-#define KEY_msgget 125
-#define KEY_msgrcv 126
-#define KEY_msgsnd 127
-#define KEY_my 128
-#define KEY_ne 129
-#define KEY_next 130
-#define KEY_no 131
-#define KEY_not 132
-#define KEY_oct 133
-#define KEY_open 134
-#define KEY_opendir 135
-#define KEY_or 136
-#define KEY_ord 137
-#define KEY_our 138
-#define KEY_pack 139
-#define KEY_package 140
-#define KEY_pipe 141
-#define KEY_pop 142
-#define KEY_pos 143
-#define KEY_print 144
-#define KEY_printf 145
-#define KEY_prototype 146
-#define KEY_push 147
-#define KEY_q 148
-#define KEY_qq 149
-#define KEY_qr 150
-#define KEY_quotemeta 151
-#define KEY_qw 152
-#define KEY_qx 153
-#define KEY_rand 154
-#define KEY_read 155
-#define KEY_readdir 156
-#define KEY_readline 157
-#define KEY_readlink 158
-#define KEY_readpipe 159
-#define KEY_recv 160
-#define KEY_redo 161
-#define KEY_ref 162
-#define KEY_rename 163
-#define KEY_require 164
-#define KEY_reset 165
-#define KEY_return 166
-#define KEY_reverse 167
-#define KEY_rewinddir 168
-#define KEY_rindex 169
-#define KEY_rmdir 170
-#define KEY_s 171
-#define KEY_scalar 172
-#define KEY_seek 173
-#define KEY_seekdir 174
-#define KEY_select 175
-#define KEY_semctl 176
-#define KEY_semget 177
-#define KEY_semop 178
-#define KEY_send 179
-#define KEY_setgrent 180
-#define KEY_sethostent 181
-#define KEY_setnetent 182
-#define KEY_setpgrp 183
-#define KEY_setpriority 184
-#define KEY_setprotoent 185
-#define KEY_setpwent 186
-#define KEY_setservent 187
-#define KEY_setsockopt 188
-#define KEY_shift 189
-#define KEY_shmctl 190
-#define KEY_shmget 191
-#define KEY_shmread 192
-#define KEY_shmwrite 193
-#define KEY_shutdown 194
-#define KEY_sin 195
-#define KEY_sleep 196
-#define KEY_socket 197
-#define KEY_socketpair 198
-#define KEY_sort 199
-#define KEY_splice 200
-#define KEY_split 201
-#define KEY_sprintf 202
-#define KEY_sqrt 203
-#define KEY_srand 204
-#define KEY_stat 205
-#define KEY_study 206
-#define KEY_sub 207
-#define KEY_substr 208
-#define KEY_symlink 209
-#define KEY_syscall 210
-#define KEY_sysopen 211
-#define KEY_sysread 212
-#define KEY_sysseek 213
-#define KEY_system 214
-#define KEY_syswrite 215
-#define KEY_tell 216
-#define KEY_telldir 217
-#define KEY_tie 218
-#define KEY_tied 219
-#define KEY_time 220
-#define KEY_times 221
-#define KEY_tr 222
-#define KEY_truncate 223
-#define KEY_uc 224
-#define KEY_ucfirst 225
-#define KEY_umask 226
-#define KEY_undef 227
-#define KEY_unless 228
-#define KEY_unlink 229
-#define KEY_unpack 230
-#define KEY_unshift 231
-#define KEY_untie 232
-#define KEY_until 233
-#define KEY_use 234
-#define KEY_utime 235
-#define KEY_values 236
-#define KEY_vec 237
-#define KEY_wait 238
-#define KEY_waitpid 239
-#define KEY_wantarray 240
-#define KEY_warn 241
-#define KEY_while 242
-#define KEY_write 243
-#define KEY_x 244
-#define KEY_xor 245
-#define KEY_y 246
+#define KEY_break 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_default 39
+#define KEY_defined 40
+#define KEY_delete 41
+#define KEY_die 42
+#define KEY_do 43
+#define KEY_dump 44
+#define KEY_each 45
+#define KEY_else 46
+#define KEY_elsif 47
+#define KEY_endgrent 48
+#define KEY_endhostent 49
+#define KEY_endnetent 50
+#define KEY_endprotoent 51
+#define KEY_endpwent 52
+#define KEY_endservent 53
+#define KEY_eof 54
+#define KEY_eq 55
+#define KEY_err 56
+#define KEY_eval 57
+#define KEY_exec 58
+#define KEY_exists 59
+#define KEY_exit 60
+#define KEY_exp 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_study 210
+#define KEY_sub 211
+#define KEY_substr 212
+#define KEY_symlink 213
+#define KEY_syscall 214
+#define KEY_sysopen 215
+#define KEY_sysread 216
+#define KEY_sysseek 217
+#define KEY_system 218
+#define KEY_syswrite 219
+#define KEY_tell 220
+#define KEY_telldir 221
+#define KEY_tie 222
+#define KEY_tied 223
+#define KEY_time 224
+#define KEY_times 225
+#define KEY_tr 226
+#define KEY_truncate 227
+#define KEY_uc 228
+#define KEY_ucfirst 229
+#define KEY_umask 230
+#define KEY_undef 231
+#define KEY_unless 232
+#define KEY_unlink 233
+#define KEY_unpack 234
+#define KEY_unshift 235
+#define KEY_untie 236
+#define KEY_until 237
+#define KEY_use 238
+#define KEY_utime 239
+#define KEY_values 240
+#define KEY_vec 241
+#define KEY_wait 242
+#define KEY_waitpid 243
+#define KEY_wantarray 244
+#define KEY_warn 245
+#define KEY_when 246
+#define KEY_while 247
+#define KEY_write 248
+#define KEY_x 249
+#define KEY_xor 250
+#define KEY_y 251
/* ex: set ro: */
diff --git a/keywords.pl b/keywords.pl
index fe745d470b..2f3a95af3d 100755
--- a/keywords.pl
+++ b/keywords.pl
@@ -68,6 +68,7 @@ atan2
bind
binmode
bless
+break
caller
chdir
chmod
@@ -85,6 +86,7 @@ cos
crypt
dbmclose
dbmopen
+default
defined
delete
die
@@ -142,6 +144,7 @@ getservbyport
getservent
getsockname
getsockopt
+given
glob
gmtime
goto
@@ -219,6 +222,7 @@ rewinddir
rindex
rmdir
s
+say
scalar
seek
seekdir
@@ -289,6 +293,7 @@ wait
waitpid
wantarray
warn
+when
while
write
x
diff --git a/lib/feature.pm b/lib/feature.pm
new file mode 100644
index 0000000000..e0981d08a9
--- /dev/null
+++ b/lib/feature.pm
@@ -0,0 +1,116 @@
+package feature;
+
+our $VERSION = '1.00';
+$feature::hint_bits = 0x04020000; # HINT_LOCALIZE_HH | HINT_HH_FOR_EVAL
+
+# (feature name) => (internal name, used in %^H)
+my %feature = (
+ switch => 'switch',
+ "~~" => "~~",
+ say => "say",
+);
+
+
+# Here are some notes that probably shouldn't be in the public
+# documentation, but which it's useful to have somewhere.
+#
+# One side-effect of the change is that C<prototype("CORE::continue")>
+# no longer throws the error C<Can't find an opnumber for "continue">.
+# One of the tests in t/op/cproto.t had to be changed to accommodate
+# this, but it really shouldn't affect real-world code.
+#
+# TODO:
+# - sort out the smartmatch semantics
+# - think about versioned features (use switch => 2)
+#
+# -- Robin 2005-12
+
+=head1 NAME
+
+feature - Perl pragma to enable new syntactic features
+
+=head1 SYNOPSIS
+
+ use feature 'switch';
+ given ($foo) {
+ when (1) { print "\$foo == 1\n" }
+ when ([2,3]) { print "\$foo == 2 || \$foo == 3\n" }
+ when (/^a[bc]d$/) { print "\$foo eq 'abd' || \$foo eq 'acd'\n" }
+ when ($_ > 100) { print "\$foo > 100\n" }
+ default { print "None of the above\n" }
+ }
+
+=head1 DESCRIPTION
+
+It is usually impossible to add new syntax to Perl without breaking
+some existing programs. This pragma provides a way to minimize that
+risk. New syntactic constructs can be enabled by C<use feature 'foo'>,
+and will be parsed only when the appropriate feature pragma is in
+scope.
+
+=head2 The 'switch' feature
+
+C<use feature 'switch'> tells the compiler to enable the Perl 6
+given/when construct from here to the end of the enclosing BLOCK.
+
+See L<perlsyn/"Switch statements"> for details.
+
+=head2 The '~~' feature
+
+C<use feature '~~'> tells the compiler to enable the Perl 6
+smart match C<~~> operator from here to the end of the enclosing BLOCK.
+
+See L<perlsyn/"Smart Matching in Detail"> for details.
+
+=head2 The 'say' feature
+
+C<use feature 'say'> tells the compiler to enable the Perl 6
+C<say> function from here to the end of the enclosing BLOCK.
+
+See L<perlfunc/say> for details.
+
+=cut
+
+sub import {
+ $^H |= $feature::hint_bits; # Need this or %^H won't work
+
+ my $class = shift;
+ if (@_ == 0) {
+ require Carp;
+ Carp->import("croak");
+ croak("No features specified");
+ }
+ while (@_) {
+ my $name = shift(@_);
+ if (!exists $feature{$name}) {
+ require Carp;
+ Carp->import("croak");
+ croak(sprintf('Feature "%s" is not supported by Perl %vd',
+ $name, $^V));
+ }
+ $^H{$feature{$name}} = 1;
+ }
+}
+
+sub unimport {
+ my $class = shift;
+
+ # A bare C<no feature> should disable *all* features
+ for my $name (@_) {
+ if (!exists($feature{$name})) {
+ require Carp;
+ Carp->import("croak");
+ croak(sprintf('Feature "%s" is not supported by Perl %vd',
+ $name, $^V));
+ }
+ else {
+ delete $^H{$feature{$name}};
+ }
+ }
+
+ if(!@_) {
+ delete @^H{ values(%feature) };
+ }
+}
+
+1;
diff --git a/lib/feature.t b/lib/feature.t
new file mode 100644
index 0000000000..a60644f442
--- /dev/null
+++ b/lib/feature.t
@@ -0,0 +1,10 @@
+#!./perl
+
+BEGIN {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+ $ENV{PERL5LIB} = '../lib';
+}
+
+our $pragma_name = "feature";
+require "../t/lib/common.pl";
diff --git a/lib/overload.pm b/lib/overload.pm
index b189044846..8a07efec69 100644
--- a/lib/overload.pm
+++ b/lib/overload.pm
@@ -422,7 +422,7 @@ The dereference operators must be specified explicitly they will not be passed t
=item * I<Special>
- "nomethod", "fallback", "=",
+ "nomethod", "fallback", "=", "~~",
see L<SPECIAL SYMBOLS FOR C<use overload>>.
@@ -517,6 +517,11 @@ The key C<"fallback"> governs what to do if a method for a particular
operation is not found. Three different cases are possible depending on
the value of C<"fallback">:
+=head2 Smart Match
+
+The key C<"~~"> allows you to override the smart matching used by
+the switch construct. See L<feature>.
+
=over 16
=item * C<undef>
diff --git a/lib/warnings.t b/lib/warnings.t
index f23d9e67f8..55e2794c7b 100644
--- a/lib/warnings.t
+++ b/lib/warnings.t
@@ -4,201 +4,7 @@ BEGIN {
chdir 't' if -d 't';
@INC = '../lib';
$ENV{PERL5LIB} = '../lib';
- require Config; import Config;
- require './test.pl';
}
-use File::Path;
-use File::Spec::Functions;
-
-$| = 1;
-
-my $Is_MacOS = $^O eq 'MacOS';
-my $tmpfile = "tmp0000";
-1 while -e ++$tmpfile;
-END { if ($tmpfile) { 1 while unlink $tmpfile} }
-
-my @prgs = () ;
-my @w_files = () ;
-
-if (@ARGV)
- { print "ARGV = [@ARGV]\n" ;
- if ($^O eq 'MacOS') {
- @w_files = map { s#^#:lib:warnings:#; $_ } @ARGV
- } else {
- @w_files = map { s#^#./lib/warnings/#; $_ } @ARGV
- }
- }
-else
- { @w_files = sort glob(catfile(curdir(), "lib", "warnings", "*")) }
-
-my $files = 0;
-foreach my $file (@w_files) {
-
- next if $file =~ /(~|\.orig|,v)$/;
- next if $file =~ /perlio$/ && !(find PerlIO::Layer 'perlio');
- next if -d $file;
-
- open F, "<$file" or die "Cannot open $file: $!\n" ;
- my $line = 0;
- while (<F>) {
- $line++;
- last if /^__END__/ ;
- }
-
- {
- local $/ = undef;
- $files++;
- @prgs = (@prgs, $file, split "\n########\n", <F>) ;
- }
- close F ;
-}
-
-undef $/;
-
-plan tests => (scalar(@prgs)-$files);
-
-
-
-for (@prgs){
- unless (/\n/)
- {
- print "# From $_\n";
- next;
- }
- my $switch = "";
- my @temps = () ;
- my @temp_path = () ;
- if (s/^\s*-\w+//){
- $switch = $&;
- }
- my($prog,$expected) = split(/\nEXPECT\n/, $_);
- my ($todo, $todo_reason);
- $todo = $prog =~ s/^#\s*TODO(.*)\n//m and $todo_reason = $1;
- if ( $prog =~ /--FILE--/) {
- my(@files) = split(/\n--FILE--\s*([^\s\n]*)\s*\n/, $prog) ;
- shift @files ;
- die "Internal error test $test didn't split into pairs, got " .
- scalar(@files) . "[" . join("%%%%", @files) ."]\n"
- if @files % 2 ;
- while (@files > 2) {
- my $filename = shift @files ;
- my $code = shift @files ;
- push @temps, $filename ;
- if ($filename =~ m#(.*)/#) {
- mkpath($1);
- push(@temp_path, $1);
- }
- open F, ">$filename" or die "Cannot open $filename: $!\n" ;
- print F $code ;
- close F or die "Cannot close $filename: $!\n";
- }
- shift @files ;
- $prog = shift @files ;
- }
-
- # fix up some paths
- if ($^O eq 'MacOS') {
- $prog =~ s|require "./abc(d)?";|require ":abc$1";|g;
- $prog =~ s|"\."|":"|g;
- }
-
- open TEST, ">$tmpfile" or die "Cannot open >$tmpfile: $!";
- print TEST q{
- BEGIN {
- open(STDERR, ">&STDOUT")
- or die "Can't dup STDOUT->STDERR: $!;";
- }
- };
- print TEST "\n#line 1\n"; # So the line numbers don't get messed up.
- print TEST $prog,"\n";
- close TEST or die "Cannot close $tmpfile: $!";
- my $results = runperl( switches => [$switch], stderr => 1, progfile => $tmpfile );
- my $status = $?;
- $results =~ s/\n+$//;
- # allow expected output to be written as if $prog is on STDIN
- $results =~ s/tmp\d+/-/g;
- if ($^O eq 'VMS') {
- # some tests will trigger VMS messages that won't be expected
- $results =~ s/\n?%[A-Z]+-[SIWEF]-[A-Z]+,.*//;
-
- # pipes double these sometimes
- $results =~ s/\n\n/\n/g;
- }
-# bison says 'parse error' instead of 'syntax error',
-# various yaccs may or may not capitalize 'syntax'.
- $results =~ s/^(syntax|parse) error/syntax error/mig;
- # allow all tests to run when there are leaks
- $results =~ s/Scalars leaked: \d+\n//g;
-
- # fix up some paths
- if ($^O eq 'MacOS') {
- $results =~ s|:abc\.pm\b|abc.pm|g;
- $results =~ s|:abc(d)?\b|./abc$1|g;
- }
-
- $expected =~ s/\n+$//;
- my $prefix = ($results =~ s#^PREFIX(\n|$)##) ;
- # any special options? (OPTIONS foo bar zap)
- my $option_regex = 0;
- my $option_random = 0;
- if ($expected =~ s/^OPTIONS? (.+)\n//) {
- foreach my $option (split(' ', $1)) {
- if ($option eq 'regex') { # allow regular expressions
- $option_regex = 1;
- }
- elsif ($option eq 'random') { # all lines match, but in any order
- $option_random = 1;
- }
- else {
- die "$0: Unknown OPTION '$option'\n";
- }
- }
- }
- die "$0: can't have OPTION regex and random\n"
- if $option_regex + option_random > 1;
- my $ok = 1;
- if ( $results =~ s/^SKIPPED\n//) {
- print "$results\n" ;
- }
- elsif ($option_random)
- {
- $ok = randomMatch($results, $expected);
- }
- elsif (($prefix && (( $option_regex && $results !~ /^$expected/) ||
- (!$option_regex && $results !~ /^\Q$expected/))) or
- (!$prefix && (( $option_regex && $results !~ /^$expected/) ||
- (!$option_regex && $results ne $expected)))) {
- my $err_line = "PROG: $switch\n$prog\n" .
- "EXPECTED:\n$expected\n" .
- "GOT:\n$results\n";
- if ($todo) {
- $err_line =~ s/^/# /mg;
- print $err_line; # Harness can't filter it out from STDERR.
- }
- else {
- print STDERR $err_line;
- }
- $ok = 0;
- }
-
- $TODO = $todo ? $todo_reason : 0;
- ok($ok);
-
- foreach (@temps)
- { unlink $_ if $_ }
- foreach (@temp_path)
- { rmtree $_ if -d $_ }
-}
-
-sub randomMatch
-{
- my $got = shift ;
- my $expected = shift;
-
- my @got = sort split "\n", $got ;
- my @expected = sort split "\n", $expected ;
-
- return "@got" eq "@expected";
-
-}
+our $pragma_name = "warnings";
+require "../t/lib/common.pl";
diff --git a/op.c b/op.c
index 626db8f548..fc1c6a8f30 100644
--- a/op.c
+++ b/op.c
@@ -820,6 +820,8 @@ Perl_scalarvoid(pTHX_ OP *o)
case OP_AND:
case OP_DOR:
case OP_COND_EXPR:
+ case OP_ENTERGIVEN:
+ case OP_ENTERWHEN:
for (kid = cUNOPo->op_first->op_sibling; kid; kid = kid->op_sibling)
scalarvoid(kid);
break;
@@ -841,6 +843,8 @@ Perl_scalarvoid(pTHX_ OP *o)
case OP_LEAVELOOP:
case OP_LINESEQ:
case OP_LIST:
+ case OP_LEAVEGIVEN:
+ case OP_LEAVEWHEN:
for (kid = cLISTOPo->op_first; kid; kid = kid->op_sibling)
scalarvoid(kid);
break;
@@ -3918,6 +3922,8 @@ Perl_newFOROP(pTHX_ I32 flags, char *label, line_t forline, OP *sv, OP *expr, OP
iterpflags = sv->op_private & OPpOUR_INTRO; /* for our $x () */
sv->op_type = OP_RV2GV;
sv->op_ppaddr = PL_ppaddr[OP_RV2GV];
+ if (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 () */
@@ -3935,6 +3941,8 @@ Perl_newFOROP(pTHX_ I32 flags, char *label, line_t forline, OP *sv, OP *expr, OP
}
else
Perl_croak(aTHX_ "Can't use %s for loop variable", PL_op_desc[sv->op_type]);
+ if (padoff && strEQ(PAD_COMPNAME_PV(padoff), "$_"))
+ iterpflags |= OPpITER_DEF;
}
else {
const I32 offset = pad_findmy("$_");
@@ -3944,6 +3952,7 @@ Perl_newFOROP(pTHX_ I32 flags, char *label, line_t forline, OP *sv, OP *expr, OP
else {
padoff = offset;
}
+ iterpflags |= OPpITER_DEF;
}
if (expr->op_type == OP_RV2AV || expr->op_type == OP_PADAV) {
expr = mod(force_list(scalar(ref(expr, OP_ITER))), OP_GREPSTART);
@@ -4031,6 +4040,177 @@ 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, mod(cond, OP_REFGEN));
+
+ 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)
+{
+ LOGOP *enterop;
+ OP *o;
+
+ NewOp(1101, enterop, 1, LOGOP);
+ enterop->op_type = enter_opcode;
+ enterop->op_ppaddr = PL_ppaddr[enter_opcode];
+ enterop->op_flags = (U8) OPf_KIDS;
+ enterop->op_targ = ((entertarg == NOT_IN_PAD) ? 0 : entertarg);
+ enterop->op_private = 0;
+
+ o = newUNOP(leave_opcode, 0, (OP *) enterop);
+
+ if (cond) {
+ enterop->op_first = scalar(cond);
+ cond->op_sibling = block;
+
+ o->op_next = LINKLIST(cond);
+ cond->op_next = (OP *) enterop;
+ }
+ else {
+ /* This is a default {} block */
+ enterop->op_first = block;
+ enterop->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_ OP *o)
+{
+ switch(o->op_type) {
+ case OP_OR:
+ return looks_like_bool(cLOGOPo->op_first);
+
+ case OP_AND:
+ return (
+ looks_like_bool(cLOGOPo->op_first)
+ && looks_like_bool(cLOGOPo->op_first->op_sibling));
+
+ case OP_ENTERSUB:
+
+ case OP_NOT: case OP_XOR:
+ /* Note that OP_DOR is not here */
+
+ 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:
+
+ 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;
+
+ /* FALL THROUGH */
+ default:
+ return FALSE;
+ }
+}
+
+OP *
+Perl_newGIVENOP(pTHX_ OP *cond, OP *block, PADOFFSET defsv_off)
+{
+ assert( cond );
+ return newGIVWHENOP(
+ ref_array_or_hash(cond),
+ block,
+ OP_ENTERGIVEN, OP_LEAVEGIVEN,
+ defsv_off);
+}
+
+/* If cond is null, this is a default {} block */
+OP *
+Perl_newWHENOP(pTHX_ OP *cond, OP *block)
+{
+ bool cond_llb = (!cond || looks_like_bool(cond));
+ OP *cond_op;
+
+ 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,
+ append_elem(block->op_type, block, newOP(OP_BREAK, OPf_SPECIAL)),
+ OP_ENTERWHEN, OP_LEAVEWHEN, 0);
+}
+
/*
=for apidoc cv_undef
@@ -5104,6 +5284,13 @@ Perl_ck_eval(pTHX_ OP *o)
o = newUNOP(OP_ENTEREVAL, 0, newDEFSVOP());
}
o->op_targ = (PADOFFSET)PL_hints;
+ if ((PL_hints & HINT_HH_FOR_EVAL) != 0 && GvHV(PL_hintgv))
+ {
+ /* Store a copy of %^H that pp_entereval can pick up */
+ OP *hhop = newSVOP(OP_CONST, 0, (SV*)newHVhv(GvHV(PL_hintgv)));
+ cUNOPo->op_first->op_sibling = hhop;
+ o->op_private |= OPpEVAL_HAS_HH;
+ }
return o;
}
@@ -5763,6 +5950,43 @@ Perl_ck_listiob(pTHX_ OP *o)
}
OP *
+Perl_ck_say(pTHX_ OP *o)
+{
+ o = ck_listiob(o);
+ o->op_type = OP_PRINT;
+ cLISTOPo->op_last = cLISTOPo->op_last->op_sibling
+ = newSVOP(OP_CONST, 0, newSVpvn("\n", 1));
+ return o;
+}
+
+OP *
+Perl_ck_smartmatch(pTHX_ OP *o)
+{
+ if (0 == (o->op_flags & OPf_SPECIAL)) {
+ OP *first = cBINOPo->op_first;
+ OP *second = first->op_sibling;
+
+ /* Implicitly take a reference to an array or hash */
+ first->op_sibling = Nullop;
+ first = cBINOPo->op_first = ref_array_or_hash(first);
+ second = first->op_sibling = ref_array_or_hash(second);
+
+ /* Implicitly take a reference to a regular expression */
+ if (first->op_type == OP_MATCH) {
+ first->op_type = OP_QR;
+ first->op_ppaddr = PL_ppaddr[OP_QR];
+ }
+ if (second->op_type == OP_MATCH) {
+ second->op_type = OP_QR;
+ second->op_ppaddr = PL_ppaddr[OP_QR];
+ }
+ }
+
+ return o;
+}
+
+
+OP *
Perl_ck_sassign(pTHX_ OP *o)
{
OP *kid = cLISTOPo->op_first;
@@ -5795,7 +6019,7 @@ Perl_ck_sassign(pTHX_ OP *o)
OP *
Perl_ck_match(pTHX_ OP *o)
{
- if (o->op_type != OP_QR) {
+ if (o->op_type != OP_QR && PL_compcv) {
const I32 offset = pad_findmy("$_");
if (offset != NOT_IN_PAD && !(PAD_COMPNAME_FLAGS(offset) & SVpad_OUR)) {
o->op_targ = offset;
diff --git a/op.h b/op.h
index caea112038..e687f42d22 100644
--- a/op.h
+++ b/op.h
@@ -110,6 +110,9 @@ Deprecated. Use C<GIMME_V> instead.
* (runtime property) */
/* On OP_AELEMFAST, indiciates pad var */
/* On OP_REQUIRE, was seen as CORE::require */
+ /* On OP_ENTERWHEN, there's no condition */
+ /* On OP_BREAK, an implicit break */
+ /* On OP_SMARTMATCH, an implicit smartmatch */
/* old names; don't use in new code, but don't break them, either */
#define OPf_LIST OPf_WANT_LIST
@@ -183,6 +186,7 @@ Deprecated. Use C<GIMME_V> instead.
/* Private for OP_ENTERITER and OP_ITER */
#define OPpITER_REVERSED 4 /* for (reverse ...) */
+#define OPpITER_DEF 8 /* for $_ or for my $_ */
/* Private for OP_CONST */
#define OPpCONST_NOVER 2 /* no 6; */
@@ -224,7 +228,7 @@ Deprecated. Use C<GIMME_V> instead.
#define OPpHUSH_VMSISH 64 /* hush DCL exit msg vmsish mode*/
#define OPpEXIT_VMSISH 128 /* exit(0) vs. exit(1) vmsish mode*/
-/* Private of OP_FTXXX */
+/* Private for OP_FTXXX */
#define OPpFT_ACCESS 2 /* use filetest 'access' */
#define OPpFT_STACKED 4 /* stacked filetest, as in "-f -x $f" */
#define OP_IS_FILETEST_ACCESS(op) \
@@ -238,6 +242,9 @@ Deprecated. Use C<GIMME_V> instead.
/* Private for OP_(MAP|GREP)(WHILE|START) */
#define OPpGREP_LEX 2 /* iterate over lexical $_ */
+/* Private for OP_ENTEREVAL */
+#define OPpEVAL_HAS_HH 2 /* Does it have a copy of %^H */
+
struct op {
BASEOP
};
diff --git a/opcode.h b/opcode.h
index 587c138199..5ebe99ff54 100644
--- a/opcode.h
+++ b/opcode.h
@@ -386,6 +386,14 @@ EXTCONST char* const PL_op_name[] = {
"method_named",
"dor",
"dorassign",
+ "entergiven",
+ "leavegiven",
+ "enterwhen",
+ "leavewhen",
+ "break",
+ "continue",
+ "smartmatch",
+ "say",
"custom",
};
#endif
@@ -747,6 +755,14 @@ EXTCONST char* const PL_op_desc[] = {
"method with known name",
"defined or (//)",
"defined or assignment (//=)",
+ "given()",
+ "leave given block",
+ "when()",
+ "leave when block",
+ "break",
+ "continue",
+ "smart match",
+ "say",
"unknown custom operator",
};
#endif
@@ -1119,6 +1135,14 @@ EXT Perl_ppaddr_t PL_ppaddr[] /* or perlvars.h */
MEMBER_TO_FPTR(Perl_pp_method_named),
MEMBER_TO_FPTR(Perl_pp_defined), /* Perl_pp_dor */
MEMBER_TO_FPTR(Perl_pp_defined), /* Perl_pp_dorassign */
+ MEMBER_TO_FPTR(Perl_pp_entergiven),
+ MEMBER_TO_FPTR(Perl_pp_leavegiven),
+ MEMBER_TO_FPTR(Perl_pp_enterwhen),
+ MEMBER_TO_FPTR(Perl_pp_leavewhen),
+ MEMBER_TO_FPTR(Perl_pp_break),
+ MEMBER_TO_FPTR(Perl_pp_continue),
+ MEMBER_TO_FPTR(Perl_pp_smartmatch),
+ MEMBER_TO_FPTR(Perl_pp_print), /* Perl_pp_say */
}
#endif
;
@@ -1485,6 +1509,14 @@ EXT Perl_check_t PL_check[] /* or perlvars.h */
MEMBER_TO_FPTR(Perl_ck_null), /* method_named */
MEMBER_TO_FPTR(Perl_ck_null), /* dor */
MEMBER_TO_FPTR(Perl_ck_null), /* dorassign */
+ MEMBER_TO_FPTR(Perl_ck_null), /* entergiven */
+ MEMBER_TO_FPTR(Perl_ck_null), /* leavegiven */
+ MEMBER_TO_FPTR(Perl_ck_null), /* enterwhen */
+ MEMBER_TO_FPTR(Perl_ck_null), /* leavewhen */
+ MEMBER_TO_FPTR(Perl_ck_null), /* break */
+ MEMBER_TO_FPTR(Perl_ck_null), /* continue */
+ MEMBER_TO_FPTR(Perl_ck_smartmatch), /* smartmatch */
+ MEMBER_TO_FPTR(Perl_ck_say), /* say */
MEMBER_TO_FPTR(Perl_ck_null), /* custom */
}
#endif
@@ -1849,6 +1881,14 @@ EXT const U32 PL_opargs[] = {
0x00000c40, /* method_named */
0x00000600, /* dor */
0x00000604, /* dorassign */
+ 0x00000640, /* entergiven */
+ 0x00000200, /* leavegiven */
+ 0x00000640, /* enterwhen */
+ 0x00000200, /* leavewhen */
+ 0x00000000, /* break */
+ 0x00000000, /* continue */
+ 0x00000404, /* smartmatch */
+ 0x0005c815, /* say */
0x00000000, /* custom */
};
#endif
diff --git a/opcode.pl b/opcode.pl
index 898a248aa7..19030a6adc 100755
--- a/opcode.pl
+++ b/opcode.pl
@@ -78,6 +78,7 @@ my @raw_alias = (
Perl_pp_or => ['orassign'],
Perl_pp_ucfirst => ['lcfirst'],
Perl_pp_sle => [qw(slt sgt sge)],
+ Perl_pp_print => ['say'],
);
while (my ($func, $names) = splice @raw_alias, 0, 2) {
@@ -1019,6 +1020,16 @@ method_named method with known name ck_null d$
dor defined or (//) ck_null |
dorassign defined or assignment (//=) ck_null s|
+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
+smartmatch smart match ck_smartmatch s2
+
+say say ck_say ims@ F? L
+
# Add new ops before this, the custom operator.
custom unknown custom operator ck_null 0
diff --git a/opnames.h b/opnames.h
index ba6a26b03f..e428e1ca67 100644
--- a/opnames.h
+++ b/opnames.h
@@ -367,11 +367,19 @@ typedef enum opcode {
OP_METHOD_NAMED,/* 350 */
OP_DOR, /* 351 */
OP_DORASSIGN, /* 352 */
- OP_CUSTOM, /* 353 */
+ OP_ENTERGIVEN, /* 353 */
+ OP_LEAVEGIVEN, /* 354 */
+ OP_ENTERWHEN, /* 355 */
+ OP_LEAVEWHEN, /* 356 */
+ OP_BREAK, /* 357 */
+ OP_CONTINUE, /* 358 */
+ OP_SMARTMATCH, /* 359 */
+ OP_SAY, /* 360 */
+ OP_CUSTOM, /* 361 */
OP_max
} opcode;
-#define MAXO 354
+#define MAXO 362
#define OP_phoney_INPUT_ONLY -1
#define OP_phoney_OUTPUT_ONLY -2
diff --git a/perl.h b/perl.h
index 5da4f62579..ea01ddad8c 100644
--- a/perl.h
+++ b/perl.h
@@ -4019,6 +4019,9 @@ EXTCONST char* const PL_block_type[] = {
"LOOP",
"SUBST",
"BLOCK",
+ "FORMAT",
+ "GIVEN",
+ "WHEN"
};
#else
EXTCONST char* PL_block_type[];
@@ -4134,6 +4137,9 @@ enum { /* pass one of these to get_vtbl */
#define HINT_ASSERTING 0x01000000
#define HINT_ASSERTIONSSEEN 0x02000000
+#define HINT_HH_FOR_EVAL 0x04000000 /* Squirrel a copy of %^H away
+ * with every eval "string" */
+
/* The following are stored in $sort::hints, not in PL_hints */
#define HINT_SORT_SORT_BITS 0x000000FF /* allow 256 different ones */
#define HINT_SORT_QUICKSORT 0x00000001
@@ -4725,7 +4731,10 @@ enum {
to_sv_amg, to_av_amg,
to_hv_amg, to_gv_amg,
to_cv_amg, iter_amg,
- int_amg, DESTROY_amg,
+ int_amg, smart_amg,
+
+ /* Note: Perl_Gv_AMupdate() assumes that DESTROY is the last entry */
+ DESTROY_amg,
max_amg_code
/* Do not leave a trailing comma here. C9X allows it, C89 doesn't. */
};
@@ -4772,7 +4781,8 @@ EXTCONST char * const PL_AMG_names[NofAMmeth] = {
"(${}", "(@{}",
"(%{}", "(*{}",
"(&{}", "(<>",
- "(int", "DESTROY",
+ "(int", "(~~",
+ "DESTROY"
};
#else
EXTCONST char * PL_AMG_names[NofAMmeth];
diff --git a/perl_keyword.pl b/perl_keyword.pl
index bb8bc74865..d0471f6891 100644
--- a/perl_keyword.pl
+++ b/perl_keyword.pl
@@ -5,34 +5,45 @@ use Devel::Tokenizer::C 0.05;
use strict;
use warnings;
-my @pos = qw(__DATA__ __END__ AUTOLOAD BEGIN CHECK DESTROY do delete defined
- END else eval elsif exists for format foreach grep goto glob INIT
- if last local m my map next no our pos print printf package
- prototype q qr qq qw qx redo return require s scalar sort split
- study sub tr tie tied use undef until untie unless while y);
+my @pos = qw(__DATA__ __END__ AUTOLOAD BEGIN CHECK DESTROY default defined
+ delete do END else eval elsif exists for format foreach given grep
+ goto glob INIT if last local m my map next no our pos print printf
+ package prototype q qr qq qw qx redo return require s scalar sort
+ split study sub tr tie tied use undef until untie unless when while
+ y);
my @neg = qw(__FILE__ __LINE__ __PACKAGE__ and abs alarm atan2 accept bless
- bind binmode CORE cmp chr cos chop close chdir chomp chmod chown
- crypt chroot caller connect closedir continue die dump dbmopen
- dbmclose eq eof err exp exit exec each endgrent endpwent
- endnetent endhostent endservent endprotoent fork fcntl flock
- fileno formline getppid getpgrp getpwent getpwnam getpwuid
- getpeername getprotoent getpriority getprotobyname
- getprotobynumber gethostbyname gethostbyaddr gethostent
- getnetbyname getnetbyaddr getnetent getservbyname getservbyport
- getservent getsockname getsockopt getgrent getgrnam getgrgid
- getlogin getc gt ge gmtime hex int index ioctl join keys kill lt
- le lc log link lock lstat length listen lcfirst localtime mkdir
- msgctl msgget msgrcv msgsnd ne not or ord oct open opendir pop
- push pack pipe quotemeta ref read rand recv rmdir reset rename
- rindex reverse readdir readlink readline readpipe rewinddir seek
- send semop select semctl semget setpgrp seekdir setpwent setgrent
- setnetent setsockopt sethostent setservent setpriority
- setprotoent shift shmctl shmget shmread shmwrite shutdown sin
- sleep socket socketpair sprintf splice sqrt srand stat substr
- system symlink syscall sysopen sysread sysseek syswrite tell time
- times telldir truncate uc utime umask unpack unlink unshift
- ucfirst values vec warn wait write waitpid wantarray x xor);
+ break bind binmode CORE cmp chr cos chop close chdir chomp chmod
+ chown crypt chroot caller connect closedir continue die dump
+ dbmopen dbmclose eq eof err exp exit exec each endgrent endpwent
+ endnetent endhostent endservent endprotoent fork fcntl flock fileno
+ formline getppid getpgrp getpwent getpwnam getpwuid getpeername
+ getprotoent getpriority getprotobyname getprotobynumber
+ gethostbyname gethostbyaddr gethostent getnetbyname getnetbyaddr
+ getnetent getservbyname getservbyport getservent getsockname
+ getsockopt getgrent getgrnam getgrgid getlogin getc gt ge gmtime
+ hex int index ioctl join keys kill lt le lc log link lock lstat
+ length listen lcfirst localtime mkdir msgctl msgget msgrcv msgsnd
+ ne not or ord oct open opendir pop push pack pipe quotemeta ref
+ read rand recv rmdir reset rename rindex reverse readdir readlink
+ readline readpipe rewinddir say seek send semop select semctl semget
+ setpgrp seekdir setpwent setgrent setnetent setsockopt sethostent
+ setservent setpriority setprotoent shift shmctl shmget shmread
+ shmwrite shutdown sin sleep socket socketpair sprintf splice sqrt
+ srand stat substr system symlink syscall sysopen sysread sysseek
+ syswrite tell time times telldir truncate uc utime umask unpack
+ unlink unshift ucfirst values vec warn wait write waitpid wantarray
+ x xor);
+
+my %feature_kw = (
+ given => 'switch',
+ when => 'switch',
+ default => 'switch',
+ # continue is already a keyword
+ break => 'switch',
+
+ say => 'say',
+ );
my %pos = map { ($_ => 1) } @pos;
@@ -71,7 +82,13 @@ if(ckWARN_d(WARN_SYNTAX))
Perl_warner(aTHX_ packWARN(WARN_SYNTAX), "elseif should be elsif");
END
}
-
+ elsif (my $feature = $feature_kw{$k}) {
+ my $feature_len = length($feature);
+ $feature =~ s/([\\"])/\\$1/g;
+ return <<END;
+return (FEATURE_IS_ENABLED("$feature", $feature_len) ? ${sign}KEY_$k : 0);
+END
+ }
return <<END;
return ${sign}KEY_$k;
END
diff --git a/perly.act b/perly.act
index 590c0a5328..817bde9e18 100644
--- a/perly.act
+++ b/perly.act
@@ -1,56 +1,61 @@
case 2:
-#line 98 "perly.y"
+#line 100 "perly.y"
{ (yyval.ival) = (yyvsp[-1].ival); newPROG(block_end((yyvsp[-1].ival),(yyvsp[0].opval))); ;}
break;
case 3:
-#line 103 "perly.y"
+#line 105 "perly.y"
{ if (PL_copline > (line_t)(yyvsp[-3].ival))
PL_copline = (line_t)(yyvsp[-3].ival);
(yyval.opval) = block_end((yyvsp[-2].ival), (yyvsp[-1].opval)); ;}
break;
case 4:
-#line 109 "perly.y"
+#line 111 "perly.y"
{ (yyval.ival) = block_start(TRUE); ;}
break;
case 5:
-#line 113 "perly.y"
+#line 115 "perly.y"
+ { (yyval.ival) = (I32) allocmy("$_"); ;}
+ break;
+
+ case 6:
+#line 119 "perly.y"
{
PL_expect = XSTATE; (yyval.ival) = block_start(TRUE);
;}
break;
- case 6:
-#line 120 "perly.y"
+ case 7:
+#line 126 "perly.y"
{ if (PL_copline > (line_t)(yyvsp[-3].ival))
PL_copline = (line_t)(yyvsp[-3].ival);
(yyval.opval) = block_end((yyvsp[-2].ival), (yyvsp[-1].opval)); ;}
break;
- case 7:
-#line 126 "perly.y"
+ case 8:
+#line 132 "perly.y"
{ (yyval.ival) = block_start(FALSE); ;}
break;
- case 8:
-#line 130 "perly.y"
+ case 9:
+#line 136 "perly.y"
{ (yyval.ival) = PL_savestack_ix; ;}
break;
- case 9:
-#line 134 "perly.y"
+ case 10:
+#line 140 "perly.y"
{ (yyval.opval) = Nullop; ;}
break;
- case 10:
-#line 136 "perly.y"
+ case 11:
+#line 142 "perly.y"
{ (yyval.opval) = (yyvsp[-1].opval); ;}
break;
- case 11:
-#line 138 "perly.y"
+ case 12:
+#line 144 "perly.y"
{ LEAVE_SCOPE((yyvsp[-1].ival));
(yyval.opval) = append_list(OP_LINESEQ,
(LISTOP*)(yyvsp[-2].opval), (LISTOP*)(yyvsp[0].opval));
@@ -58,13 +63,23 @@ case 2:
if ((yyvsp[-2].opval) && (yyvsp[0].opval)) PL_hints |= HINT_BLOCK_SCOPE; ;}
break;
- case 12:
-#line 147 "perly.y"
+ case 13:
+#line 153 "perly.y"
+ { (yyval.opval) = newSTATEOP(0, (yyvsp[-1].pval), (yyvsp[0].opval)); ;}
+ break;
+
+ case 15:
+#line 156 "perly.y"
+ { (yyval.opval) = (yyvsp[0].opval); ;}
+ break;
+
+ case 16:
+#line 158 "perly.y"
{ (yyval.opval) = newSTATEOP(0, (yyvsp[-1].pval), (yyvsp[0].opval)); ;}
break;
- case 14:
-#line 150 "perly.y"
+ case 17:
+#line 160 "perly.y"
{ if ((yyvsp[-1].pval) != Nullch) {
(yyval.opval) = newSTATEOP(0, (yyvsp[-1].pval), newOP(OP_NULL, 0));
}
@@ -75,91 +90,102 @@ case 2:
PL_expect = XSTATE; ;}
break;
- case 15:
-#line 159 "perly.y"
+ case 18:
+#line 169 "perly.y"
{ (yyval.opval) = newSTATEOP(0, (yyvsp[-2].pval), (yyvsp[-1].opval));
PL_expect = XSTATE; ;}
break;
- case 16:
-#line 165 "perly.y"
+ case 19:
+#line 175 "perly.y"
{ (yyval.opval) = Nullop; ;}
break;
- case 17:
-#line 167 "perly.y"
+ case 20:
+#line 177 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 18:
-#line 169 "perly.y"
+ case 21:
+#line 179 "perly.y"
{ (yyval.opval) = newLOGOP(OP_AND, 0, (yyvsp[0].opval), (yyvsp[-2].opval)); ;}
break;
- case 19:
-#line 171 "perly.y"
+ case 22:
+#line 181 "perly.y"
{ (yyval.opval) = newLOGOP(OP_OR, 0, (yyvsp[0].opval), (yyvsp[-2].opval)); ;}
break;
- case 20:
-#line 173 "perly.y"
+ case 23:
+#line 183 "perly.y"
{ (yyval.opval) = newLOOPOP(OPf_PARENS, 1, scalar((yyvsp[0].opval)), (yyvsp[-2].opval)); ;}
break;
- case 21:
-#line 175 "perly.y"
+ case 24:
+#line 185 "perly.y"
{ (yyval.opval) = newLOOPOP(OPf_PARENS, 1, (yyvsp[0].opval), (yyvsp[-2].opval));;}
break;
- case 22:
-#line 177 "perly.y"
+ case 25:
+#line 187 "perly.y"
{ (yyval.opval) = newFOROP(0, Nullch, (line_t)(yyvsp[-1].ival),
Nullop, (yyvsp[0].opval), (yyvsp[-2].opval), Nullop); ;}
break;
- case 23:
-#line 183 "perly.y"
+ case 26:
+#line 193 "perly.y"
{ (yyval.opval) = Nullop; ;}
break;
- case 24:
-#line 185 "perly.y"
+ case 27:
+#line 195 "perly.y"
{ ((yyvsp[0].opval))->op_flags |= OPf_PARENS; (yyval.opval) = scope((yyvsp[0].opval)); ;}
break;
- case 25:
-#line 187 "perly.y"
+ case 28:
+#line 197 "perly.y"
{ PL_copline = (line_t)(yyvsp[-5].ival);
(yyval.opval) = newCONDOP(0, (yyvsp[-3].opval), scope((yyvsp[-1].opval)), (yyvsp[0].opval));
PL_hints |= HINT_BLOCK_SCOPE; ;}
break;
- case 26:
-#line 194 "perly.y"
+ case 29:
+#line 204 "perly.y"
{ PL_copline = (line_t)(yyvsp[-6].ival);
(yyval.opval) = block_end((yyvsp[-4].ival),
newCONDOP(0, (yyvsp[-3].opval), scope((yyvsp[-1].opval)), (yyvsp[0].opval))); ;}
break;
- case 27:
-#line 198 "perly.y"
+ case 30:
+#line 208 "perly.y"
{ PL_copline = (line_t)(yyvsp[-6].ival);
(yyval.opval) = block_end((yyvsp[-4].ival),
newCONDOP(0, (yyvsp[-3].opval), scope((yyvsp[-1].opval)), (yyvsp[0].opval))); ;}
break;
- case 28:
-#line 205 "perly.y"
+ case 31:
+#line 215 "perly.y"
+ { (yyval.opval) = block_end((yyvsp[-3].ival),
+ newWHENOP((yyvsp[-2].opval), scope((yyvsp[0].opval)))); ;}
+ break;
+
+ case 32:
+#line 218 "perly.y"
+ { (yyval.opval) = newWHENOP(0, scope((yyvsp[0].opval))); ;}
+ break;
+
+ case 33:
+#line 223 "perly.y"
{ (yyval.opval) = Nullop; ;}
break;
- case 29:
-#line 207 "perly.y"
+ case 34:
+#line 225 "perly.y"
{ (yyval.opval) = scope((yyvsp[0].opval)); ;}
break;
- case 30:
-#line 212 "perly.y"
+ case 35:
+#line 230 "perly.y"
{ PL_copline = (line_t)(yyvsp[-7].ival);
(yyval.opval) = block_end((yyvsp[-5].ival),
newSTATEOP(0, (yyvsp[-8].pval),
@@ -167,8 +193,8 @@ case 2:
(yyvsp[-7].ival), (yyvsp[-4].opval), (yyvsp[-1].opval), (yyvsp[0].opval), (yyvsp[-2].ival)))); ;}
break;
- case 31:
-#line 218 "perly.y"
+ case 36:
+#line 236 "perly.y"
{ PL_copline = (line_t)(yyvsp[-7].ival);
(yyval.opval) = block_end((yyvsp[-5].ival),
newSTATEOP(0, (yyvsp[-8].pval),
@@ -176,27 +202,27 @@ case 2:
(yyvsp[-7].ival), (yyvsp[-4].opval), (yyvsp[-1].opval), (yyvsp[0].opval), (yyvsp[-2].ival)))); ;}
break;
- case 32:
-#line 224 "perly.y"
+ case 37:
+#line 242 "perly.y"
{ (yyval.opval) = block_end((yyvsp[-6].ival),
newFOROP(0, (yyvsp[-9].pval), (line_t)(yyvsp[-8].ival), (yyvsp[-5].opval), (yyvsp[-3].opval), (yyvsp[-1].opval), (yyvsp[0].opval))); ;}
break;
- case 33:
-#line 227 "perly.y"
+ case 38:
+#line 245 "perly.y"
{ (yyval.opval) = block_end((yyvsp[-4].ival),
newFOROP(0, (yyvsp[-8].pval), (line_t)(yyvsp[-7].ival), mod((yyvsp[-6].opval), OP_ENTERLOOP),
(yyvsp[-3].opval), (yyvsp[-1].opval), (yyvsp[0].opval))); ;}
break;
- case 34:
-#line 231 "perly.y"
+ case 39:
+#line 249 "perly.y"
{ (yyval.opval) = block_end((yyvsp[-4].ival),
newFOROP(0, (yyvsp[-7].pval), (line_t)(yyvsp[-6].ival), Nullop, (yyvsp[-3].opval), (yyvsp[-1].opval), (yyvsp[0].opval))); ;}
break;
- case 35:
-#line 236 "perly.y"
+ case 40:
+#line 254 "perly.y"
{ OP *forop;
PL_copline = (line_t)(yyvsp[-10].ival);
forop = newSTATEOP(0, (yyvsp[-11].pval),
@@ -213,122 +239,131 @@ case 2:
(yyval.opval) = block_end((yyvsp[-8].ival), forop); ;}
break;
- case 36:
-#line 251 "perly.y"
+ case 41:
+#line 269 "perly.y"
{ (yyval.opval) = newSTATEOP(0, (yyvsp[-2].pval),
newWHILEOP(0, 1, (LOOP*)Nullop,
NOLINE, Nullop, (yyvsp[-1].opval), (yyvsp[0].opval), 0)); ;}
break;
- case 37:
-#line 258 "perly.y"
+ case 42:
+#line 276 "perly.y"
+ { PL_copline = (line_t) (yyvsp[-6].ival);
+ (yyval.opval) = block_end((yyvsp[-4].ival),
+ newSTATEOP(0, (yyvsp[-7].pval),
+ newGIVENOP((yyvsp[-2].opval), scope((yyvsp[0].opval)),
+ (PADOFFSET) (yyvsp[-3].ival)) )); ;}
+ break;
+
+ case 43:
+#line 285 "perly.y"
{ (yyval.ival) = (PL_min_intro_pending &&
PL_max_intro_pending >= PL_min_intro_pending);
intro_my(); ;}
break;
- case 38:
-#line 264 "perly.y"
+ case 44:
+#line 291 "perly.y"
{ (yyval.opval) = Nullop; ;}
break;
- case 40:
-#line 270 "perly.y"
+ case 46:
+#line 297 "perly.y"
{ (void)scan_num("1", &yylval); (yyval.opval) = yylval.opval; ;}
break;
- case 42:
-#line 276 "perly.y"
+ case 48:
+#line 303 "perly.y"
{ (yyval.opval) = invert(scalar((yyvsp[0].opval))); ;}
break;
- case 43:
-#line 281 "perly.y"
+ case 49:
+#line 308 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); intro_my(); ;}
break;
- case 44:
-#line 285 "perly.y"
+ case 50:
+#line 312 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); intro_my(); ;}
break;
- case 45:
-#line 289 "perly.y"
+ case 51:
+#line 316 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); intro_my(); ;}
break;
- case 46:
-#line 294 "perly.y"
+ case 52:
+#line 321 "perly.y"
{ (yyval.pval) = Nullch; ;}
break;
- case 48:
-#line 300 "perly.y"
+ case 54:
+#line 327 "perly.y"
{ (yyval.ival) = 0; ;}
break;
- case 49:
-#line 302 "perly.y"
+ case 55:
+#line 329 "perly.y"
{ (yyval.ival) = 0; ;}
break;
- case 50:
-#line 304 "perly.y"
+ case 56:
+#line 331 "perly.y"
{ (yyval.ival) = 0; ;}
break;
- case 51:
-#line 306 "perly.y"
+ case 57:
+#line 333 "perly.y"
{ (yyval.ival) = 0; ;}
break;
- case 52:
-#line 308 "perly.y"
+ case 58:
+#line 335 "perly.y"
{ (yyval.ival) = 0; ;}
break;
- case 53:
-#line 312 "perly.y"
+ case 59:
+#line 339 "perly.y"
{ newFORM((yyvsp[-2].ival), (yyvsp[-1].opval), (yyvsp[0].opval)); ;}
break;
- case 54:
-#line 315 "perly.y"
+ case 60:
+#line 342 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 55:
-#line 316 "perly.y"
+ case 61:
+#line 343 "perly.y"
{ (yyval.opval) = Nullop; ;}
break;
- case 56:
-#line 321 "perly.y"
+ case 62:
+#line 348 "perly.y"
{ newMYSUB((yyvsp[-4].ival), (yyvsp[-3].opval), (yyvsp[-2].opval), (yyvsp[-1].opval), (yyvsp[0].opval)); ;}
break;
- case 57:
-#line 326 "perly.y"
+ case 63:
+#line 353 "perly.y"
{ newATTRSUB((yyvsp[-4].ival), (yyvsp[-3].opval), (yyvsp[-2].opval), (yyvsp[-1].opval), (yyvsp[0].opval)); ;}
break;
- case 58:
-#line 330 "perly.y"
+ case 64:
+#line 357 "perly.y"
{ (yyval.ival) = start_subparse(FALSE, 0); ;}
break;
- case 59:
-#line 334 "perly.y"
+ case 65:
+#line 361 "perly.y"
{ (yyval.ival) = start_subparse(FALSE, CVf_ANON); ;}
break;
- case 60:
-#line 338 "perly.y"
+ case 66:
+#line 365 "perly.y"
{ (yyval.ival) = start_subparse(TRUE, 0); ;}
break;
- case 61:
-#line 342 "perly.y"
+ case 67:
+#line 369 "perly.y"
{ const char *const name = SvPV_nolen_const(((SVOP*)(yyvsp[0].opval))->op_sv);
if (strEQ(name, "BEGIN") || strEQ(name, "END")
|| strEQ(name, "INIT") || strEQ(name, "CHECK"))
@@ -336,387 +371,387 @@ case 2:
(yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 62:
-#line 351 "perly.y"
+ case 68:
+#line 378 "perly.y"
{ (yyval.opval) = Nullop; ;}
break;
- case 64:
-#line 357 "perly.y"
+ case 70:
+#line 384 "perly.y"
{ (yyval.opval) = Nullop; ;}
break;
- case 65:
-#line 359 "perly.y"
+ case 71:
+#line 386 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 66:
-#line 361 "perly.y"
+ case 72:
+#line 388 "perly.y"
{ (yyval.opval) = Nullop; ;}
break;
- case 67:
-#line 366 "perly.y"
+ case 73:
+#line 393 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 68:
-#line 368 "perly.y"
+ case 74:
+#line 395 "perly.y"
{ (yyval.opval) = Nullop; ;}
break;
- case 69:
-#line 372 "perly.y"
+ case 75:
+#line 399 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 70:
-#line 373 "perly.y"
+ case 76:
+#line 400 "perly.y"
{ (yyval.opval) = Nullop; PL_expect = XSTATE; ;}
break;
- case 71:
-#line 377 "perly.y"
+ case 77:
+#line 404 "perly.y"
{ package((yyvsp[-1].opval)); ;}
break;
- case 72:
-#line 381 "perly.y"
+ case 78:
+#line 408 "perly.y"
{ CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ ;}
break;
- case 73:
-#line 383 "perly.y"
+ case 79:
+#line 410 "perly.y"
{ utilize((yyvsp[-6].ival), (yyvsp[-5].ival), (yyvsp[-3].opval), (yyvsp[-2].opval), (yyvsp[-1].opval)); ;}
break;
- case 74:
-#line 388 "perly.y"
+ case 80:
+#line 415 "perly.y"
{ (yyval.opval) = newLOGOP(OP_AND, 0, (yyvsp[-2].opval), (yyvsp[0].opval)); ;}
break;
- case 75:
-#line 390 "perly.y"
+ case 81:
+#line 417 "perly.y"
{ (yyval.opval) = newLOGOP((yyvsp[-1].ival), 0, (yyvsp[-2].opval), (yyvsp[0].opval)); ;}
break;
- case 76:
-#line 392 "perly.y"
+ case 82:
+#line 419 "perly.y"
{ (yyval.opval) = newLOGOP(OP_DOR, 0, (yyvsp[-2].opval), (yyvsp[0].opval)); ;}
break;
- case 78:
-#line 398 "perly.y"
+ case 84:
+#line 425 "perly.y"
{ (yyval.opval) = (yyvsp[-1].opval); ;}
break;
- case 79:
-#line 400 "perly.y"
+ case 85:
+#line 427 "perly.y"
{ (yyval.opval) = append_elem(OP_LIST, (yyvsp[-2].opval), (yyvsp[0].opval)); ;}
break;
- case 81:
-#line 406 "perly.y"
+ case 87:
+#line 433 "perly.y"
{ (yyval.opval) = convert((yyvsp[-2].ival), OPf_STACKED,
prepend_elem(OP_LIST, newGVREF((yyvsp[-2].ival),(yyvsp[-1].opval)), (yyvsp[0].opval)) ); ;}
break;
- case 82:
-#line 409 "perly.y"
+ case 88:
+#line 436 "perly.y"
{ (yyval.opval) = convert((yyvsp[-4].ival), OPf_STACKED,
prepend_elem(OP_LIST, newGVREF((yyvsp[-4].ival),(yyvsp[-2].opval)), (yyvsp[-1].opval)) ); ;}
break;
- case 83:
-#line 412 "perly.y"
+ case 89:
+#line 439 "perly.y"
{ (yyval.opval) = convert(OP_ENTERSUB, OPf_STACKED,
append_elem(OP_LIST,
prepend_elem(OP_LIST, scalar((yyvsp[-5].opval)), (yyvsp[-1].opval)),
newUNOP(OP_METHOD, 0, (yyvsp[-3].opval)))); ;}
break;
- case 84:
-#line 417 "perly.y"
+ case 90:
+#line 444 "perly.y"
{ (yyval.opval) = convert(OP_ENTERSUB, OPf_STACKED,
append_elem(OP_LIST, scalar((yyvsp[-2].opval)),
newUNOP(OP_METHOD, 0, (yyvsp[0].opval)))); ;}
break;
- case 85:
-#line 421 "perly.y"
+ case 91:
+#line 448 "perly.y"
{ (yyval.opval) = convert(OP_ENTERSUB, OPf_STACKED,
append_elem(OP_LIST,
prepend_elem(OP_LIST, (yyvsp[-1].opval), (yyvsp[0].opval)),
newUNOP(OP_METHOD, 0, (yyvsp[-2].opval)))); ;}
break;
- case 86:
-#line 426 "perly.y"
+ case 92:
+#line 453 "perly.y"
{ (yyval.opval) = convert(OP_ENTERSUB, OPf_STACKED,
append_elem(OP_LIST,
prepend_elem(OP_LIST, (yyvsp[-3].opval), (yyvsp[-1].opval)),
newUNOP(OP_METHOD, 0, (yyvsp[-4].opval)))); ;}
break;
- case 87:
-#line 431 "perly.y"
+ case 93:
+#line 458 "perly.y"
{ (yyval.opval) = convert((yyvsp[-1].ival), 0, (yyvsp[0].opval)); ;}
break;
- case 88:
-#line 433 "perly.y"
+ case 94:
+#line 460 "perly.y"
{ (yyval.opval) = convert((yyvsp[-3].ival), 0, (yyvsp[-1].opval)); ;}
break;
- case 89:
-#line 435 "perly.y"
+ case 95:
+#line 462 "perly.y"
{ (yyvsp[0].opval) = newANONATTRSUB((yyvsp[-1].ival), 0, Nullop, (yyvsp[0].opval)); ;}
break;
- case 90:
-#line 437 "perly.y"
+ case 96:
+#line 464 "perly.y"
{ (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
append_elem(OP_LIST,
prepend_elem(OP_LIST, (yyvsp[-2].opval), (yyvsp[0].opval)), (yyvsp[-4].opval))); ;}
break;
- case 93:
-#line 451 "perly.y"
+ case 99:
+#line 478 "perly.y"
{ (yyval.opval) = newBINOP(OP_GELEM, 0, (yyvsp[-4].opval), scalar((yyvsp[-2].opval)));
PL_expect = XOPERATOR; ;}
break;
- case 94:
-#line 454 "perly.y"
+ case 100:
+#line 481 "perly.y"
{ (yyval.opval) = newBINOP(OP_AELEM, 0, oopsAV((yyvsp[-3].opval)), scalar((yyvsp[-1].opval))); ;}
break;
- case 95:
-#line 456 "perly.y"
+ case 101:
+#line 483 "perly.y"
{ (yyval.opval) = newBINOP(OP_AELEM, 0,
ref(newAVREF((yyvsp[-4].opval)),OP_RV2AV),
scalar((yyvsp[-1].opval)));;}
break;
- case 96:
-#line 460 "perly.y"
+ case 102:
+#line 487 "perly.y"
{ (yyval.opval) = newBINOP(OP_AELEM, 0,
ref(newAVREF((yyvsp[-3].opval)),OP_RV2AV),
scalar((yyvsp[-1].opval)));;}
break;
- case 97:
-#line 464 "perly.y"
+ case 103:
+#line 491 "perly.y"
{ (yyval.opval) = newBINOP(OP_HELEM, 0, oopsHV((yyvsp[-4].opval)), jmaybe((yyvsp[-2].opval)));
PL_expect = XOPERATOR; ;}
break;
- case 98:
-#line 467 "perly.y"
+ case 104:
+#line 494 "perly.y"
{ (yyval.opval) = newBINOP(OP_HELEM, 0,
ref(newHVREF((yyvsp[-5].opval)),OP_RV2HV),
jmaybe((yyvsp[-2].opval)));
PL_expect = XOPERATOR; ;}
break;
- case 99:
-#line 472 "perly.y"
+ case 105:
+#line 499 "perly.y"
{ (yyval.opval) = newBINOP(OP_HELEM, 0,
ref(newHVREF((yyvsp[-4].opval)),OP_RV2HV),
jmaybe((yyvsp[-2].opval)));
PL_expect = XOPERATOR; ;}
break;
- case 100:
-#line 477 "perly.y"
+ case 106:
+#line 504 "perly.y"
{ (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
newCVREF(0, scalar((yyvsp[-3].opval)))); ;}
break;
- case 101:
-#line 480 "perly.y"
+ case 107:
+#line 507 "perly.y"
{ (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
append_elem(OP_LIST, (yyvsp[-1].opval),
newCVREF(0, scalar((yyvsp[-4].opval))))); ;}
break;
- case 102:
-#line 485 "perly.y"
+ case 108:
+#line 512 "perly.y"
{ (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
append_elem(OP_LIST, (yyvsp[-1].opval),
newCVREF(0, scalar((yyvsp[-3].opval))))); ;}
break;
- case 103:
-#line 489 "perly.y"
+ case 109:
+#line 516 "perly.y"
{ (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
newCVREF(0, scalar((yyvsp[-2].opval)))); ;}
break;
- case 104:
-#line 492 "perly.y"
+ case 110:
+#line 519 "perly.y"
{ (yyval.opval) = newSLICEOP(0, (yyvsp[-1].opval), (yyvsp[-4].opval)); ;}
break;
- case 105:
-#line 494 "perly.y"
+ case 111:
+#line 521 "perly.y"
{ (yyval.opval) = newSLICEOP(0, (yyvsp[-1].opval), Nullop); ;}
break;
- case 106:
-#line 499 "perly.y"
+ case 112:
+#line 526 "perly.y"
{ (yyval.opval) = newASSIGNOP(OPf_STACKED, (yyvsp[-2].opval), (yyvsp[-1].ival), (yyvsp[0].opval)); ;}
break;
- case 107:
-#line 501 "perly.y"
+ case 113:
+#line 528 "perly.y"
{ (yyval.opval) = newBINOP((yyvsp[-1].ival), 0, scalar((yyvsp[-2].opval)), scalar((yyvsp[0].opval))); ;}
break;
- case 108:
-#line 503 "perly.y"
+ case 114:
+#line 530 "perly.y"
{ if ((yyvsp[-1].ival) != OP_REPEAT)
scalar((yyvsp[-2].opval));
(yyval.opval) = newBINOP((yyvsp[-1].ival), 0, (yyvsp[-2].opval), scalar((yyvsp[0].opval))); ;}
break;
- case 109:
-#line 507 "perly.y"
+ case 115:
+#line 534 "perly.y"
{ (yyval.opval) = newBINOP((yyvsp[-1].ival), 0, scalar((yyvsp[-2].opval)), scalar((yyvsp[0].opval))); ;}
break;
- case 110:
-#line 509 "perly.y"
+ case 116:
+#line 536 "perly.y"
{ (yyval.opval) = newBINOP((yyvsp[-1].ival), 0, scalar((yyvsp[-2].opval)), scalar((yyvsp[0].opval))); ;}
break;
- case 111:
-#line 511 "perly.y"
+ case 117:
+#line 538 "perly.y"
{ (yyval.opval) = newBINOP((yyvsp[-1].ival), 0, scalar((yyvsp[-2].opval)), scalar((yyvsp[0].opval))); ;}
break;
- case 112:
-#line 513 "perly.y"
+ case 118:
+#line 540 "perly.y"
{ (yyval.opval) = newBINOP((yyvsp[-1].ival), 0, scalar((yyvsp[-2].opval)), scalar((yyvsp[0].opval))); ;}
break;
- case 113:
-#line 515 "perly.y"
+ case 119:
+#line 542 "perly.y"
{ (yyval.opval) = newBINOP((yyvsp[-1].ival), 0, scalar((yyvsp[-2].opval)), scalar((yyvsp[0].opval))); ;}
break;
- case 114:
-#line 517 "perly.y"
+ case 120:
+#line 544 "perly.y"
{ (yyval.opval) = newBINOP((yyvsp[-1].ival), 0, scalar((yyvsp[-2].opval)), scalar((yyvsp[0].opval))); ;}
break;
- case 115:
-#line 519 "perly.y"
+ case 121:
+#line 546 "perly.y"
{ (yyval.opval) = newRANGE((yyvsp[-1].ival), scalar((yyvsp[-2].opval)), scalar((yyvsp[0].opval)));;}
break;
- case 116:
-#line 521 "perly.y"
+ case 122:
+#line 548 "perly.y"
{ (yyval.opval) = newLOGOP(OP_AND, 0, (yyvsp[-2].opval), (yyvsp[0].opval)); ;}
break;
- case 117:
-#line 523 "perly.y"
+ case 123:
+#line 550 "perly.y"
{ (yyval.opval) = newLOGOP(OP_OR, 0, (yyvsp[-2].opval), (yyvsp[0].opval)); ;}
break;
- case 118:
-#line 525 "perly.y"
+ case 124:
+#line 552 "perly.y"
{ (yyval.opval) = newLOGOP(OP_DOR, 0, (yyvsp[-2].opval), (yyvsp[0].opval)); ;}
break;
- case 119:
-#line 527 "perly.y"
+ case 125:
+#line 554 "perly.y"
{ (yyval.opval) = bind_match((yyvsp[-1].ival), (yyvsp[-2].opval), (yyvsp[0].opval)); ;}
break;
- case 120:
-#line 532 "perly.y"
+ case 126:
+#line 559 "perly.y"
{ (yyval.opval) = newUNOP(OP_NEGATE, 0, scalar((yyvsp[0].opval))); ;}
break;
- case 121:
-#line 534 "perly.y"
+ case 127:
+#line 561 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 122:
-#line 536 "perly.y"
+ case 128:
+#line 563 "perly.y"
{ (yyval.opval) = newUNOP(OP_NOT, 0, scalar((yyvsp[0].opval))); ;}
break;
- case 123:
-#line 538 "perly.y"
+ case 129:
+#line 565 "perly.y"
{ (yyval.opval) = newUNOP(OP_COMPLEMENT, 0, scalar((yyvsp[0].opval)));;}
break;
- case 124:
-#line 540 "perly.y"
+ case 130:
+#line 567 "perly.y"
{ (yyval.opval) = newUNOP(OP_POSTINC, 0,
mod(scalar((yyvsp[-1].opval)), OP_POSTINC)); ;}
break;
- case 125:
-#line 543 "perly.y"
+ case 131:
+#line 570 "perly.y"
{ (yyval.opval) = newUNOP(OP_POSTDEC, 0,
mod(scalar((yyvsp[-1].opval)), OP_POSTDEC)); ;}
break;
- case 126:
-#line 546 "perly.y"
+ case 132:
+#line 573 "perly.y"
{ (yyval.opval) = newUNOP(OP_PREINC, 0,
mod(scalar((yyvsp[0].opval)), OP_PREINC)); ;}
break;
- case 127:
-#line 549 "perly.y"
+ case 133:
+#line 576 "perly.y"
{ (yyval.opval) = newUNOP(OP_PREDEC, 0,
mod(scalar((yyvsp[0].opval)), OP_PREDEC)); ;}
break;
- case 128:
-#line 556 "perly.y"
+ case 134:
+#line 583 "perly.y"
{ (yyval.opval) = newANONLIST((yyvsp[-1].opval)); ;}
break;
- case 129:
-#line 558 "perly.y"
+ case 135:
+#line 585 "perly.y"
{ (yyval.opval) = newANONLIST(Nullop); ;}
break;
- case 130:
-#line 560 "perly.y"
+ case 136:
+#line 587 "perly.y"
{ (yyval.opval) = newANONHASH((yyvsp[-2].opval)); ;}
break;
- case 131:
-#line 562 "perly.y"
+ case 137:
+#line 589 "perly.y"
{ (yyval.opval) = newANONHASH(Nullop); ;}
break;
- case 132:
-#line 564 "perly.y"
+ case 138:
+#line 591 "perly.y"
{ (yyval.opval) = newANONATTRSUB((yyvsp[-3].ival), (yyvsp[-2].opval), (yyvsp[-1].opval), (yyvsp[0].opval)); ;}
break;
- case 133:
-#line 570 "perly.y"
+ case 139:
+#line 597 "perly.y"
{ (yyval.opval) = dofile((yyvsp[0].opval), (yyvsp[-1].ival)); ;}
break;
- case 134:
-#line 572 "perly.y"
+ case 140:
+#line 599 "perly.y"
{ (yyval.opval) = newUNOP(OP_NULL, OPf_SPECIAL, scope((yyvsp[0].opval))); ;}
break;
- case 135:
-#line 574 "perly.y"
+ case 141:
+#line 601 "perly.y"
{ (yyval.opval) = newUNOP(OP_ENTERSUB,
OPf_SPECIAL|OPf_STACKED,
prepend_elem(OP_LIST,
@@ -726,8 +761,8 @@ case 2:
)),Nullop)); dep();;}
break;
- case 136:
-#line 582 "perly.y"
+ case 142:
+#line 609 "perly.y"
{ (yyval.opval) = newUNOP(OP_ENTERSUB,
OPf_SPECIAL|OPf_STACKED,
append_elem(OP_LIST,
@@ -738,83 +773,83 @@ case 2:
)))); dep();;}
break;
- case 137:
-#line 591 "perly.y"
+ case 143:
+#line 618 "perly.y"
{ (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
prepend_elem(OP_LIST,
scalar(newCVREF(0,scalar((yyvsp[-2].opval)))), Nullop)); dep();;}
break;
- case 138:
-#line 595 "perly.y"
+ case 144:
+#line 622 "perly.y"
{ (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
prepend_elem(OP_LIST,
(yyvsp[-1].opval),
scalar(newCVREF(0,scalar((yyvsp[-3].opval)))))); dep();;}
break;
- case 143:
-#line 607 "perly.y"
+ case 149:
+#line 634 "perly.y"
{ (yyval.opval) = newCONDOP(0, (yyvsp[-4].opval), (yyvsp[-2].opval), (yyvsp[0].opval)); ;}
break;
- case 144:
-#line 609 "perly.y"
+ case 150:
+#line 636 "perly.y"
{ (yyval.opval) = newUNOP(OP_REFGEN, 0, mod((yyvsp[0].opval),OP_REFGEN)); ;}
break;
- case 145:
-#line 611 "perly.y"
+ case 151:
+#line 638 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 146:
-#line 613 "perly.y"
+ case 152:
+#line 640 "perly.y"
{ (yyval.opval) = localize((yyvsp[0].opval),(yyvsp[-1].ival)); ;}
break;
- case 147:
-#line 615 "perly.y"
+ case 153:
+#line 642 "perly.y"
{ (yyval.opval) = sawparens((yyvsp[-1].opval)); ;}
break;
- case 148:
-#line 617 "perly.y"
+ case 154:
+#line 644 "perly.y"
{ (yyval.opval) = sawparens(newNULLLIST()); ;}
break;
- case 149:
-#line 619 "perly.y"
+ case 155:
+#line 646 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 150:
-#line 621 "perly.y"
+ case 156:
+#line 648 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 151:
-#line 623 "perly.y"
+ case 157:
+#line 650 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 152:
-#line 625 "perly.y"
+ case 158:
+#line 652 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 153:
-#line 627 "perly.y"
+ case 159:
+#line 654 "perly.y"
{ (yyval.opval) = newUNOP(OP_AV2ARYLEN, 0, ref((yyvsp[0].opval), OP_AV2ARYLEN));;}
break;
- case 154:
-#line 629 "perly.y"
+ case 160:
+#line 656 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 155:
-#line 631 "perly.y"
+ case 161:
+#line 658 "perly.y"
{ (yyval.opval) = prepend_elem(OP_ASLICE,
newOP(OP_PUSHMARK, 0),
newLISTOP(OP_ASLICE, 0,
@@ -822,8 +857,8 @@ case 2:
ref((yyvsp[-3].opval), OP_ASLICE))); ;}
break;
- case 156:
-#line 637 "perly.y"
+ case 162:
+#line 664 "perly.y"
{ (yyval.opval) = prepend_elem(OP_HSLICE,
newOP(OP_PUSHMARK, 0),
newLISTOP(OP_HSLICE, 0,
@@ -832,224 +867,224 @@ case 2:
PL_expect = XOPERATOR; ;}
break;
- case 157:
-#line 644 "perly.y"
+ case 163:
+#line 671 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 158:
-#line 646 "perly.y"
+ case 164:
+#line 673 "perly.y"
{ (yyval.opval) = newUNOP(OP_ENTERSUB, 0, scalar((yyvsp[0].opval))); ;}
break;
- case 159:
-#line 648 "perly.y"
+ case 165:
+#line 675 "perly.y"
{ (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar((yyvsp[-2].opval))); ;}
break;
- case 160:
-#line 650 "perly.y"
+ case 166:
+#line 677 "perly.y"
{ (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
append_elem(OP_LIST, (yyvsp[-1].opval), scalar((yyvsp[-3].opval)))); ;}
break;
- case 161:
-#line 653 "perly.y"
+ case 167:
+#line 680 "perly.y"
{ (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
append_elem(OP_LIST, (yyvsp[0].opval), scalar((yyvsp[-1].opval)))); ;}
break;
- case 162:
-#line 656 "perly.y"
+ case 168:
+#line 683 "perly.y"
{ (yyval.opval) = newOP((yyvsp[0].ival), OPf_SPECIAL);
PL_hints |= HINT_BLOCK_SCOPE; ;}
break;
- case 163:
-#line 659 "perly.y"
+ case 169:
+#line 686 "perly.y"
{ (yyval.opval) = newLOOPEX((yyvsp[-1].ival),(yyvsp[0].opval)); ;}
break;
- case 164:
-#line 661 "perly.y"
+ case 170:
+#line 688 "perly.y"
{ (yyval.opval) = newUNOP(OP_NOT, 0, scalar((yyvsp[0].opval))); ;}
break;
- case 165:
-#line 663 "perly.y"
+ case 171:
+#line 690 "perly.y"
{ (yyval.opval) = newOP((yyvsp[0].ival), 0); ;}
break;
- case 166:
-#line 665 "perly.y"
+ case 172:
+#line 692 "perly.y"
{ (yyval.opval) = newUNOP((yyvsp[-1].ival), 0, (yyvsp[0].opval)); ;}
break;
- case 167:
-#line 667 "perly.y"
+ case 173:
+#line 694 "perly.y"
{ (yyval.opval) = newUNOP((yyvsp[-1].ival), 0, (yyvsp[0].opval)); ;}
break;
- case 168:
-#line 669 "perly.y"
+ case 174:
+#line 696 "perly.y"
{ (yyval.opval) = newOP(OP_REQUIRE, (yyvsp[0].ival) ? OPf_SPECIAL : 0); ;}
break;
- case 169:
-#line 671 "perly.y"
+ case 175:
+#line 698 "perly.y"
{ (yyval.opval) = newUNOP(OP_REQUIRE, (yyvsp[-1].ival) ? OPf_SPECIAL : 0, (yyvsp[0].opval)); ;}
break;
- case 170:
-#line 673 "perly.y"
+ case 176:
+#line 700 "perly.y"
{ (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
append_elem(OP_LIST, (yyvsp[0].opval), scalar((yyvsp[-1].opval)))); ;}
break;
- case 171:
-#line 676 "perly.y"
+ case 177:
+#line 703 "perly.y"
{ (yyval.opval) = newOP((yyvsp[0].ival), 0); ;}
break;
- case 172:
-#line 678 "perly.y"
+ case 178:
+#line 705 "perly.y"
{ (yyval.opval) = newOP((yyvsp[-2].ival), 0); ;}
break;
- case 173:
-#line 680 "perly.y"
+ case 179:
+#line 707 "perly.y"
{ (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
scalar((yyvsp[0].opval))); ;}
break;
- case 174:
-#line 683 "perly.y"
+ case 180:
+#line 710 "perly.y"
{ (yyval.opval) = (yyvsp[-2].ival) == OP_NOT ? newUNOP((yyvsp[-2].ival), 0, newSVOP(OP_CONST, 0, newSViv(0)))
: newOP((yyvsp[-2].ival), OPf_SPECIAL); ;}
break;
- case 175:
-#line 686 "perly.y"
+ case 181:
+#line 713 "perly.y"
{ (yyval.opval) = newUNOP((yyvsp[-3].ival), 0, (yyvsp[-1].opval)); ;}
break;
- case 176:
-#line 688 "perly.y"
+ case 182:
+#line 715 "perly.y"
{ (yyval.opval) = pmruntime((yyvsp[-3].opval), (yyvsp[-1].opval), 1); ;}
break;
- case 179:
-#line 695 "perly.y"
+ case 185:
+#line 722 "perly.y"
{ (yyval.opval) = my_attrs((yyvsp[-1].opval),(yyvsp[0].opval)); ;}
break;
- case 180:
-#line 697 "perly.y"
+ case 186:
+#line 724 "perly.y"
{ (yyval.opval) = localize((yyvsp[0].opval),(yyvsp[-1].ival)); ;}
break;
- case 181:
-#line 702 "perly.y"
+ case 187:
+#line 729 "perly.y"
{ (yyval.opval) = sawparens((yyvsp[-1].opval)); ;}
break;
- case 182:
-#line 704 "perly.y"
+ case 188:
+#line 731 "perly.y"
{ (yyval.opval) = sawparens(newNULLLIST()); ;}
break;
- case 183:
-#line 706 "perly.y"
+ case 189:
+#line 733 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 184:
-#line 708 "perly.y"
+ case 190:
+#line 735 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 185:
-#line 710 "perly.y"
+ case 191:
+#line 737 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 186:
-#line 715 "perly.y"
+ case 192:
+#line 742 "perly.y"
{ (yyval.opval) = Nullop; ;}
break;
- case 187:
-#line 717 "perly.y"
+ case 193:
+#line 744 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 188:
-#line 721 "perly.y"
+ case 194:
+#line 748 "perly.y"
{ (yyval.opval) = Nullop; ;}
break;
- case 189:
-#line 723 "perly.y"
+ case 195:
+#line 750 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
- case 190:
-#line 725 "perly.y"
+ case 196:
+#line 752 "perly.y"
{ (yyval.opval) = (yyvsp[-1].opval); ;}
break;
- case 191:
-#line 731 "perly.y"
+ case 197:
+#line 758 "perly.y"
{ PL_in_my = 0; (yyval.opval) = my((yyvsp[0].opval)); ;}
break;
- case 192:
-#line 735 "perly.y"
+ case 198:
+#line 762 "perly.y"
{ (yyval.opval) = newCVREF((yyvsp[-1].ival),(yyvsp[0].opval)); ;}
break;
- case 193:
-#line 739 "perly.y"
+ case 199:
+#line 766 "perly.y"
{ (yyval.opval) = newSVREF((yyvsp[0].opval)); ;}
break;
- case 194:
-#line 743 "perly.y"
+ case 200:
+#line 770 "perly.y"
{ (yyval.opval) = newAVREF((yyvsp[0].opval)); ;}
break;
- case 195:
-#line 747 "perly.y"
+ case 201:
+#line 774 "perly.y"
{ (yyval.opval) = newHVREF((yyvsp[0].opval)); ;}
break;
- case 196:
-#line 751 "perly.y"
+ case 202:
+#line 778 "perly.y"
{ (yyval.opval) = newAVREF((yyvsp[0].opval)); ;}
break;
- case 197:
-#line 755 "perly.y"
+ case 203:
+#line 782 "perly.y"
{ (yyval.opval) = newGVREF(0,(yyvsp[0].opval)); ;}
break;
- case 198:
-#line 760 "perly.y"
+ case 204:
+#line 787 "perly.y"
{ (yyval.opval) = scalar((yyvsp[0].opval)); ;}
break;
- case 199:
-#line 762 "perly.y"
+ case 205:
+#line 789 "perly.y"
{ (yyval.opval) = scalar((yyvsp[0].opval)); ;}
break;
- case 200:
-#line 764 "perly.y"
+ case 206:
+#line 791 "perly.y"
{ (yyval.opval) = scope((yyvsp[0].opval)); ;}
break;
- case 201:
-#line 767 "perly.y"
+ case 207:
+#line 794 "perly.y"
{ (yyval.opval) = (yyvsp[0].opval); ;}
break;
diff --git a/perly.h b/perly.h
index cbcebc5a99..7c6ec9979b 100644
--- a/perly.h
+++ b/perly.h
@@ -53,47 +53,50 @@
ELSIF = 278,
CONTINUE = 279,
FOR = 280,
- LOOPEX = 281,
- DOTDOT = 282,
- FUNC0 = 283,
- FUNC1 = 284,
- FUNC = 285,
- UNIOP = 286,
- LSTOP = 287,
- RELOP = 288,
- EQOP = 289,
- MULOP = 290,
- ADDOP = 291,
- DOLSHARP = 292,
- DO = 293,
- HASHBRACK = 294,
- NOAMP = 295,
- LOCAL = 296,
- MY = 297,
- MYSUB = 298,
- REQUIRE = 299,
- COLONATTR = 300,
- PREC_LOW = 301,
- DOROP = 302,
- OROP = 303,
- ANDOP = 304,
- NOTOP = 305,
- ASSIGNOP = 306,
- DORDOR = 307,
- OROR = 308,
- ANDAND = 309,
- BITOROP = 310,
- BITANDOP = 311,
- SHIFTOP = 312,
- MATCHOP = 313,
- REFGEN = 314,
- UMINUS = 315,
- POWOP = 316,
- POSTDEC = 317,
- POSTINC = 318,
- PREDEC = 319,
- PREINC = 320,
- ARROW = 321
+ GIVEN = 281,
+ WHEN = 282,
+ DEFAULT = 283,
+ LOOPEX = 284,
+ DOTDOT = 285,
+ FUNC0 = 286,
+ FUNC1 = 287,
+ FUNC = 288,
+ UNIOP = 289,
+ LSTOP = 290,
+ RELOP = 291,
+ EQOP = 292,
+ MULOP = 293,
+ ADDOP = 294,
+ DOLSHARP = 295,
+ DO = 296,
+ HASHBRACK = 297,
+ NOAMP = 298,
+ LOCAL = 299,
+ MY = 300,
+ MYSUB = 301,
+ REQUIRE = 302,
+ COLONATTR = 303,
+ PREC_LOW = 304,
+ DOROP = 305,
+ OROP = 306,
+ ANDOP = 307,
+ NOTOP = 308,
+ ASSIGNOP = 309,
+ DORDOR = 310,
+ OROR = 311,
+ ANDAND = 312,
+ BITOROP = 313,
+ BITANDOP = 314,
+ SHIFTOP = 315,
+ MATCHOP = 316,
+ REFGEN = 317,
+ UMINUS = 318,
+ POWOP = 319,
+ POSTDEC = 320,
+ POSTINC = 321,
+ PREDEC = 322,
+ PREINC = 323,
+ ARROW = 324
};
#endif
/* Tokens. */
@@ -120,47 +123,50 @@
#define ELSIF 278
#define CONTINUE 279
#define FOR 280
-#define LOOPEX 281
-#define DOTDOT 282
-#define FUNC0 283
-#define FUNC1 284
-#define FUNC 285
-#define UNIOP 286
-#define LSTOP 287
-#define RELOP 288
-#define EQOP 289
-#define MULOP 290
-#define ADDOP 291
-#define DOLSHARP 292
-#define DO 293
-#define HASHBRACK 294
-#define NOAMP 295
-#define LOCAL 296
-#define MY 297
-#define MYSUB 298
-#define REQUIRE 299
-#define COLONATTR 300
-#define PREC_LOW 301
-#define DOROP 302
-#define OROP 303
-#define ANDOP 304
-#define NOTOP 305
-#define ASSIGNOP 306
-#define DORDOR 307
-#define OROR 308
-#define ANDAND 309
-#define BITOROP 310
-#define BITANDOP 311
-#define SHIFTOP 312
-#define MATCHOP 313
-#define REFGEN 314
-#define UMINUS 315
-#define POWOP 316
-#define POSTDEC 317
-#define POSTINC 318
-#define PREDEC 319
-#define PREINC 320
-#define ARROW 321
+#define GIVEN 281
+#define WHEN 282
+#define DEFAULT 283
+#define LOOPEX 284
+#define DOTDOT 285
+#define FUNC0 286
+#define FUNC1 287
+#define FUNC 288
+#define UNIOP 289
+#define LSTOP 290
+#define RELOP 291
+#define EQOP 292
+#define MULOP 293
+#define ADDOP 294
+#define DOLSHARP 295
+#define DO 296
+#define HASHBRACK 297
+#define NOAMP 298
+#define LOCAL 299
+#define MY 300
+#define MYSUB 301
+#define REQUIRE 302
+#define COLONATTR 303
+#define PREC_LOW 304
+#define DOROP 305
+#define OROP 306
+#define ANDOP 307
+#define NOTOP 308
+#define ASSIGNOP 309
+#define DORDOR 310
+#define OROR 311
+#define ANDAND 312
+#define BITOROP 313
+#define BITANDOP 314
+#define SHIFTOP 315
+#define MATCHOP 316
+#define REFGEN 317
+#define UMINUS 318
+#define POWOP 319
+#define POSTDEC 320
+#define POSTINC 321
+#define PREDEC 322
+#define PREINC 323
+#define ARROW 324
@@ -175,7 +181,7 @@ typedef union YYSTYPE {
GV *gvval;
} YYSTYPE;
/* Line 1447 of yacc.c. */
-#line 177 "perly.h"
+#line 183 "perly.h"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
diff --git a/perly.tab b/perly.tab
index 48ac1b308e..aab8ed059b 100644
--- a/perly.tab
+++ b/perly.tab
@@ -1,19 +1,19 @@
#define YYFINAL 3
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 1993
+#define YYLAST 2047
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 86
+#define YYNTOKENS 89
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 62
+#define YYNNTS 65
/* YYNRULES -- Number of rules. */
-#define YYNRULES 201
+#define YYNRULES 207
/* YYNRULES -- Number of states. */
-#define YYNSTATES 401
+#define YYNSTATES 418
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 321
+#define YYMAXUTOK 324
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -24,16 +24,16 @@ static const unsigned char 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, 64, 2, 2, 82, 84, 47, 2,
- 75, 74, 85, 81, 53, 80, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 56, 78,
- 2, 2, 2, 55, 83, 2, 2, 2, 2, 2,
+ 2, 2, 2, 67, 2, 2, 85, 87, 50, 2,
+ 78, 77, 88, 84, 56, 83, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 59, 81,
+ 2, 2, 2, 58, 86, 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, 76, 2, 79, 2, 2, 2, 2, 2, 2,
+ 2, 79, 2, 82, 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, 3, 2, 77, 65, 2, 2, 2,
+ 2, 2, 2, 3, 2, 80, 68, 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,
@@ -51,9 +51,9 @@ static const unsigned char yytranslate[] =
16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
- 46, 48, 49, 50, 51, 52, 54, 57, 58, 59,
- 60, 61, 62, 63, 66, 67, 68, 69, 70, 71,
- 72, 73
+ 46, 47, 48, 49, 51, 52, 53, 54, 55, 57,
+ 60, 61, 62, 63, 64, 65, 66, 69, 70, 71,
+ 72, 73, 74, 75, 76
};
#if YYDEBUG
@@ -61,129 +61,131 @@ static const unsigned char yytranslate[] =
YYRHS. */
static const unsigned short int yyprhs[] =
{
- 0, 0, 3, 6, 11, 12, 13, 18, 19, 20,
- 21, 24, 28, 31, 33, 36, 40, 42, 44, 48,
- 52, 56, 60, 64, 65, 68, 75, 83, 91, 92,
- 95, 105, 115, 126, 136, 145, 158, 162, 163, 164,
- 166, 167, 169, 171, 173, 175, 177, 178, 180, 182,
- 184, 186, 188, 190, 195, 197, 198, 205, 212, 213,
- 214, 215, 217, 218, 220, 221, 224, 226, 229, 231,
- 233, 235, 239, 240, 248, 252, 256, 260, 262, 265,
- 269, 271, 275, 281, 288, 292, 296, 302, 305, 310,
- 311, 317, 319, 321, 327, 332, 338, 343, 349, 356,
- 362, 367, 373, 378, 382, 389, 395, 399, 403, 407,
- 411, 415, 419, 423, 427, 431, 435, 439, 443, 447,
- 451, 454, 457, 460, 463, 466, 469, 472, 475, 479,
- 482, 487, 491, 497, 500, 503, 508, 514, 519, 525,
- 527, 529, 531, 533, 539, 542, 544, 547, 551, 554,
- 556, 558, 560, 562, 564, 566, 571, 577, 579, 581,
- 585, 590, 594, 596, 599, 602, 604, 607, 610, 612,
- 615, 618, 620, 624, 626, 630, 635, 640, 642, 644,
- 648, 651, 655, 658, 660, 662, 664, 665, 667, 668,
- 670, 673, 675, 678, 681, 684, 687, 690, 693, 695,
- 697, 699
+ 0, 0, 3, 6, 11, 12, 13, 14, 19, 20,
+ 21, 22, 25, 29, 32, 34, 36, 39, 42, 46,
+ 48, 50, 54, 58, 62, 66, 70, 71, 74, 81,
+ 89, 97, 104, 107, 108, 111, 121, 131, 142, 152,
+ 161, 174, 178, 187, 188, 189, 191, 192, 194, 196,
+ 198, 200, 202, 203, 205, 207, 209, 211, 213, 215,
+ 220, 222, 223, 230, 237, 238, 239, 240, 242, 243,
+ 245, 246, 249, 251, 254, 256, 258, 260, 264, 265,
+ 273, 277, 281, 285, 287, 290, 294, 296, 300, 306,
+ 313, 317, 321, 327, 330, 335, 336, 342, 344, 346,
+ 352, 357, 363, 368, 374, 381, 387, 392, 398, 403,
+ 407, 414, 420, 424, 428, 432, 436, 440, 444, 448,
+ 452, 456, 460, 464, 468, 472, 476, 479, 482, 485,
+ 488, 491, 494, 497, 500, 504, 507, 512, 516, 522,
+ 525, 528, 533, 539, 544, 550, 552, 554, 556, 558,
+ 564, 567, 569, 572, 576, 579, 581, 583, 585, 587,
+ 589, 591, 596, 602, 604, 606, 610, 615, 619, 621,
+ 624, 627, 629, 632, 635, 637, 640, 643, 645, 649,
+ 651, 655, 660, 665, 667, 669, 673, 676, 680, 683,
+ 685, 687, 689, 690, 692, 693, 695, 698, 700, 703,
+ 706, 709, 712, 715, 718, 720, 722, 724
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const short int yyrhs[] =
{
- 87, 0, -1, 90, 94, -1, 3, 89, 94, 77,
- -1, -1, -1, 3, 92, 94, 77, -1, -1, -1,
- -1, 94, 109, -1, 94, 93, 95, -1, 108, 98,
- -1, 100, -1, 108, 78, -1, 108, 96, 78, -1,
- 1, -1, 125, -1, 125, 21, 125, -1, 125, 22,
- 125, -1, 125, 19, 125, -1, 125, 20, 104, -1,
- 125, 26, 125, -1, -1, 23, 91, -1, 24, 75,
- 105, 74, 91, 97, -1, 21, 75, 89, 105, 74,
- 91, 97, -1, 22, 75, 89, 107, 74, 91, 97,
- -1, -1, 25, 88, -1, 108, 19, 75, 89, 103,
- 74, 101, 91, 99, -1, 108, 20, 75, 89, 104,
- 74, 101, 91, 99, -1, 108, 26, 43, 89, 140,
- 75, 105, 74, 91, 99, -1, 108, 26, 142, 75,
- 89, 105, 74, 91, 99, -1, 108, 26, 75, 89,
- 105, 74, 91, 99, -1, 108, 26, 75, 89, 106,
- 78, 103, 78, 101, 106, 74, 91, -1, 108, 88,
- 99, -1, -1, -1, 96, -1, -1, 125, -1, 125,
- -1, 125, -1, 102, -1, 104, -1, -1, 13, -1,
- 110, -1, 113, -1, 112, -1, 122, -1, 123, -1,
- 14, 116, 111, 88, -1, 4, -1, -1, 44, 114,
- 117, 118, 119, 121, -1, 15, 114, 117, 118, 119,
- 121, -1, -1, -1, -1, 4, -1, -1, 7, -1,
- -1, 46, 7, -1, 46, -1, 46, 7, -1, 46,
- -1, 88, -1, 78, -1, 17, 4, 78, -1, -1,
- 18, 114, 124, 4, 4, 138, 78, -1, 125, 51,
- 125, -1, 125, 50, 125, -1, 125, 49, 125, -1,
- 126, -1, 126, 53, -1, 126, 53, 135, -1, 135,
- -1, 33, 147, 126, -1, 31, 75, 147, 125, 74,
- -1, 135, 73, 129, 75, 139, 74, -1, 135, 73,
- 129, -1, 5, 147, 138, -1, 6, 147, 75, 139,
- 74, -1, 33, 138, -1, 31, 75, 139, 74, -1,
- -1, 12, 115, 88, 128, 138, -1, 5, -1, 142,
- -1, 146, 3, 125, 78, 77, -1, 142, 76, 125,
- 79, -1, 135, 73, 76, 125, 79, -1, 130, 76,
- 125, 79, -1, 142, 3, 125, 78, 77, -1, 135,
- 73, 3, 125, 78, 77, -1, 130, 3, 125, 78,
- 77, -1, 135, 73, 75, 74, -1, 135, 73, 75,
- 125, 74, -1, 130, 75, 125, 74, -1, 130, 75,
- 74, -1, 75, 125, 74, 76, 125, 79, -1, 75,
- 74, 76, 125, 79, -1, 135, 54, 135, -1, 135,
- 68, 135, -1, 135, 36, 135, -1, 135, 37, 135,
- -1, 135, 62, 135, -1, 135, 34, 135, -1, 135,
- 35, 135, -1, 135, 61, 135, -1, 135, 60, 135,
- -1, 135, 28, 135, -1, 135, 59, 135, -1, 135,
- 58, 135, -1, 135, 57, 135, -1, 135, 63, 135,
- -1, 80, 135, -1, 81, 135, -1, 64, 135, -1,
- 65, 135, -1, 135, 70, -1, 135, 69, -1, 72,
- 135, -1, 71, 135, -1, 76, 125, 79, -1, 76,
- 79, -1, 40, 125, 78, 77, -1, 40, 78, 77,
- -1, 16, 115, 118, 119, 88, -1, 39, 135, -1,
- 39, 88, -1, 39, 4, 75, 74, -1, 39, 4,
- 75, 125, 74, -1, 39, 142, 75, 74, -1, 39,
- 142, 75, 125, 74, -1, 131, -1, 132, -1, 133,
- -1, 134, -1, 135, 55, 135, 56, 135, -1, 66,
- 135, -1, 136, -1, 42, 135, -1, 75, 125, 74,
- -1, 75, 74, -1, 142, -1, 146, -1, 144, -1,
- 143, -1, 145, -1, 130, -1, 143, 76, 125, 79,
- -1, 143, 3, 125, 78, 77, -1, 7, -1, 141,
- -1, 141, 75, 74, -1, 141, 75, 125, 74, -1,
- 41, 4, 138, -1, 27, -1, 27, 135, -1, 52,
- 126, -1, 32, -1, 32, 88, -1, 32, 135, -1,
- 45, -1, 45, 135, -1, 11, 135, -1, 29, -1,
- 29, 75, 74, -1, 10, -1, 30, 75, 74, -1,
- 30, 75, 125, 74, -1, 8, 75, 126, 74, -1,
- 4, -1, 127, -1, 43, 137, 120, -1, 43, 137,
- -1, 75, 125, 74, -1, 75, 74, -1, 142, -1,
- 144, -1, 143, -1, -1, 126, -1, -1, 125, -1,
- 125, 53, -1, 142, -1, 47, 147, -1, 82, 147,
- -1, 83, 147, -1, 84, 147, -1, 38, 147, -1,
- 85, 147, -1, 4, -1, 142, -1, 88, -1, 9,
- -1
+ 90, 0, -1, 94, 98, -1, 3, 92, 98, 80,
+ -1, -1, -1, -1, 3, 96, 98, 80, -1, -1,
+ -1, -1, 98, 115, -1, 98, 97, 99, -1, 114,
+ 102, -1, 105, -1, 106, -1, 114, 103, -1, 114,
+ 81, -1, 114, 100, 81, -1, 1, -1, 131, -1,
+ 131, 21, 131, -1, 131, 22, 131, -1, 131, 19,
+ 131, -1, 131, 20, 110, -1, 131, 26, 131, -1,
+ -1, 23, 95, -1, 24, 78, 111, 77, 95, 101,
+ -1, 21, 78, 92, 111, 77, 95, 101, -1, 22,
+ 78, 92, 113, 77, 95, 101, -1, 28, 78, 92,
+ 111, 77, 95, -1, 29, 91, -1, -1, 25, 91,
+ -1, 114, 19, 78, 92, 109, 77, 107, 95, 104,
+ -1, 114, 20, 78, 92, 110, 77, 107, 95, 104,
+ -1, 114, 26, 46, 92, 146, 78, 111, 77, 95,
+ 104, -1, 114, 26, 148, 78, 92, 111, 77, 95,
+ 104, -1, 114, 26, 78, 92, 111, 77, 95, 104,
+ -1, 114, 26, 78, 92, 112, 81, 109, 81, 107,
+ 112, 77, 95, -1, 114, 91, 104, -1, 114, 27,
+ 78, 92, 93, 111, 77, 95, -1, -1, -1, 100,
+ -1, -1, 131, -1, 131, -1, 131, -1, 108, -1,
+ 110, -1, -1, 13, -1, 116, -1, 119, -1, 118,
+ -1, 128, -1, 129, -1, 14, 122, 117, 91, -1,
+ 4, -1, -1, 47, 120, 123, 124, 125, 127, -1,
+ 15, 120, 123, 124, 125, 127, -1, -1, -1, -1,
+ 4, -1, -1, 7, -1, -1, 49, 7, -1, 49,
+ -1, 49, 7, -1, 49, -1, 91, -1, 81, -1,
+ 17, 4, 81, -1, -1, 18, 120, 130, 4, 4,
+ 144, 81, -1, 131, 54, 131, -1, 131, 53, 131,
+ -1, 131, 52, 131, -1, 132, -1, 132, 56, -1,
+ 132, 56, 141, -1, 141, -1, 36, 153, 132, -1,
+ 34, 78, 153, 131, 77, -1, 141, 76, 135, 78,
+ 145, 77, -1, 141, 76, 135, -1, 5, 153, 144,
+ -1, 6, 153, 78, 145, 77, -1, 36, 144, -1,
+ 34, 78, 145, 77, -1, -1, 12, 121, 91, 134,
+ 144, -1, 5, -1, 148, -1, 152, 3, 131, 81,
+ 80, -1, 148, 79, 131, 82, -1, 141, 76, 79,
+ 131, 82, -1, 136, 79, 131, 82, -1, 148, 3,
+ 131, 81, 80, -1, 141, 76, 3, 131, 81, 80,
+ -1, 136, 3, 131, 81, 80, -1, 141, 76, 78,
+ 77, -1, 141, 76, 78, 131, 77, -1, 136, 78,
+ 131, 77, -1, 136, 78, 77, -1, 78, 131, 77,
+ 79, 131, 82, -1, 78, 77, 79, 131, 82, -1,
+ 141, 57, 141, -1, 141, 71, 141, -1, 141, 39,
+ 141, -1, 141, 40, 141, -1, 141, 65, 141, -1,
+ 141, 37, 141, -1, 141, 38, 141, -1, 141, 64,
+ 141, -1, 141, 63, 141, -1, 141, 31, 141, -1,
+ 141, 62, 141, -1, 141, 61, 141, -1, 141, 60,
+ 141, -1, 141, 66, 141, -1, 83, 141, -1, 84,
+ 141, -1, 67, 141, -1, 68, 141, -1, 141, 73,
+ -1, 141, 72, -1, 75, 141, -1, 74, 141, -1,
+ 79, 131, 82, -1, 79, 82, -1, 43, 131, 81,
+ 80, -1, 43, 81, 80, -1, 16, 121, 124, 125,
+ 91, -1, 42, 141, -1, 42, 91, -1, 42, 4,
+ 78, 77, -1, 42, 4, 78, 131, 77, -1, 42,
+ 148, 78, 77, -1, 42, 148, 78, 131, 77, -1,
+ 137, -1, 138, -1, 139, -1, 140, -1, 141, 58,
+ 141, 59, 141, -1, 69, 141, -1, 142, -1, 45,
+ 141, -1, 78, 131, 77, -1, 78, 77, -1, 148,
+ -1, 152, -1, 150, -1, 149, -1, 151, -1, 136,
+ -1, 149, 79, 131, 82, -1, 149, 3, 131, 81,
+ 80, -1, 7, -1, 147, -1, 147, 78, 77, -1,
+ 147, 78, 131, 77, -1, 44, 4, 144, -1, 30,
+ -1, 30, 141, -1, 55, 132, -1, 35, -1, 35,
+ 91, -1, 35, 141, -1, 48, -1, 48, 141, -1,
+ 11, 141, -1, 32, -1, 32, 78, 77, -1, 10,
+ -1, 33, 78, 77, -1, 33, 78, 131, 77, -1,
+ 8, 78, 132, 77, -1, 4, -1, 133, -1, 46,
+ 143, 126, -1, 46, 143, -1, 78, 131, 77, -1,
+ 78, 77, -1, 148, -1, 150, -1, 149, -1, -1,
+ 132, -1, -1, 131, -1, 131, 56, -1, 148, -1,
+ 50, 153, -1, 85, 153, -1, 86, 153, -1, 87,
+ 153, -1, 41, 153, -1, 88, 153, -1, 4, -1,
+ 148, -1, 91, -1, 9, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const unsigned short int yyrline[] =
{
- 0, 96, 96, 102, 109, 113, 119, 126, 130, 134,
- 135, 137, 146, 148, 149, 158, 164, 166, 168, 170,
- 172, 174, 176, 183, 184, 186, 193, 197, 205, 206,
- 211, 217, 223, 226, 230, 233, 250, 258, 264, 265,
- 270, 271, 275, 280, 284, 288, 294, 295, 299, 301,
- 303, 305, 307, 311, 315, 316, 320, 325, 330, 334,
- 338, 342, 351, 352, 357, 358, 360, 365, 367, 372,
- 373, 376, 381, 380, 387, 389, 391, 393, 397, 399,
- 401, 405, 408, 411, 416, 420, 425, 430, 432, 435,
- 434, 443, 444, 448, 453, 455, 459, 463, 466, 471,
- 476, 479, 484, 488, 491, 493, 498, 500, 502, 506,
- 508, 510, 512, 514, 516, 518, 520, 522, 524, 526,
- 531, 533, 535, 537, 539, 542, 545, 548, 555, 557,
- 559, 561, 563, 569, 571, 573, 581, 590, 594, 602,
- 603, 604, 605, 606, 608, 610, 612, 614, 616, 618,
- 620, 622, 624, 626, 628, 630, 636, 643, 645, 647,
- 649, 652, 655, 658, 660, 662, 664, 666, 668, 670,
- 672, 675, 677, 679, 682, 685, 687, 689, 690, 694,
- 696, 701, 703, 705, 707, 709, 714, 716, 721, 722,
- 724, 730, 734, 738, 742, 746, 750, 754, 759, 761,
- 763, 766
+ 0, 98, 98, 104, 111, 115, 119, 125, 132, 136,
+ 140, 141, 143, 152, 154, 155, 157, 159, 168, 174,
+ 176, 178, 180, 182, 184, 186, 193, 194, 196, 203,
+ 207, 214, 217, 223, 224, 229, 235, 241, 244, 248,
+ 251, 268, 275, 285, 291, 292, 297, 298, 302, 307,
+ 311, 315, 321, 322, 326, 328, 330, 332, 334, 338,
+ 342, 343, 347, 352, 357, 361, 365, 369, 378, 379,
+ 384, 385, 387, 392, 394, 399, 400, 403, 408, 407,
+ 414, 416, 418, 420, 424, 426, 428, 432, 435, 438,
+ 443, 447, 452, 457, 459, 462, 461, 470, 471, 475,
+ 480, 482, 486, 490, 493, 498, 503, 506, 511, 515,
+ 518, 520, 525, 527, 529, 533, 535, 537, 539, 541,
+ 543, 545, 547, 549, 551, 553, 558, 560, 562, 564,
+ 566, 569, 572, 575, 582, 584, 586, 588, 590, 596,
+ 598, 600, 608, 617, 621, 629, 630, 631, 632, 633,
+ 635, 637, 639, 641, 643, 645, 647, 649, 651, 653,
+ 655, 657, 663, 670, 672, 674, 676, 679, 682, 685,
+ 687, 689, 691, 693, 695, 697, 699, 702, 704, 706,
+ 709, 712, 714, 716, 717, 721, 723, 728, 730, 732,
+ 734, 736, 741, 743, 748, 749, 751, 757, 761, 765,
+ 769, 773, 777, 781, 786, 788, 790, 793
};
#endif
@@ -195,24 +197,25 @@ static const char *const yytname[] =
"$end", "error", "$undefined", "'{'", "WORD", "METHOD", "FUNCMETH",
"THING", "PMFUNC", "PRIVATEREF", "FUNC0SUB", "UNIOPSUB", "LSTOPSUB",
"LABEL", "FORMAT", "SUB", "ANONSUB", "PACKAGE", "USE", "WHILE", "UNTIL",
- "IF", "UNLESS", "ELSE", "ELSIF", "CONTINUE", "FOR", "LOOPEX", "DOTDOT",
- "FUNC0", "FUNC1", "FUNC", "UNIOP", "LSTOP", "RELOP", "EQOP", "MULOP",
- "ADDOP", "DOLSHARP", "DO", "HASHBRACK", "NOAMP", "LOCAL", "MY", "MYSUB",
- "REQUIRE", "COLONATTR", "'&'", "PREC_LOW", "DOROP", "OROP", "ANDOP",
- "NOTOP", "','", "ASSIGNOP", "'?'", "':'", "DORDOR", "OROR", "ANDAND",
- "BITOROP", "BITANDOP", "SHIFTOP", "MATCHOP", "'!'", "'~'", "REFGEN",
- "UMINUS", "POWOP", "POSTDEC", "POSTINC", "PREDEC", "PREINC", "ARROW",
- "')'", "'('", "'['", "'}'", "';'", "']'", "'-'", "'+'", "'$'", "'@'",
- "'%'", "'*'", "$accept", "prog", "block", "remember", "progstart",
- "mblock", "mremember", "savescope", "lineseq", "line", "sideff", "else",
- "cond", "cont", "loop", "mintro", "nexpr", "texpr", "iexpr", "mexpr",
- "mnexpr", "miexpr", "label", "decl", "format", "formname", "mysubrout",
- "subrout", "startsub", "startanonsub", "startformsub", "subname",
- "proto", "subattrlist", "myattrlist", "subbody", "package", "use", "@1",
- "expr", "argexpr", "listop", "@2", "method", "subscripted", "termbinop",
- "termunop", "anonymous", "termdo", "term", "myattrterm", "myterm",
- "listexpr", "listexprcom", "my_scalar", "amper", "scalar", "ary", "hsh",
- "arylen", "star", "indirob", 0
+ "IF", "UNLESS", "ELSE", "ELSIF", "CONTINUE", "FOR", "GIVEN", "WHEN",
+ "DEFAULT", "LOOPEX", "DOTDOT", "FUNC0", "FUNC1", "FUNC", "UNIOP",
+ "LSTOP", "RELOP", "EQOP", "MULOP", "ADDOP", "DOLSHARP", "DO",
+ "HASHBRACK", "NOAMP", "LOCAL", "MY", "MYSUB", "REQUIRE", "COLONATTR",
+ "'&'", "PREC_LOW", "DOROP", "OROP", "ANDOP", "NOTOP", "','", "ASSIGNOP",
+ "'?'", "':'", "DORDOR", "OROR", "ANDAND", "BITOROP", "BITANDOP",
+ "SHIFTOP", "MATCHOP", "'!'", "'~'", "REFGEN", "UMINUS", "POWOP",
+ "POSTDEC", "POSTINC", "PREDEC", "PREINC", "ARROW", "')'", "'('", "'['",
+ "'}'", "';'", "']'", "'-'", "'+'", "'$'", "'@'", "'%'", "'*'", "$accept",
+ "prog", "block", "remember", "mydefsv", "progstart", "mblock",
+ "mremember", "savescope", "lineseq", "line", "sideff", "else", "cond",
+ "case", "cont", "loop", "switch", "mintro", "nexpr", "texpr", "iexpr",
+ "mexpr", "mnexpr", "miexpr", "label", "decl", "format", "formname",
+ "mysubrout", "subrout", "startsub", "startanonsub", "startformsub",
+ "subname", "proto", "subattrlist", "myattrlist", "subbody", "package",
+ "use", "@1", "expr", "argexpr", "listop", "@2", "method", "subscripted",
+ "termbinop", "termunop", "anonymous", "termdo", "term", "myattrterm",
+ "myterm", "listexpr", "listexprcom", "my_scalar", "amper", "scalar",
+ "ary", "hsh", "arylen", "star", "indirob", 0
};
#endif
@@ -225,64 +228,64 @@ static const unsigned short int yytoknum[] =
264, 265, 266, 267, 268, 269, 270, 271, 272, 273,
274, 275, 276, 277, 278, 279, 280, 281, 282, 283,
284, 285, 286, 287, 288, 289, 290, 291, 292, 293,
- 294, 295, 296, 297, 298, 299, 300, 38, 301, 302,
- 303, 304, 305, 44, 306, 63, 58, 307, 308, 309,
- 310, 311, 312, 313, 33, 126, 314, 315, 316, 317,
- 318, 319, 320, 321, 41, 40, 91, 125, 59, 93,
- 45, 43, 36, 64, 37, 42
+ 294, 295, 296, 297, 298, 299, 300, 301, 302, 303,
+ 38, 304, 305, 306, 307, 308, 44, 309, 63, 58,
+ 310, 311, 312, 313, 314, 315, 316, 33, 126, 317,
+ 318, 319, 320, 321, 322, 323, 324, 41, 40, 91,
+ 125, 59, 93, 45, 43, 36, 64, 37, 42
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const unsigned char yyr1[] =
{
- 0, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- 94, 94, 95, 95, 95, 95, 96, 96, 96, 96,
- 96, 96, 96, 97, 97, 97, 98, 98, 99, 99,
- 100, 100, 100, 100, 100, 100, 100, 101, 102, 102,
- 103, 103, 104, 105, 106, 107, 108, 108, 109, 109,
- 109, 109, 109, 110, 111, 111, 112, 113, 114, 115,
- 116, 117, 118, 118, 119, 119, 119, 120, 120, 121,
- 121, 122, 124, 123, 125, 125, 125, 125, 126, 126,
- 126, 127, 127, 127, 127, 127, 127, 127, 127, 128,
- 127, 129, 129, 130, 130, 130, 130, 130, 130, 130,
- 130, 130, 130, 130, 130, 130, 131, 131, 131, 131,
- 131, 131, 131, 131, 131, 131, 131, 131, 131, 131,
- 132, 132, 132, 132, 132, 132, 132, 132, 133, 133,
- 133, 133, 133, 134, 134, 134, 134, 134, 134, 135,
- 135, 135, 135, 135, 135, 135, 135, 135, 135, 135,
- 135, 135, 135, 135, 135, 135, 135, 135, 135, 135,
- 135, 135, 135, 135, 135, 135, 135, 135, 135, 135,
- 135, 135, 135, 135, 135, 135, 135, 135, 135, 136,
- 136, 137, 137, 137, 137, 137, 138, 138, 139, 139,
- 139, 140, 141, 142, 143, 144, 145, 146, 147, 147,
- 147, 147
+ 0, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ 98, 98, 98, 99, 99, 99, 99, 99, 99, 100,
+ 100, 100, 100, 100, 100, 100, 101, 101, 101, 102,
+ 102, 103, 103, 104, 104, 105, 105, 105, 105, 105,
+ 105, 105, 106, 107, 108, 108, 109, 109, 110, 111,
+ 112, 113, 114, 114, 115, 115, 115, 115, 115, 116,
+ 117, 117, 118, 119, 120, 121, 122, 123, 124, 124,
+ 125, 125, 125, 126, 126, 127, 127, 128, 130, 129,
+ 131, 131, 131, 131, 132, 132, 132, 133, 133, 133,
+ 133, 133, 133, 133, 133, 134, 133, 135, 135, 136,
+ 136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
+ 136, 136, 137, 137, 137, 137, 137, 137, 137, 137,
+ 137, 137, 137, 137, 137, 137, 138, 138, 138, 138,
+ 138, 138, 138, 138, 139, 139, 139, 139, 139, 140,
+ 140, 140, 140, 140, 140, 141, 141, 141, 141, 141,
+ 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
+ 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
+ 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
+ 141, 141, 141, 141, 141, 142, 142, 143, 143, 143,
+ 143, 143, 144, 144, 145, 145, 145, 146, 147, 148,
+ 149, 150, 151, 152, 153, 153, 153, 153
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
static const unsigned char yyr2[] =
{
- 0, 2, 2, 4, 0, 0, 4, 0, 0, 0,
- 2, 3, 2, 1, 2, 3, 1, 1, 3, 3,
- 3, 3, 3, 0, 2, 6, 7, 7, 0, 2,
- 9, 9, 10, 9, 8, 12, 3, 0, 0, 1,
- 0, 1, 1, 1, 1, 1, 0, 1, 1, 1,
- 1, 1, 1, 4, 1, 0, 6, 6, 0, 0,
- 0, 1, 0, 1, 0, 2, 1, 2, 1, 1,
- 1, 3, 0, 7, 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, 5, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 2, 2, 2, 2, 2, 2, 2, 2, 3, 2,
- 4, 3, 5, 2, 2, 4, 5, 4, 5, 1,
- 1, 1, 1, 5, 2, 1, 2, 3, 2, 1,
- 1, 1, 1, 1, 1, 4, 5, 1, 1, 3,
- 4, 3, 1, 2, 2, 1, 2, 2, 1, 2,
- 2, 1, 3, 1, 3, 4, 4, 1, 1, 3,
- 2, 3, 2, 1, 1, 1, 0, 1, 0, 1,
- 2, 1, 2, 2, 2, 2, 2, 2, 1, 1,
- 1, 1
+ 0, 2, 2, 4, 0, 0, 0, 4, 0, 0,
+ 0, 2, 3, 2, 1, 1, 2, 2, 3, 1,
+ 1, 3, 3, 3, 3, 3, 0, 2, 6, 7,
+ 7, 6, 2, 0, 2, 9, 9, 10, 9, 8,
+ 12, 3, 8, 0, 0, 1, 0, 1, 1, 1,
+ 1, 1, 0, 1, 1, 1, 1, 1, 1, 4,
+ 1, 0, 6, 6, 0, 0, 0, 1, 0, 1,
+ 0, 2, 1, 2, 1, 1, 1, 3, 0, 7,
+ 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, 5, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 2, 2, 2, 2,
+ 2, 2, 2, 2, 3, 2, 4, 3, 5, 2,
+ 2, 4, 5, 4, 5, 1, 1, 1, 1, 5,
+ 2, 1, 2, 3, 2, 1, 1, 1, 1, 1,
+ 1, 4, 5, 1, 1, 3, 4, 3, 1, 2,
+ 2, 1, 2, 2, 1, 2, 2, 1, 3, 1,
+ 3, 4, 4, 1, 1, 3, 2, 3, 2, 1,
+ 1, 1, 0, 1, 0, 1, 2, 1, 2, 2,
+ 2, 2, 2, 2, 1, 1, 1, 1
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -290,577 +293,590 @@ static const unsigned char yyr2[] =
means the default is an error. */
static const unsigned char yydefact[] =
{
- 5, 0, 9, 1, 8, 60, 58, 0, 58, 58,
- 46, 10, 48, 50, 49, 51, 52, 55, 0, 0,
- 72, 0, 47, 11, 13, 0, 54, 0, 61, 62,
- 71, 0, 62, 16, 4, 177, 0, 0, 157, 0,
- 173, 0, 59, 59, 0, 0, 0, 0, 0, 162,
- 171, 0, 0, 165, 186, 0, 0, 0, 0, 0,
- 0, 168, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 14, 0, 0, 0, 0, 0, 0, 28, 0,
- 12, 17, 77, 178, 154, 139, 140, 141, 142, 80,
- 145, 158, 149, 152, 151, 153, 150, 53, 63, 64,
- 0, 64, 9, 198, 201, 200, 199, 186, 0, 0,
- 170, 0, 62, 4, 4, 4, 4, 4, 4, 0,
- 163, 0, 0, 188, 166, 167, 198, 187, 87, 199,
- 0, 196, 177, 134, 133, 149, 0, 0, 186, 146,
- 0, 180, 183, 185, 184, 169, 192, 164, 122, 123,
- 144, 127, 126, 148, 0, 129, 0, 120, 121, 193,
- 194, 195, 197, 0, 36, 15, 0, 0, 0, 0,
- 0, 0, 0, 0, 78, 0, 0, 0, 0, 0,
+ 6, 0, 10, 1, 9, 66, 64, 0, 64, 64,
+ 52, 11, 54, 56, 55, 57, 58, 61, 0, 0,
+ 78, 0, 53, 12, 14, 15, 0, 60, 0, 67,
+ 68, 77, 0, 68, 19, 4, 183, 0, 0, 163,
+ 0, 179, 0, 65, 65, 0, 0, 0, 0, 0,
+ 0, 0, 0, 168, 177, 0, 0, 171, 192, 0,
+ 0, 0, 0, 0, 0, 174, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 0, 0, 0, 0,
+ 0, 0, 33, 0, 13, 16, 20, 83, 184, 160,
+ 145, 146, 147, 148, 86, 151, 164, 155, 158, 157,
+ 159, 156, 59, 69, 70, 0, 70, 10, 204, 207,
+ 206, 205, 192, 0, 0, 176, 0, 68, 4, 4,
+ 4, 4, 4, 4, 0, 4, 4, 32, 169, 0,
+ 0, 194, 172, 173, 204, 193, 93, 205, 0, 202,
+ 183, 140, 139, 155, 0, 0, 192, 152, 0, 186,
+ 189, 191, 190, 175, 198, 170, 128, 129, 150, 133,
+ 132, 154, 0, 135, 0, 126, 127, 199, 200, 201,
+ 203, 0, 41, 18, 0, 0, 0, 0, 0, 0,
+ 0, 0, 84, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 125, 124, 0, 0, 0, 0, 0,
- 0, 0, 66, 0, 186, 0, 8, 85, 188, 0,
- 89, 64, 40, 0, 0, 0, 0, 0, 4, 172,
- 174, 0, 189, 0, 0, 81, 0, 0, 131, 0,
- 161, 182, 0, 68, 179, 0, 147, 128, 29, 20,
- 21, 42, 18, 19, 22, 76, 75, 74, 79, 0,
- 103, 0, 0, 115, 111, 112, 108, 109, 106, 0,
- 118, 117, 116, 114, 113, 110, 119, 107, 0, 91,
- 0, 0, 84, 92, 159, 0, 0, 0, 0, 0,
- 0, 65, 70, 69, 57, 0, 56, 3, 0, 176,
- 186, 0, 0, 41, 0, 0, 43, 45, 0, 0,
- 191, 39, 44, 0, 0, 17, 0, 175, 190, 88,
- 0, 135, 0, 137, 0, 130, 181, 67, 0, 0,
- 0, 102, 96, 0, 0, 100, 0, 0, 188, 160,
- 0, 94, 0, 155, 0, 73, 86, 90, 132, 37,
- 37, 0, 0, 0, 0, 40, 0, 82, 136, 138,
- 105, 0, 99, 143, 0, 101, 95, 0, 97, 156,
- 93, 0, 0, 7, 23, 23, 0, 28, 0, 0,
- 104, 98, 83, 28, 28, 9, 0, 0, 26, 27,
- 0, 34, 37, 28, 30, 31, 8, 24, 0, 28,
- 0, 33, 6, 0, 32, 0, 0, 0, 23, 35,
- 25
+ 0, 131, 130, 0, 0, 0, 0, 0, 0, 0,
+ 72, 0, 192, 0, 9, 91, 194, 0, 95, 70,
+ 46, 0, 0, 0, 0, 0, 4, 5, 0, 178,
+ 180, 0, 195, 0, 0, 87, 0, 0, 137, 0,
+ 167, 188, 0, 74, 185, 0, 153, 134, 34, 23,
+ 24, 48, 21, 22, 25, 82, 81, 80, 85, 0,
+ 109, 0, 0, 121, 117, 118, 114, 115, 112, 0,
+ 124, 123, 122, 120, 119, 116, 125, 113, 0, 97,
+ 0, 0, 90, 98, 165, 0, 0, 0, 0, 0,
+ 0, 71, 76, 75, 63, 0, 62, 3, 0, 182,
+ 192, 0, 0, 47, 0, 0, 49, 51, 0, 0,
+ 197, 45, 50, 0, 0, 20, 0, 0, 0, 181,
+ 196, 94, 0, 141, 0, 143, 0, 136, 187, 73,
+ 0, 0, 0, 108, 102, 0, 0, 106, 0, 0,
+ 194, 166, 0, 100, 0, 161, 0, 79, 92, 96,
+ 138, 43, 43, 0, 0, 0, 0, 46, 0, 0,
+ 0, 88, 142, 144, 111, 0, 105, 149, 0, 107,
+ 101, 0, 103, 162, 99, 0, 0, 8, 26, 26,
+ 0, 33, 0, 0, 0, 31, 110, 104, 89, 33,
+ 33, 10, 0, 0, 29, 30, 0, 39, 43, 33,
+ 42, 35, 36, 9, 27, 0, 33, 0, 38, 7,
+ 0, 37, 0, 0, 0, 26, 40, 28
};
/* YYDEFGOTO[NTERM-NUM]. */
static const short int yydefgoto[] =
{
- -1, 1, 105, 102, 2, 364, 375, 10, 4, 23,
- 301, 378, 80, 164, 24, 361, 302, 292, 240, 295,
- 304, 298, 25, 11, 12, 27, 13, 14, 18, 111,
- 17, 29, 99, 203, 234, 284, 15, 16, 31, 296,
- 82, 83, 290, 272, 84, 85, 86, 87, 88, 89,
- 90, 141, 128, 223, 299, 91, 92, 93, 94, 95,
- 96, 107
+ -1, 1, 110, 107, 317, 2, 378, 391, 10, 4,
+ 23, 311, 394, 84, 85, 172, 24, 25, 375, 312,
+ 302, 250, 305, 314, 308, 26, 11, 12, 28, 13,
+ 14, 18, 116, 17, 30, 104, 211, 244, 294, 15,
+ 16, 32, 306, 87, 88, 300, 282, 89, 90, 91,
+ 92, 93, 94, 95, 149, 136, 233, 309, 96, 97,
+ 98, 99, 100, 101, 112
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -352
+#define YYPACT_NINF -362
static const short int yypact[] =
{
- -352, 27, -352, -352, 121, -352, -352, 15, -352, -352,
- 18, -352, -352, -352, -352, -352, -352, 31, 39, -28,
- -352, 39, -352, -352, -352, 321, -352, 64, -352, 68,
- -352, 102, 68, -352, -352, -352, 7, 7, -352, 8,
- -352, 1642, -352, -352, 36, 49, 62, 65, -34, 1642,
- 74, 80, 89, 657, 574, 7, 740, 822, 119, 1642,
- 79, 1642, 7, 1642, 1642, 1642, 1642, 1642, 1642, 904,
- 986, -352, 1642, 1642, 7, 7, 7, 7, 104, 88,
- -352, 821, 117, -352, 34, -352, -352, -352, -352, 1860,
- -352, 106, 10, 14, -352, -352, 179, -352, -352, 138,
- 181, 138, -352, -352, -352, -352, -352, 1642, 114, 1642,
- 308, 64, 68, -352, -352, -352, -352, -352, -352, 120,
- 1860, 126, 1068, 574, -352, 308, 1770, 117, -352, 1709,
- 1642, -352, 128, -352, 308, 52, 135, 108, 1642, 308,
- 1150, 148, -352, -352, -352, 308, -352, 117, 266, 266,
- 266, -9, -9, 161, -21, -352, 118, 266, 266, -352,
- -352, -352, -352, 64, -352, -352, 1642, 1642, 1642, 1642,
- 1642, 1642, 1642, 1642, 1642, 1642, 1232, 1642, 1642, 1642,
- 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642, 1642,
- 1642, 1642, 1642, -352, -352, 37, 1314, 1642, 1642, 1642,
- 1642, 1642, 221, 4, 1642, 4, 48, -352, 1642, -20,
- -352, 138, 1642, 1642, 1642, 1642, 160, 406, -352, -352,
- -352, 19, 621, 170, 1642, 117, 1396, 1478, -352, 177,
- -352, -352, 201, 249, -352, 1642, 190, -352, -352, 67,
- -352, 67, 67, 67, 67, 220, 220, -352, 1860, 182,
- -352, 592, 129, 1920, 643, 477, 859, 721, 1860, 1817,
- 227, 227, 244, 393, 560, 690, 266, 266, 1642, -352,
- 1560, 1642, 198, -352, -352, 602, 306, 259, 374, 340,
- 391, -352, -352, -352, -352, 199, -352, -352, 208, -352,
- 1642, 64, 209, 67, 211, 217, 67, -352, 224, 226,
- -352, -352, -352, 225, 233, 185, 1642, -352, -352, -352,
- 725, -352, 807, -352, 827, -352, -352, -352, 425, 1642,
- 238, -352, -352, 1642, 459, -352, 874, 509, 1642, -352,
- 241, -352, 242, -352, 246, -352, -352, -352, -352, -352,
- -352, 299, 299, 1642, 299, 1642, 247, -352, -352, -352,
- -352, 519, -352, 1903, 253, -352, -352, 272, -352, -352,
- -352, 299, 299, -352, 54, 54, 275, 104, 289, 299,
- -352, -352, -352, 104, 104, -352, 299, 294, -352, -352,
- 299, -352, -352, 104, -352, -352, 116, -352, 1642, 104,
- 491, -352, -352, 298, -352, 300, 299, 299, 54, -352,
- -352
+ -362, 19, -362, -362, 123, -362, -362, 20, -362, -362,
+ 40, -362, -362, -362, -362, -362, -362, 51, 57, -8,
+ -362, 57, -362, -362, -362, -362, 291, -362, 73, -362,
+ 70, -362, 95, 70, -362, -362, -362, 17, 17, -362,
+ 41, -362, 1660, -362, -362, 43, 46, 50, 58, 83,
+ 65, 67, 73, 1660, 68, 78, 84, 639, 553, 17,
+ 725, 810, 138, 1660, 262, 1660, 17, 1660, 1660, 1660,
+ 1660, 1660, 1660, 895, 980, -362, 1660, 1660, 17, 17,
+ 17, 17, 140, 86, -362, -362, 604, 108, -362, 10,
+ -362, -362, -362, -362, 1911, -362, 91, 11, 14, -362,
+ -362, 171, -362, -362, 128, 180, 128, -362, -362, -362,
+ -362, -362, 1660, 126, 1660, 796, 73, 70, -362, -362,
+ -362, -362, -362, -362, 137, -362, -362, -362, 1911, 109,
+ 1065, 553, -362, 796, 1794, 108, -362, 1730, 1660, -362,
+ 161, -362, 796, 39, 169, 160, 1660, 796, 1150, 168,
+ -362, -362, -362, 796, -362, 108, 499, 499, 499, -35,
+ -35, 172, 214, -362, -23, 499, 499, -362, -362, -362,
+ -362, 73, -362, -362, 1660, 1660, 1660, 1660, 1660, 1660,
+ 1660, 1660, 1660, 1660, 1235, 1660, 1660, 1660, 1660, 1660,
+ 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660,
+ 1660, -362, -362, 47, 1320, 1660, 1660, 1660, 1660, 1660,
+ 211, 6, 1660, 6, 64, -362, 1660, -45, -362, 128,
+ 1660, 1660, 1660, 1660, 155, 379, -362, -362, 1660, -362,
+ -362, 349, 149, 176, 1660, 108, 1405, 1490, -362, 179,
+ -362, -362, 428, 253, -362, 1660, 182, -362, -362, 383,
+ -362, 383, 383, 383, 383, 227, 227, -362, 1911, 235,
+ -362, 471, 31, 1971, 758, 625, 842, 100, 1911, 1868,
+ 207, 207, 455, 540, 711, 367, 499, 499, 1660, -362,
+ 1575, 1660, 206, -362, -362, 514, 276, 139, 290, 204,
+ 364, -362, -362, -362, -362, 201, -362, -362, 213, -362,
+ 1660, 73, 216, 383, 223, 229, 383, -362, 231, 244,
+ -362, -362, -362, 232, 257, 378, 1660, 1660, 268, -362,
+ -362, -362, 600, -362, 657, -362, 667, -362, -362, -362,
+ 222, 1660, 270, -362, -362, 1660, 433, -362, 686, 300,
+ 1660, -362, 271, -362, 275, -362, 281, -362, -362, -362,
+ -362, -362, -362, 353, 353, 1660, 353, 1660, 311, 316,
+ 353, -362, -362, -362, -362, 310, -362, 1954, 287, -362,
+ -362, 317, -362, -362, -362, 353, 353, -362, 16, 16,
+ 319, 140, 324, 353, 353, -362, -362, -362, -362, 140,
+ 140, -362, 353, 330, -362, -362, 353, -362, -362, 140,
+ -362, -362, -362, 116, -362, 1660, 140, 467, -362, -362,
+ 333, -362, 342, 353, 353, 16, -362, -362
};
/* YYPGOTO[NTERM-NUM]. */
static const short int yypgoto[] =
{
- -352, -352, -7, -92, -352, -104, -352, -352, -101, -352,
- 350, -351, -352, 152, -352, -325, -352, 38, -177, -211,
- -11, -352, -352, -352, -352, -352, -352, -352, 72, 337,
- -352, 361, -27, -97, -352, 189, -352, -352, -352, -25,
- -51, -352, -352, -352, -352, -352, -352, -352, -352, 35,
- -352, -352, -99, -206, -352, -352, 193, 335, 338, -352,
- -352, -3
+ -362, -362, -24, -51, -362, -362, 1508, -362, -362, -106,
+ -362, 402, -361, -362, -362, -183, -362, -362, -342, -362,
+ 85, -196, -220, -39, -362, -362, -362, -362, -362, -362,
+ -362, 49, 397, -362, 423, -17, -99, -362, 236, -362,
+ -362, -362, -26, -52, -362, -362, -362, -362, -362, -362,
+ -362, -362, 38, -362, -362, -100, -213, -362, -362, -15,
+ 386, 387, -362, -362, 184
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -178
+#define YYTABLE_NINF -184
static const short int yytable[] =
{
- 81, 206, 288, 127, 205, 101, 303, 34, 207, 117,
- 34, 103, 147, 197, 379, 362, 104, 199, 78, 19,
- 97, 212, 213, 214, 215, 216, 217, 3, 171, 172,
- 173, 22, 137, 174, 108, 26, 294, 175, 297, 230,
- 268, 118, 269, 28, 154, 156, 124, 400, 74, 133,
- 30, 130, 131, 236, 289, 197, 127, 390, 209, 146,
- -178, -178, 5, 6, 195, 7, 8, 34, 171, 172,
- 173, 159, 160, 161, 162, 98, 110, 376, 377, 225,
- 20, 21, 282, 109, 120, 211, 198, 127, 125, 74,
- 200, 134, 9, 307, 139, 346, 145, 221, 222, 148,
- 149, 150, 151, 152, 210, 285, 100, 157, 158, 176,
- 177, 113, 270, 271, 291, 232, 171, 172, 173, 74,
- 224, -2, 357, 138, 114, 287, 306, 227, 198, 163,
- 5, 6, 366, 7, 8, 5, 6, 115, 7, 8,
- 116, 239, 241, 242, 243, 244, 245, 246, 247, 121,
- 249, 251, 252, 127, 140, 122, 238, 171, 172, 173,
- 9, 74, 75, 76, 123, 9, 165, 171, 172, 173,
- 174, 275, 276, 277, 278, 279, 280, 393, 171, 172,
- 173, 196, 201, 222, 202, 204, 229, 293, 241, 208,
- 241, 337, 305, 392, 233, 218, 283, 237, 283, 310,
- 219, 312, 314, 226, 166, 167, 168, 169, 322, 248,
- 318, 170, 228, 253, 254, 255, 256, 257, 258, 259,
- 260, 261, 262, 263, 264, 265, 266, 267, 281, 106,
- 106, 171, 172, 173, 171, 172, 173, 235, 365, 127,
- 367, 119, 74, 324, 309, 326, 327, 129, 106, 135,
- 171, 172, 173, 142, 315, 106, 317, 373, 374, -43,
- 320, 179, 180, 181, 182, 383, 319, 106, 106, 106,
- 106, 173, 387, 328, 386, 316, 389, 335, 179, 180,
- 181, 182, 336, 339, 338, 340, 187, 188, 189, 190,
- 191, 341, 398, 399, 351, 192, 193, 194, 342, 344,
- 195, 343, 363, 222, 188, 189, 190, 191, 171, 172,
- 173, 345, 192, 193, 194, 352, 129, 195, 358, 359,
- 293, 369, 33, 360, 34, 35, 36, 37, 38, 39,
- 371, 40, 41, 42, 192, 193, 194, 43, 331, 195,
- 44, 45, 46, 47, 181, 182, 372, 48, 49, 380,
- 50, 51, 52, 53, 54, 171, 172, 173, 353, 55,
- 56, 57, 58, 59, 60, 81, 61, 382, 62, 388,
- 190, 191, 396, 63, 397, 79, 192, 193, 194, 395,
- 112, 195, 32, 368, 330, 64, 65, 66, 273, 171,
- 172, 173, 67, 68, 286, 143, 69, 70, 144, 71,
- 0, 72, 73, 74, 75, 76, 77, 33, 0, 300,
- 35, 36, 37, 38, 39, 0, 40, 41, 42, 333,
- 0, 0, 43, 171, 172, 173, 0, 179, 180, 181,
- 182, 0, 0, 49, 0, 50, 51, 52, 53, 54,
- 171, 172, 173, 0, 55, 56, 57, 58, 59, 60,
- 0, 61, 332, 62, 189, 190, 191, 0, 63, 0,
- 0, 192, 193, 194, 0, 0, 195, 0, 0, 334,
- 64, 65, 66, 0, 171, 172, 173, 67, 68, 0,
- 0, 69, 70, 0, -38, 0, 72, 73, 74, 75,
- 76, 77, 33, 0, 0, 35, 36, 37, 38, 39,
- 0, 40, 41, 42, 350, 0, 0, 43, 171, 172,
- 173, 179, -178, 181, 182, 0, 0, 0, 49, 381,
- 50, 51, 52, 53, 54, 384, 385, 0, 0, 55,
- 56, 57, 58, 59, 60, 391, 61, 354, 62, 190,
- 191, 394, 0, 63, 0, 192, 193, 194, 0, 0,
- 195, 0, 0, 0, 0, 64, 65, 66, 171, 172,
- 173, 0, 67, 68, 0, -38, 69, 70, 171, 172,
- 173, 72, 73, 74, 75, 76, 77, 34, 126, 36,
- 37, 38, 39, 104, 40, 41, 42, 0, 356, 0,
- 43, 0, 0, 0, 179, 180, 181, 182, 370, 0,
- 0, 49, 0, 50, 51, 52, 53, 54, 0, 0,
- 0, 0, 55, 56, 57, 58, 59, 60, 0, 61,
- 0, 62, 190, 191, 0, 0, 63, 0, 192, 193,
- 194, 0, 0, 195, 0, 0, 0, 0, 64, 65,
- 66, 171, 172, 173, 0, 67, 68, 0, 0, 69,
- 70, 171, 172, 173, 72, 73, 74, 75, 76, 77,
- 34, 35, 36, 37, 38, 39, 321, 40, 41, 42,
- 171, 172, 173, 43, 308, 0, 329, -178, 0, 181,
- 182, 0, 0, 0, 49, 0, 50, 51, 52, 53,
- 54, 0, 0, 0, 0, 55, 56, 57, 58, 59,
- 60, 0, 61, 0, 62, 190, 191, 0, 0, 63,
- 0, 192, 193, 194, 0, 0, 195, 0, 0, 0,
- 0, 64, 65, 66, 0, 0, 181, 182, 67, 68,
- 0, 0, 69, 70, 0, 0, 0, 72, 73, 74,
- 75, 76, 77, 34, 132, 36, 37, 38, 39, 0,
- 40, 41, 42, 191, 0, 0, 43, 181, 192, 193,
- 194, 0, 0, 195, 0, 0, 0, 49, 0, 50,
- 51, 52, 53, 54, 171, 172, 173, 0, 55, 56,
- 57, 58, 59, 60, 191, 61, 0, 62, 0, 192,
- 193, 194, 63, 0, 195, 0, 0, 0, 0, 347,
- 0, 0, 0, 0, 64, 65, 66, 0, 0, 0,
- 0, 67, 68, 0, 0, 69, 70, 0, 0, 0,
- 72, 73, 74, 75, 76, 77, 35, 36, 37, 38,
- 39, 0, 40, 41, 42, 0, 0, 0, 43, 0,
- 166, 167, 168, 169, 0, 0, 0, 170, 0, 49,
- 0, 50, 51, 52, 53, 54, 171, 172, 173, 0,
- 55, 56, 57, 58, 59, 60, 0, 61, 0, 62,
- 171, 172, 173, 0, 63, 0, 171, 172, 173, 0,
- 0, 348, 0, 0, 0, 0, 64, 65, 66, 0,
- 0, 0, 0, 67, 68, 0, 0, 69, 70, 0,
- 136, 349, 72, 73, 74, 75, 76, 77, 35, 36,
- 37, 38, 39, 0, 40, 41, 42, 0, 0, 0,
- 43, 0, 191, 171, 172, 173, 0, 192, 193, 194,
- 0, 49, 195, 50, 51, 52, 53, 54, 0, 0,
- 0, 0, 55, 56, 57, 58, 59, 60, 355, 61,
- 0, 62, 0, 0, 0, 0, 63, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 64, 65,
- 66, 0, 0, 0, 0, 67, 68, 0, 153, 69,
- 70, 0, 0, 0, 72, 73, 74, 75, 76, 77,
- 35, 36, 37, 38, 39, 0, 40, 41, 42, 0,
- 0, 0, 43, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 49, 0, 50, 51, 52, 53, 54,
- 0, 0, 0, 0, 55, 56, 57, 58, 59, 60,
- 0, 61, 0, 62, 0, 0, 0, 0, 63, 0,
+ 86, 214, 82, 298, 102, 313, 135, 213, 318, 35,
+ 376, 182, 215, 183, 205, 155, 106, 207, 395, 3,
+ 35, 108, 111, 111, 19, 304, 109, 307, 127, 179,
+ 180, 181, 299, 132, 124, 145, 141, -184, -184, 392,
+ 393, 203, 205, 137, 111, 143, 240, 162, 164, 150,
+ 278, 111, 279, 22, 417, 27, 407, 20, 21, 247,
+ 135, 29, 217, 111, 111, 111, 111, 220, 221, 222,
+ 223, 224, 225, 31, 227, 228, 35, 103, 5, 6,
+ 115, 7, 8, 179, 180, 181, 235, 292, 184, 185,
+ 206, 128, 218, 208, 135, 133, 358, 359, 142, 105,
+ 219, 147, 78, 153, 231, 232, 156, 157, 158, 159,
+ 160, 9, 295, 334, 165, 166, 137, 237, 206, 114,
+ 301, 118, 242, -2, 119, 280, 281, 371, 120, 122,
+ 5, 6, 78, 7, 8, 380, 121, 5, 6, 189,
+ 7, 8, 146, 125, 297, 126, 129, 248, 249, 251,
+ 252, 253, 254, 255, 256, 257, 130, 259, 261, 262,
+ 135, 123, 131, 9, 182, 171, 199, 173, 78, 204,
+ 9, 200, 201, 202, 209, 316, 203, 210, 285, 286,
+ 287, 288, 289, 290, 212, 410, 229, 293, 283, 293,
+ 232, 179, 180, 181, 303, 251, 409, 251, 397, 315,
+ 349, 179, 180, 181, 216, 320, 401, 402, 322, 310,
+ 324, 326, 179, 180, 181, 226, 408, 243, 291, 330,
+ 258, 343, 113, 411, 263, 264, 265, 266, 267, 268,
+ 269, 270, 271, 272, 273, 274, 275, 276, 277, 236,
+ 78, 239, 138, 139, 187, 188, 189, 190, 135, 238,
+ 154, 245, 336, 321, 338, 339, 179, 180, 181, 327,
+ 329, 331, 167, 168, 169, 170, 179, 180, 181, 195,
+ 196, 197, 198, 199, 179, 180, 181, 350, 200, 201,
+ 202, 181, 347, 203, 340, 403, 345, 179, 180, 181,
+ 348, 246, 34, 351, 35, 36, 37, 38, 39, 40,
+ 352, 41, 42, 43, 364, 365, 353, 44, 354, 356,
+ 45, 46, 47, 48, 232, 234, 332, 49, 50, 51,
+ 52, 53, 355, 54, 55, 56, 57, 58, 179, 180,
+ 181, 303, 59, 60, 61, 62, 63, 64, 357, 65,
+ 148, 66, 179, 180, 181, 360, 67, 78, 79, 80,
+ 366, 372, 179, 180, 181, 373, 377, 342, 68, 69,
+ 70, 374, 179, 180, 181, 71, 72, 387, 412, 73,
+ 74, 344, 75, 367, 76, 77, 78, 79, 80, 81,
+ 34, 86, 370, 36, 37, 38, 39, 40, 383, 41,
+ 42, 43, 386, 384, 388, 44, 396, 174, 175, 176,
+ 177, 179, 180, 181, 178, 398, 189, 190, 405, 53,
+ 413, 54, 55, 56, 57, 58, 179, 180, 181, 414,
+ 59, 60, 61, 62, 63, 64, 319, 65, 83, 66,
+ 179, 180, 181, 199, 67, 179, 180, 181, 200, 201,
+ 202, 117, 382, 203, 33, 346, 68, 69, 70, 296,
+ 151, 152, 0, 71, 72, -49, 0, 73, 74, 0,
+ -44, 0, 76, 77, 78, 79, 80, 81, 34, 0,
+ 0, 36, 37, 38, 39, 40, 0, 41, 42, 43,
+ 179, 180, 181, 44, 0, 179, 180, 181, 0, 0,
+ 0, 0, 187, 188, 189, 190, 0, 53, 0, 54,
+ 55, 56, 57, 58, 0, 328, 0, 0, 59, 60,
+ 61, 62, 63, 64, 368, 65, 0, 66, 196, 197,
+ 198, 199, 67, 179, 180, 181, 200, 201, 202, 0,
+ 0, 203, 0, 0, 68, 69, 70, 0, 0, 0,
+ 0, 71, 72, 0, -44, 73, 74, 0, 333, 0,
+ 76, 77, 78, 79, 80, 81, 35, 134, 37, 38,
+ 39, 40, 109, 41, 42, 43, 179, 180, 181, 44,
+ 200, 201, 202, 0, 0, 203, 0, 187, 188, 189,
+ 190, 0, 0, 53, 0, 54, 55, 56, 57, 58,
+ 0, 341, 0, 0, 59, 60, 61, 62, 63, 64,
+ 0, 65, 0, 66, 197, 198, 199, 0, 67, 0,
+ 0, 200, 201, 202, 0, 0, 203, 0, 0, 0,
+ 68, 69, 70, 174, 175, 176, 177, 71, 72, 0,
+ 178, 73, 74, 0, 0, 0, 76, 77, 78, 79,
+ 80, 81, 35, 36, 37, 38, 39, 40, 0, 41,
+ 42, 43, 179, 180, 181, 44, 179, 180, 181, 0,
+ 0, 0, 187, -184, 189, 190, 0, 0, 0, 53,
+ 0, 54, 55, 56, 57, 58, 0, 361, 0, 0,
+ 59, 60, 61, 62, 63, 64, 0, 65, 0, 66,
+ 198, 199, 0, 0, 67, 0, 200, 201, 202, 0,
+ 0, 203, 0, 0, 0, 0, 68, 69, 70, 179,
+ 180, 181, 0, 71, 72, 0, 0, 73, 74, 179,
+ 180, 181, 76, 77, 78, 79, 80, 81, 35, 140,
+ 37, 38, 39, 40, 362, 41, 42, 43, 179, 180,
+ 181, 44, 0, 0, 363, 0, 0, 0, 187, 188,
+ 189, 190, 0, 0, 0, 53, 0, 54, 55, 56,
+ 57, 58, 0, 369, 0, 0, 59, 60, 61, 62,
+ 63, 64, 0, 65, 0, 66, 198, 199, 0, 0,
+ 67, 0, 200, 201, 202, 0, 0, 203, 0, 0,
+ 0, 0, 68, 69, 70, -184, 0, 189, 190, 71,
+ 72, 0, 0, 73, 74, 0, 0, 0, 76, 77,
+ 78, 79, 80, 81, 36, 37, 38, 39, 40, 0,
+ 41, 42, 43, 198, 199, 0, 44, 0, 0, 200,
+ 201, 202, 0, 0, 203, 189, 190, 0, 0, 0,
+ 53, 0, 54, 55, 56, 57, 58, 0, 0, 0,
+ 0, 59, 60, 61, 62, 63, 64, 0, 65, 0,
+ 66, 198, 199, 0, 0, 67, 0, 200, 201, 202,
+ 0, 0, 203, 0, 0, 0, 0, 68, 69, 70,
+ 0, 0, 0, 0, 71, 72, 0, 0, 73, 74,
+ 0, 144, 0, 76, 77, 78, 79, 80, 81, 36,
+ 37, 38, 39, 40, 0, 41, 42, 43, 199, 0,
+ 0, 44, 0, 200, 201, 202, 0, 0, 203, 0,
+ 0, 0, 0, 0, 0, 53, 0, 54, 55, 56,
+ 57, 58, 0, 0, 0, 0, 59, 60, 61, 62,
+ 63, 64, 0, 65, 0, 66, 0, 0, 0, 0,
+ 67, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 68, 69, 70, 0, 0, 0, 0, 71,
+ 72, 0, 161, 73, 74, 0, 0, 0, 76, 77,
+ 78, 79, 80, 81, 36, 37, 38, 39, 40, 0,
+ 41, 42, 43, 0, 0, 0, 44, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 64, 65, 66, 0, 0, 0, 0, 67, 68, 0,
- 0, 69, 70, 0, 0, 155, 72, 73, 74, 75,
- 76, 77, 35, 36, 37, 38, 39, 0, 40, 41,
- 42, 0, 0, 0, 43, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 49, 0, 50, 51, 52,
- 53, 54, 0, 0, 0, 0, 55, 56, 57, 58,
- 59, 60, 0, 61, 0, 62, 0, 0, 0, 0,
- 63, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 64, 65, 66, 0, 0, 0, 0, 67,
- 68, 0, 220, 69, 70, 0, 0, 0, 72, 73,
- 74, 75, 76, 77, 35, 36, 37, 38, 39, 0,
- 40, 41, 42, 0, 0, 0, 43, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 49, 0, 50,
- 51, 52, 53, 54, 0, 0, 0, 0, 55, 56,
- 57, 58, 59, 60, 0, 61, 0, 62, 0, 0,
- 0, 0, 63, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 64, 65, 66, 0, 0, 0,
- 0, 67, 68, 0, 231, 69, 70, 0, 0, 0,
- 72, 73, 74, 75, 76, 77, 35, 36, 37, 38,
- 39, 0, 40, 41, 42, 0, 0, 0, 43, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 49,
- 0, 50, 51, 52, 53, 54, 0, 0, 0, 0,
- 55, 56, 57, 58, 59, 60, 0, 61, 0, 62,
- 0, 0, 0, 0, 63, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 64, 65, 66, 0,
- 0, 0, 0, 67, 68, 0, 250, 69, 70, 0,
- 0, 0, 72, 73, 74, 75, 76, 77, 35, 36,
- 37, 38, 39, 0, 40, 41, 42, 0, 0, 0,
- 43, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 49, 0, 50, 51, 52, 53, 54, 0, 0,
- 0, 0, 55, 56, 57, 58, 59, 60, 0, 61,
- 0, 62, 0, 0, 0, 0, 63, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 64, 65,
- 66, 0, 0, 0, 0, 67, 68, 0, 274, 69,
- 70, 0, 0, 0, 72, 73, 74, 75, 76, 77,
- 35, 36, 37, 38, 39, 0, 40, 41, 42, 0,
- 0, 0, 43, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 49, 0, 50, 51, 52, 53, 54,
- 0, 0, 0, 0, 55, 56, 57, 58, 59, 60,
- 0, 61, 0, 62, 0, 0, 0, 0, 63, 0,
+ 53, 0, 54, 55, 56, 57, 58, 0, 0, 0,
+ 0, 59, 60, 61, 62, 63, 64, 0, 65, 0,
+ 66, 0, 0, 0, 0, 67, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 68, 69, 70,
+ 0, 0, 0, 0, 71, 72, 0, 0, 73, 74,
+ 0, 0, 163, 76, 77, 78, 79, 80, 81, 36,
+ 37, 38, 39, 40, 0, 41, 42, 43, 0, 0,
+ 0, 44, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 53, 0, 54, 55, 56,
+ 57, 58, 0, 0, 0, 0, 59, 60, 61, 62,
+ 63, 64, 0, 65, 0, 66, 0, 0, 0, 0,
+ 67, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 68, 69, 70, 0, 0, 0, 0, 71,
+ 72, 0, 230, 73, 74, 0, 0, 0, 76, 77,
+ 78, 79, 80, 81, 36, 37, 38, 39, 40, 0,
+ 41, 42, 43, 0, 0, 0, 44, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 64, 65, 66, 0, 0, 0, 0, 67, 68, 0,
- 311, 69, 70, 0, 0, 0, 72, 73, 74, 75,
- 76, 77, 35, 36, 37, 38, 39, 0, 40, 41,
- 42, 0, 0, 0, 43, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 49, 0, 50, 51, 52,
- 53, 54, 0, 0, 0, 0, 55, 56, 57, 58,
- 59, 60, 0, 61, 0, 62, 0, 0, 0, 0,
- 63, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 64, 65, 66, 0, 0, 0, 0, 67,
- 68, 0, 313, 69, 70, 0, 0, 0, 72, 73,
- 74, 75, 76, 77, 35, 36, 37, 38, 39, 0,
- 40, 41, 42, 0, 0, 0, 43, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 49, 0, 50,
- 51, 52, 53, 54, 0, 0, 0, 0, 55, 56,
- 57, 58, 59, 60, 0, 61, 0, 62, 0, 0,
- 0, 0, 63, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 64, 65, 66, 0, 0, 0,
- 0, 67, 68, 0, 325, 69, 70, 0, 0, 0,
- 72, 73, 74, 75, 76, 77, 35, 36, 37, 38,
- 39, 0, 40, 41, 42, 0, 0, 0, 43, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 49,
- 0, 50, 51, 52, 53, 54, 0, 0, 0, 0,
- 55, 56, 57, 58, 59, 60, 0, 61, 0, 62,
- 0, 0, 0, 0, 63, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 64, 65, 66, 0,
- 0, 0, 197, 67, 68, 0, 0, 69, 70, 0,
- 0, 0, 72, 73, 74, 75, 76, 77, -149, -149,
- -149, -149, 0, 0, 0, -149, 0, -149, 0, 0,
- 0, 0, 0, -149, -149, -149, -149, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, -149, -149,
- -149, 0, -149, -149, -149, -149, -149, -149, -149, -149,
- -149, -149, -149, 0, 0, 0, 0, -149, -149, -149,
- 0, 0, -149, -149, 0, 198, 0, -149, -149, -177,
- -177, -177, -177, 0, 0, 0, -177, 0, -177, 0,
- 0, 0, 0, 0, -177, -177, -177, -177, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, -177,
- -177, -177, 0, -177, -177, -177, -177, -177, -177, -177,
- -177, -177, -177, -177, 0, 0, 0, 0, -177, -177,
- -177, 0, 0, -177, -177, 178, 0, 0, -177, -177,
- 0, 179, 180, 181, 182, 0, 0, 0, 0, 0,
+ 53, 0, 54, 55, 56, 57, 58, 0, 0, 0,
+ 0, 59, 60, 61, 62, 63, 64, 0, 65, 0,
+ 66, 0, 0, 0, 0, 67, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 68, 69, 70,
+ 0, 0, 0, 0, 71, 72, 0, 241, 73, 74,
+ 0, 0, 0, 76, 77, 78, 79, 80, 81, 36,
+ 37, 38, 39, 40, 0, 41, 42, 43, 0, 0,
+ 0, 44, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 53, 0, 54, 55, 56,
+ 57, 58, 0, 0, 0, 0, 59, 60, 61, 62,
+ 63, 64, 0, 65, 0, 66, 0, 0, 0, 0,
+ 67, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 68, 69, 70, 0, 0, 0, 0, 71,
+ 72, 0, 260, 73, 74, 0, 0, 0, 76, 77,
+ 78, 79, 80, 81, 36, 37, 38, 39, 40, 0,
+ 41, 42, 43, 0, 0, 0, 44, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 183, 184, 323, 185, 186, 187, 188, 189, 190,
- 191, 0, 0, 0, 0, 192, 193, 194, 178, 0,
- 195, 0, 0, 0, 179, 180, 181, 182, 0, 0,
+ 53, 0, 54, 55, 56, 57, 58, 0, 0, 0,
+ 0, 59, 60, 61, 62, 63, 64, 0, 65, 0,
+ 66, 0, 0, 0, 0, 67, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 68, 69, 70,
+ 0, 0, 0, 0, 71, 72, 0, 284, 73, 74,
+ 0, 0, 0, 76, 77, 78, 79, 80, 81, 36,
+ 37, 38, 39, 40, 0, 41, 42, 43, 0, 0,
+ 0, 44, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 53, 0, 54, 55, 56,
+ 57, 58, 0, 0, 0, 0, 59, 60, 61, 62,
+ 63, 64, 0, 65, 0, 66, 0, 0, 0, 0,
+ 67, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 68, 69, 70, 0, 0, 0, 0, 71,
+ 72, 0, 323, 73, 74, 0, 0, 0, 76, 77,
+ 78, 79, 80, 81, 36, 37, 38, 39, 40, 0,
+ 41, 42, 43, 0, 0, 0, 44, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 183, 184, 0, 185, 186, 187,
- 188, 189, 190, 191, 0, 0, 0, 0, 192, 193,
- 194, 178, 0, 195, 0, 0, 0, 179, 180, 181,
- 182, 0, 0, 0, 0, 0, 0, 0, -178, 0,
- 0, 0, 0, 0, 179, 180, 181, 182, 184, 0,
- 185, 186, 187, 188, 189, 190, 191, 0, 0, 0,
- 0, 192, 193, 194, 0, 0, 195, 185, 186, 187,
- 188, 189, 190, 191, 0, 0, 0, 0, 192, 193,
- 194, 0, 0, 195
+ 53, 0, 54, 55, 56, 57, 58, 0, 0, 0,
+ 0, 59, 60, 61, 62, 63, 64, 0, 65, 0,
+ 66, 0, 0, 0, 0, 67, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 68, 69, 70,
+ 0, 0, 0, 0, 71, 72, 0, 325, 73, 74,
+ 0, 0, 0, 76, 77, 78, 79, 80, 81, 36,
+ 37, 38, 39, 40, 0, 41, 42, 43, 0, 0,
+ 0, 44, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 53, 0, 54, 55, 56,
+ 57, 58, 0, 0, 0, 0, 59, 60, 61, 62,
+ 63, 64, 0, 65, 0, 66, 0, 0, 0, 0,
+ 67, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 68, 69, 70, 0, 0, 0, 0, 71,
+ 72, 0, 337, 73, 74, 0, 0, 0, 76, 77,
+ 78, 79, 80, 81, 36, 37, 38, 39, 40, 0,
+ 41, 42, 43, 0, 0, 0, 44, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 53, 0, 54, 55, 56, 57, 58, 0, 0, 0,
+ 0, 59, 60, 61, 62, 63, 64, 0, 65, 0,
+ 66, 0, 0, 0, 0, 67, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 68, 69, 70,
+ 0, 0, 0, 205, 71, 72, 0, 0, 73, 74,
+ 0, 0, 0, 76, 77, 78, 79, 80, 81, -155,
+ -155, -155, -155, 0, 0, 0, -155, 0, 0, 0,
+ 0, -155, 0, 0, 0, 0, 0, -155, -155, -155,
+ -155, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, -155, -155, -155, 0, -155, -155, -155, -155,
+ -155, -155, -155, -155, -155, -155, -155, 0, 0, 0,
+ 0, -155, -155, -155, 0, 0, -155, -155, 0, 206,
+ 0, -155, -155, -183, -183, -183, -183, 0, 0, 0,
+ -183, 0, 0, 0, 0, -183, 0, 0, 0, 0,
+ 0, -183, -183, -183, -183, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, -183, -183, -183, 0,
+ -183, -183, -183, -183, -183, -183, -183, -183, -183, -183,
+ -183, 0, 379, 0, 381, -183, -183, -183, 385, 0,
+ -183, -183, 0, 0, 0, -183, -183, 0, 0, 0,
+ 0, 0, 0, 389, 390, 0, 0, 0, 0, 0,
+ 0, 399, 400, 0, 0, 0, 0, 0, 0, 186,
+ 404, 0, 0, 0, 406, 187, 188, 189, 190, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 415, 416, 0, 0, 191, 192, 335, 193, 194,
+ 195, 196, 197, 198, 199, 0, 0, 0, 0, 200,
+ 201, 202, 186, 0, 203, 0, 0, 0, 187, 188,
+ 189, 190, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 191, 192,
+ 0, 193, 194, 195, 196, 197, 198, 199, 0, 0,
+ 0, 0, 200, 201, 202, 186, 0, 203, 0, 0,
+ 0, 187, 188, 189, 190, 0, 0, 0, 0, 0,
+ 0, 0, -184, 0, 0, 0, 0, 0, 187, 188,
+ 189, 190, 192, 0, 193, 194, 195, 196, 197, 198,
+ 199, 0, 0, 0, 0, 200, 201, 202, 0, 0,
+ 203, 193, 194, 195, 196, 197, 198, 199, 0, 0,
+ 0, 0, 200, 201, 202, 0, 0, 203
};
static const short int yycheck[] =
{
- 25, 102, 208, 54, 101, 32, 217, 3, 107, 43,
- 3, 4, 63, 3, 365, 340, 9, 3, 25, 4,
- 27, 113, 114, 115, 116, 117, 118, 0, 49, 50,
- 51, 13, 57, 53, 37, 4, 213, 3, 215, 138,
- 3, 75, 5, 4, 69, 70, 53, 398, 82, 56,
- 78, 54, 55, 74, 74, 3, 107, 382, 109, 62,
- 69, 70, 14, 15, 73, 17, 18, 3, 49, 50,
- 51, 74, 75, 76, 77, 7, 41, 23, 24, 130,
- 8, 9, 78, 75, 49, 112, 76, 138, 53, 82,
- 76, 56, 44, 74, 59, 306, 61, 122, 123, 64,
- 65, 66, 67, 68, 111, 204, 4, 72, 73, 75,
- 76, 75, 75, 76, 211, 140, 49, 50, 51, 82,
- 123, 0, 328, 4, 75, 77, 218, 75, 76, 25,
- 14, 15, 343, 17, 18, 14, 15, 75, 17, 18,
- 75, 166, 167, 168, 169, 170, 171, 172, 173, 75,
- 175, 176, 177, 204, 75, 75, 163, 49, 50, 51,
- 44, 82, 83, 84, 75, 44, 78, 49, 50, 51,
- 53, 196, 197, 198, 199, 200, 201, 388, 49, 50,
- 51, 75, 3, 208, 46, 4, 78, 212, 213, 75,
- 215, 290, 217, 77, 46, 75, 203, 79, 205, 224,
- 74, 226, 227, 75, 19, 20, 21, 22, 79, 174,
- 235, 26, 77, 178, 179, 180, 181, 182, 183, 184,
- 185, 186, 187, 188, 189, 190, 191, 192, 7, 36,
- 37, 49, 50, 51, 49, 50, 51, 76, 342, 290,
- 344, 48, 82, 268, 74, 270, 271, 54, 55, 56,
- 49, 50, 51, 60, 77, 62, 7, 361, 362, 74,
- 78, 34, 35, 36, 37, 369, 76, 74, 75, 76,
- 77, 51, 376, 75, 375, 74, 380, 78, 34, 35,
- 36, 37, 74, 74, 291, 74, 59, 60, 61, 62,
- 63, 74, 396, 397, 319, 68, 69, 70, 74, 74,
- 73, 75, 3, 328, 60, 61, 62, 63, 49, 50,
- 51, 78, 68, 69, 70, 77, 123, 73, 77, 77,
- 345, 74, 1, 77, 3, 4, 5, 6, 7, 8,
- 77, 10, 11, 12, 68, 69, 70, 16, 79, 73,
- 19, 20, 21, 22, 36, 37, 74, 26, 27, 74,
- 29, 30, 31, 32, 33, 49, 50, 51, 323, 38,
- 39, 40, 41, 42, 43, 390, 45, 78, 47, 75,
- 62, 63, 74, 52, 74, 25, 68, 69, 70, 390,
- 43, 73, 21, 345, 78, 64, 65, 66, 195, 49,
- 50, 51, 71, 72, 205, 60, 75, 76, 60, 78,
- -1, 80, 81, 82, 83, 84, 85, 1, -1, 216,
- 4, 5, 6, 7, 8, -1, 10, 11, 12, 79,
- -1, -1, 16, 49, 50, 51, -1, 34, 35, 36,
- 37, -1, -1, 27, -1, 29, 30, 31, 32, 33,
- 49, 50, 51, -1, 38, 39, 40, 41, 42, 43,
- -1, 45, 78, 47, 61, 62, 63, -1, 52, -1,
- -1, 68, 69, 70, -1, -1, 73, -1, -1, 78,
- 64, 65, 66, -1, 49, 50, 51, 71, 72, -1,
- -1, 75, 76, -1, 78, -1, 80, 81, 82, 83,
- 84, 85, 1, -1, -1, 4, 5, 6, 7, 8,
- -1, 10, 11, 12, 79, -1, -1, 16, 49, 50,
- 51, 34, 35, 36, 37, -1, -1, -1, 27, 367,
- 29, 30, 31, 32, 33, 373, 374, -1, -1, 38,
- 39, 40, 41, 42, 43, 383, 45, 78, 47, 62,
- 63, 389, -1, 52, -1, 68, 69, 70, -1, -1,
- 73, -1, -1, -1, -1, 64, 65, 66, 49, 50,
- 51, -1, 71, 72, -1, 74, 75, 76, 49, 50,
- 51, 80, 81, 82, 83, 84, 85, 3, 4, 5,
- 6, 7, 8, 9, 10, 11, 12, -1, 79, -1,
- 16, -1, -1, -1, 34, 35, 36, 37, 79, -1,
- -1, 27, -1, 29, 30, 31, 32, 33, -1, -1,
- -1, -1, 38, 39, 40, 41, 42, 43, -1, 45,
- -1, 47, 62, 63, -1, -1, 52, -1, 68, 69,
- 70, -1, -1, 73, -1, -1, -1, -1, 64, 65,
- 66, 49, 50, 51, -1, 71, 72, -1, -1, 75,
- 76, 49, 50, 51, 80, 81, 82, 83, 84, 85,
- 3, 4, 5, 6, 7, 8, 74, 10, 11, 12,
- 49, 50, 51, 16, 53, -1, 74, 34, -1, 36,
- 37, -1, -1, -1, 27, -1, 29, 30, 31, 32,
- 33, -1, -1, -1, -1, 38, 39, 40, 41, 42,
- 43, -1, 45, -1, 47, 62, 63, -1, -1, 52,
- -1, 68, 69, 70, -1, -1, 73, -1, -1, -1,
- -1, 64, 65, 66, -1, -1, 36, 37, 71, 72,
- -1, -1, 75, 76, -1, -1, -1, 80, 81, 82,
- 83, 84, 85, 3, 4, 5, 6, 7, 8, -1,
- 10, 11, 12, 63, -1, -1, 16, 36, 68, 69,
- 70, -1, -1, 73, -1, -1, -1, 27, -1, 29,
- 30, 31, 32, 33, 49, 50, 51, -1, 38, 39,
- 40, 41, 42, 43, 63, 45, -1, 47, -1, 68,
- 69, 70, 52, -1, 73, -1, -1, -1, -1, 74,
- -1, -1, -1, -1, 64, 65, 66, -1, -1, -1,
- -1, 71, 72, -1, -1, 75, 76, -1, -1, -1,
- 80, 81, 82, 83, 84, 85, 4, 5, 6, 7,
- 8, -1, 10, 11, 12, -1, -1, -1, 16, -1,
- 19, 20, 21, 22, -1, -1, -1, 26, -1, 27,
- -1, 29, 30, 31, 32, 33, 49, 50, 51, -1,
- 38, 39, 40, 41, 42, 43, -1, 45, -1, 47,
- 49, 50, 51, -1, 52, -1, 49, 50, 51, -1,
- -1, 74, -1, -1, -1, -1, 64, 65, 66, -1,
- -1, -1, -1, 71, 72, -1, -1, 75, 76, -1,
- 78, 74, 80, 81, 82, 83, 84, 85, 4, 5,
- 6, 7, 8, -1, 10, 11, 12, -1, -1, -1,
- 16, -1, 63, 49, 50, 51, -1, 68, 69, 70,
- -1, 27, 73, 29, 30, 31, 32, 33, -1, -1,
- -1, -1, 38, 39, 40, 41, 42, 43, 74, 45,
- -1, 47, -1, -1, -1, -1, 52, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 64, 65,
- 66, -1, -1, -1, -1, 71, 72, -1, 74, 75,
- 76, -1, -1, -1, 80, 81, 82, 83, 84, 85,
- 4, 5, 6, 7, 8, -1, 10, 11, 12, -1,
- -1, -1, 16, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 27, -1, 29, 30, 31, 32, 33,
- -1, -1, -1, -1, 38, 39, 40, 41, 42, 43,
- -1, 45, -1, 47, -1, -1, -1, -1, 52, -1,
+ 26, 107, 26, 216, 28, 225, 58, 106, 228, 3,
+ 352, 56, 112, 3, 3, 67, 33, 3, 379, 0,
+ 3, 4, 37, 38, 4, 221, 9, 223, 52, 52,
+ 53, 54, 77, 57, 49, 61, 60, 72, 73, 23,
+ 24, 76, 3, 58, 59, 60, 146, 73, 74, 64,
+ 3, 66, 5, 13, 415, 4, 398, 8, 9, 82,
+ 112, 4, 114, 78, 79, 80, 81, 118, 119, 120,
+ 121, 122, 123, 81, 125, 126, 3, 7, 14, 15,
+ 42, 17, 18, 52, 53, 54, 138, 81, 78, 79,
+ 79, 53, 116, 79, 146, 57, 316, 317, 60, 4,
+ 117, 63, 85, 65, 130, 131, 68, 69, 70, 71,
+ 72, 47, 212, 82, 76, 77, 131, 78, 79, 78,
+ 219, 78, 148, 0, 78, 78, 79, 340, 78, 46,
+ 14, 15, 85, 17, 18, 355, 78, 14, 15, 39,
+ 17, 18, 4, 78, 80, 78, 78, 171, 174, 175,
+ 176, 177, 178, 179, 180, 181, 78, 183, 184, 185,
+ 212, 78, 78, 47, 56, 25, 66, 81, 85, 78,
+ 47, 71, 72, 73, 3, 226, 76, 49, 204, 205,
+ 206, 207, 208, 209, 4, 405, 77, 211, 203, 213,
+ 216, 52, 53, 54, 220, 221, 80, 223, 381, 225,
+ 300, 52, 53, 54, 78, 56, 389, 390, 234, 224,
+ 236, 237, 52, 53, 54, 78, 399, 49, 7, 245,
+ 182, 82, 38, 406, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199, 200, 78,
+ 85, 81, 58, 59, 37, 38, 39, 40, 300, 80,
+ 66, 79, 278, 77, 280, 281, 52, 53, 54, 80,
+ 7, 79, 78, 79, 80, 81, 52, 53, 54, 62,
+ 63, 64, 65, 66, 52, 53, 54, 301, 71, 72,
+ 73, 54, 81, 76, 78, 391, 82, 52, 53, 54,
+ 77, 77, 1, 77, 3, 4, 5, 6, 7, 8,
+ 77, 10, 11, 12, 82, 331, 77, 16, 77, 77,
+ 19, 20, 21, 22, 340, 131, 81, 26, 27, 28,
+ 29, 30, 78, 32, 33, 34, 35, 36, 52, 53,
+ 54, 357, 41, 42, 43, 44, 45, 46, 81, 48,
+ 78, 50, 52, 53, 54, 77, 55, 85, 86, 87,
+ 80, 80, 52, 53, 54, 80, 3, 81, 67, 68,
+ 69, 80, 52, 53, 54, 74, 75, 80, 407, 78,
+ 79, 81, 81, 335, 83, 84, 85, 86, 87, 88,
+ 1, 407, 82, 4, 5, 6, 7, 8, 77, 10,
+ 11, 12, 82, 77, 77, 16, 77, 19, 20, 21,
+ 22, 52, 53, 54, 26, 81, 39, 40, 78, 30,
+ 77, 32, 33, 34, 35, 36, 52, 53, 54, 77,
+ 41, 42, 43, 44, 45, 46, 77, 48, 26, 50,
+ 52, 53, 54, 66, 55, 52, 53, 54, 71, 72,
+ 73, 44, 357, 76, 21, 81, 67, 68, 69, 213,
+ 64, 64, -1, 74, 75, 77, -1, 78, 79, -1,
+ 81, -1, 83, 84, 85, 86, 87, 88, 1, -1,
+ -1, 4, 5, 6, 7, 8, -1, 10, 11, 12,
+ 52, 53, 54, 16, -1, 52, 53, 54, -1, -1,
+ -1, -1, 37, 38, 39, 40, -1, 30, -1, 32,
+ 33, 34, 35, 36, -1, 77, -1, -1, 41, 42,
+ 43, 44, 45, 46, 81, 48, -1, 50, 63, 64,
+ 65, 66, 55, 52, 53, 54, 71, 72, 73, -1,
+ -1, 76, -1, -1, 67, 68, 69, -1, -1, -1,
+ -1, 74, 75, -1, 77, 78, 79, -1, 77, -1,
+ 83, 84, 85, 86, 87, 88, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 52, 53, 54, 16,
+ 71, 72, 73, -1, -1, 76, -1, 37, 38, 39,
+ 40, -1, -1, 30, -1, 32, 33, 34, 35, 36,
+ -1, 77, -1, -1, 41, 42, 43, 44, 45, 46,
+ -1, 48, -1, 50, 64, 65, 66, -1, 55, -1,
+ -1, 71, 72, 73, -1, -1, 76, -1, -1, -1,
+ 67, 68, 69, 19, 20, 21, 22, 74, 75, -1,
+ 26, 78, 79, -1, -1, -1, 83, 84, 85, 86,
+ 87, 88, 3, 4, 5, 6, 7, 8, -1, 10,
+ 11, 12, 52, 53, 54, 16, 52, 53, 54, -1,
+ -1, -1, 37, 38, 39, 40, -1, -1, -1, 30,
+ -1, 32, 33, 34, 35, 36, -1, 77, -1, -1,
+ 41, 42, 43, 44, 45, 46, -1, 48, -1, 50,
+ 65, 66, -1, -1, 55, -1, 71, 72, 73, -1,
+ -1, 76, -1, -1, -1, -1, 67, 68, 69, 52,
+ 53, 54, -1, 74, 75, -1, -1, 78, 79, 52,
+ 53, 54, 83, 84, 85, 86, 87, 88, 3, 4,
+ 5, 6, 7, 8, 77, 10, 11, 12, 52, 53,
+ 54, 16, -1, -1, 77, -1, -1, -1, 37, 38,
+ 39, 40, -1, -1, -1, 30, -1, 32, 33, 34,
+ 35, 36, -1, 77, -1, -1, 41, 42, 43, 44,
+ 45, 46, -1, 48, -1, 50, 65, 66, -1, -1,
+ 55, -1, 71, 72, 73, -1, -1, 76, -1, -1,
+ -1, -1, 67, 68, 69, 37, -1, 39, 40, 74,
+ 75, -1, -1, 78, 79, -1, -1, -1, 83, 84,
+ 85, 86, 87, 88, 4, 5, 6, 7, 8, -1,
+ 10, 11, 12, 65, 66, -1, 16, -1, -1, 71,
+ 72, 73, -1, -1, 76, 39, 40, -1, -1, -1,
+ 30, -1, 32, 33, 34, 35, 36, -1, -1, -1,
+ -1, 41, 42, 43, 44, 45, 46, -1, 48, -1,
+ 50, 65, 66, -1, -1, 55, -1, 71, 72, 73,
+ -1, -1, 76, -1, -1, -1, -1, 67, 68, 69,
+ -1, -1, -1, -1, 74, 75, -1, -1, 78, 79,
+ -1, 81, -1, 83, 84, 85, 86, 87, 88, 4,
+ 5, 6, 7, 8, -1, 10, 11, 12, 66, -1,
+ -1, 16, -1, 71, 72, 73, -1, -1, 76, -1,
+ -1, -1, -1, -1, -1, 30, -1, 32, 33, 34,
+ 35, 36, -1, -1, -1, -1, 41, 42, 43, 44,
+ 45, 46, -1, 48, -1, 50, -1, -1, -1, -1,
+ 55, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 67, 68, 69, -1, -1, -1, -1, 74,
+ 75, -1, 77, 78, 79, -1, -1, -1, 83, 84,
+ 85, 86, 87, 88, 4, 5, 6, 7, 8, -1,
+ 10, 11, 12, -1, -1, -1, 16, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 30, -1, 32, 33, 34, 35, 36, -1, -1, -1,
+ -1, 41, 42, 43, 44, 45, 46, -1, 48, -1,
+ 50, -1, -1, -1, -1, 55, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 67, 68, 69,
+ -1, -1, -1, -1, 74, 75, -1, -1, 78, 79,
+ -1, -1, 82, 83, 84, 85, 86, 87, 88, 4,
+ 5, 6, 7, 8, -1, 10, 11, 12, -1, -1,
+ -1, 16, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 30, -1, 32, 33, 34,
+ 35, 36, -1, -1, -1, -1, 41, 42, 43, 44,
+ 45, 46, -1, 48, -1, 50, -1, -1, -1, -1,
+ 55, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 67, 68, 69, -1, -1, -1, -1, 74,
+ 75, -1, 77, 78, 79, -1, -1, -1, 83, 84,
+ 85, 86, 87, 88, 4, 5, 6, 7, 8, -1,
+ 10, 11, 12, -1, -1, -1, 16, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 30, -1, 32, 33, 34, 35, 36, -1, -1, -1,
+ -1, 41, 42, 43, 44, 45, 46, -1, 48, -1,
+ 50, -1, -1, -1, -1, 55, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 67, 68, 69,
+ -1, -1, -1, -1, 74, 75, -1, 77, 78, 79,
+ -1, -1, -1, 83, 84, 85, 86, 87, 88, 4,
+ 5, 6, 7, 8, -1, 10, 11, 12, -1, -1,
+ -1, 16, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 30, -1, 32, 33, 34,
+ 35, 36, -1, -1, -1, -1, 41, 42, 43, 44,
+ 45, 46, -1, 48, -1, 50, -1, -1, -1, -1,
+ 55, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 67, 68, 69, -1, -1, -1, -1, 74,
+ 75, -1, 77, 78, 79, -1, -1, -1, 83, 84,
+ 85, 86, 87, 88, 4, 5, 6, 7, 8, -1,
+ 10, 11, 12, -1, -1, -1, 16, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 64, 65, 66, -1, -1, -1, -1, 71, 72, -1,
- -1, 75, 76, -1, -1, 79, 80, 81, 82, 83,
- 84, 85, 4, 5, 6, 7, 8, -1, 10, 11,
- 12, -1, -1, -1, 16, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 27, -1, 29, 30, 31,
- 32, 33, -1, -1, -1, -1, 38, 39, 40, 41,
- 42, 43, -1, 45, -1, 47, -1, -1, -1, -1,
- 52, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 64, 65, 66, -1, -1, -1, -1, 71,
- 72, -1, 74, 75, 76, -1, -1, -1, 80, 81,
- 82, 83, 84, 85, 4, 5, 6, 7, 8, -1,
+ 30, -1, 32, 33, 34, 35, 36, -1, -1, -1,
+ -1, 41, 42, 43, 44, 45, 46, -1, 48, -1,
+ 50, -1, -1, -1, -1, 55, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 67, 68, 69,
+ -1, -1, -1, -1, 74, 75, -1, 77, 78, 79,
+ -1, -1, -1, 83, 84, 85, 86, 87, 88, 4,
+ 5, 6, 7, 8, -1, 10, 11, 12, -1, -1,
+ -1, 16, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 30, -1, 32, 33, 34,
+ 35, 36, -1, -1, -1, -1, 41, 42, 43, 44,
+ 45, 46, -1, 48, -1, 50, -1, -1, -1, -1,
+ 55, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 67, 68, 69, -1, -1, -1, -1, 74,
+ 75, -1, 77, 78, 79, -1, -1, -1, 83, 84,
+ 85, 86, 87, 88, 4, 5, 6, 7, 8, -1,
10, 11, 12, -1, -1, -1, 16, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 27, -1, 29,
- 30, 31, 32, 33, -1, -1, -1, -1, 38, 39,
- 40, 41, 42, 43, -1, 45, -1, 47, -1, -1,
- -1, -1, 52, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 64, 65, 66, -1, -1, -1,
- -1, 71, 72, -1, 74, 75, 76, -1, -1, -1,
- 80, 81, 82, 83, 84, 85, 4, 5, 6, 7,
- 8, -1, 10, 11, 12, -1, -1, -1, 16, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 27,
- -1, 29, 30, 31, 32, 33, -1, -1, -1, -1,
- 38, 39, 40, 41, 42, 43, -1, 45, -1, 47,
- -1, -1, -1, -1, 52, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 64, 65, 66, -1,
- -1, -1, -1, 71, 72, -1, 74, 75, 76, -1,
- -1, -1, 80, 81, 82, 83, 84, 85, 4, 5,
- 6, 7, 8, -1, 10, 11, 12, -1, -1, -1,
- 16, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 27, -1, 29, 30, 31, 32, 33, -1, -1,
- -1, -1, 38, 39, 40, 41, 42, 43, -1, 45,
- -1, 47, -1, -1, -1, -1, 52, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 64, 65,
- 66, -1, -1, -1, -1, 71, 72, -1, 74, 75,
- 76, -1, -1, -1, 80, 81, 82, 83, 84, 85,
- 4, 5, 6, 7, 8, -1, 10, 11, 12, -1,
- -1, -1, 16, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 27, -1, 29, 30, 31, 32, 33,
- -1, -1, -1, -1, 38, 39, 40, 41, 42, 43,
- -1, 45, -1, 47, -1, -1, -1, -1, 52, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 64, 65, 66, -1, -1, -1, -1, 71, 72, -1,
- 74, 75, 76, -1, -1, -1, 80, 81, 82, 83,
- 84, 85, 4, 5, 6, 7, 8, -1, 10, 11,
- 12, -1, -1, -1, 16, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 27, -1, 29, 30, 31,
- 32, 33, -1, -1, -1, -1, 38, 39, 40, 41,
- 42, 43, -1, 45, -1, 47, -1, -1, -1, -1,
- 52, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 64, 65, 66, -1, -1, -1, -1, 71,
- 72, -1, 74, 75, 76, -1, -1, -1, 80, 81,
- 82, 83, 84, 85, 4, 5, 6, 7, 8, -1,
+ 30, -1, 32, 33, 34, 35, 36, -1, -1, -1,
+ -1, 41, 42, 43, 44, 45, 46, -1, 48, -1,
+ 50, -1, -1, -1, -1, 55, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 67, 68, 69,
+ -1, -1, -1, -1, 74, 75, -1, 77, 78, 79,
+ -1, -1, -1, 83, 84, 85, 86, 87, 88, 4,
+ 5, 6, 7, 8, -1, 10, 11, 12, -1, -1,
+ -1, 16, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 30, -1, 32, 33, 34,
+ 35, 36, -1, -1, -1, -1, 41, 42, 43, 44,
+ 45, 46, -1, 48, -1, 50, -1, -1, -1, -1,
+ 55, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 67, 68, 69, -1, -1, -1, -1, 74,
+ 75, -1, 77, 78, 79, -1, -1, -1, 83, 84,
+ 85, 86, 87, 88, 4, 5, 6, 7, 8, -1,
10, 11, 12, -1, -1, -1, 16, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 27, -1, 29,
- 30, 31, 32, 33, -1, -1, -1, -1, 38, 39,
- 40, 41, 42, 43, -1, 45, -1, 47, -1, -1,
- -1, -1, 52, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 64, 65, 66, -1, -1, -1,
- -1, 71, 72, -1, 74, 75, 76, -1, -1, -1,
- 80, 81, 82, 83, 84, 85, 4, 5, 6, 7,
- 8, -1, 10, 11, 12, -1, -1, -1, 16, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 27,
- -1, 29, 30, 31, 32, 33, -1, -1, -1, -1,
- 38, 39, 40, 41, 42, 43, -1, 45, -1, 47,
- -1, -1, -1, -1, 52, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 64, 65, 66, -1,
- -1, -1, 3, 71, 72, -1, -1, 75, 76, -1,
- -1, -1, 80, 81, 82, 83, 84, 85, 19, 20,
- 21, 22, -1, -1, -1, 26, -1, 28, -1, -1,
- -1, -1, -1, 34, 35, 36, 37, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 49, 50,
- 51, -1, 53, 54, 55, 56, 57, 58, 59, 60,
- 61, 62, 63, -1, -1, -1, -1, 68, 69, 70,
- -1, -1, 73, 74, -1, 76, -1, 78, 79, 19,
- 20, 21, 22, -1, -1, -1, 26, -1, 28, -1,
- -1, -1, -1, -1, 34, 35, 36, 37, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 49,
- 50, 51, -1, 53, 54, 55, 56, 57, 58, 59,
- 60, 61, 62, 63, -1, -1, -1, -1, 68, 69,
- 70, -1, -1, 73, 74, 28, -1, -1, 78, 79,
- -1, 34, 35, 36, 37, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 54, 55, 56, 57, 58, 59, 60, 61, 62,
- 63, -1, -1, -1, -1, 68, 69, 70, 28, -1,
- 73, -1, -1, -1, 34, 35, 36, 37, -1, -1,
+ 30, -1, 32, 33, 34, 35, 36, -1, -1, -1,
+ -1, 41, 42, 43, 44, 45, 46, -1, 48, -1,
+ 50, -1, -1, -1, -1, 55, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 67, 68, 69,
+ -1, -1, -1, 3, 74, 75, -1, -1, 78, 79,
+ -1, -1, -1, 83, 84, 85, 86, 87, 88, 19,
+ 20, 21, 22, -1, -1, -1, 26, -1, -1, -1,
+ -1, 31, -1, -1, -1, -1, -1, 37, 38, 39,
+ 40, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 52, 53, 54, -1, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, -1, -1, -1,
+ -1, 71, 72, 73, -1, -1, 76, 77, -1, 79,
+ -1, 81, 82, 19, 20, 21, 22, -1, -1, -1,
+ 26, -1, -1, -1, -1, 31, -1, -1, -1, -1,
+ -1, 37, 38, 39, 40, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 52, 53, 54, -1,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, -1, 354, -1, 356, 71, 72, 73, 360, -1,
+ 76, 77, -1, -1, -1, 81, 82, -1, -1, -1,
+ -1, -1, -1, 375, 376, -1, -1, -1, -1, -1,
+ -1, 383, 384, -1, -1, -1, -1, -1, -1, 31,
+ 392, -1, -1, -1, 396, 37, 38, 39, 40, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 54, 55, -1, 57, 58, 59,
- 60, 61, 62, 63, -1, -1, -1, -1, 68, 69,
- 70, 28, -1, 73, -1, -1, -1, 34, 35, 36,
- 37, -1, -1, -1, -1, -1, -1, -1, 28, -1,
- -1, -1, -1, -1, 34, 35, 36, 37, 55, -1,
- 57, 58, 59, 60, 61, 62, 63, -1, -1, -1,
- -1, 68, 69, 70, -1, -1, 73, 57, 58, 59,
- 60, 61, 62, 63, -1, -1, -1, -1, 68, 69,
- 70, -1, -1, 73
+ -1, 413, 414, -1, -1, 57, 58, 59, 60, 61,
+ 62, 63, 64, 65, 66, -1, -1, -1, -1, 71,
+ 72, 73, 31, -1, 76, -1, -1, -1, 37, 38,
+ 39, 40, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 57, 58,
+ -1, 60, 61, 62, 63, 64, 65, 66, -1, -1,
+ -1, -1, 71, 72, 73, 31, -1, 76, -1, -1,
+ -1, 37, 38, 39, 40, -1, -1, -1, -1, -1,
+ -1, -1, 31, -1, -1, -1, -1, -1, 37, 38,
+ 39, 40, 58, -1, 60, 61, 62, 63, 64, 65,
+ 66, -1, -1, -1, -1, 71, 72, 73, -1, -1,
+ 76, 60, 61, 62, 63, 64, 65, 66, -1, -1,
+ -1, -1, 71, 72, 73, -1, -1, 76
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const unsigned char yystos[] =
{
- 0, 87, 90, 0, 94, 14, 15, 17, 18, 44,
- 93, 109, 110, 112, 113, 122, 123, 116, 114, 4,
- 114, 114, 13, 95, 100, 108, 4, 111, 4, 117,
- 78, 124, 117, 1, 3, 4, 5, 6, 7, 8,
- 10, 11, 12, 16, 19, 20, 21, 22, 26, 27,
- 29, 30, 31, 32, 33, 38, 39, 40, 41, 42,
- 43, 45, 47, 52, 64, 65, 66, 71, 72, 75,
- 76, 78, 80, 81, 82, 83, 84, 85, 88, 96,
- 98, 125, 126, 127, 130, 131, 132, 133, 134, 135,
- 136, 141, 142, 143, 144, 145, 146, 88, 7, 118,
- 4, 118, 89, 4, 9, 88, 142, 147, 147, 75,
- 135, 115, 115, 75, 75, 75, 75, 43, 75, 142,
- 135, 75, 75, 75, 88, 135, 4, 126, 138, 142,
- 147, 147, 4, 88, 135, 142, 78, 125, 4, 135,
- 75, 137, 142, 143, 144, 135, 147, 126, 135, 135,
- 135, 135, 135, 74, 125, 79, 125, 135, 135, 147,
- 147, 147, 147, 25, 99, 78, 19, 20, 21, 22,
- 26, 49, 50, 51, 53, 3, 75, 76, 28, 34,
- 35, 36, 37, 54, 55, 57, 58, 59, 60, 61,
- 62, 63, 68, 69, 70, 73, 75, 3, 76, 3,
- 76, 3, 46, 119, 4, 119, 94, 138, 75, 126,
- 88, 118, 89, 89, 89, 89, 89, 89, 75, 74,
- 74, 125, 125, 139, 147, 126, 75, 75, 77, 78,
- 138, 74, 125, 46, 120, 76, 74, 79, 88, 125,
- 104, 125, 125, 125, 125, 125, 125, 125, 135, 125,
- 74, 125, 125, 135, 135, 135, 135, 135, 135, 135,
- 135, 135, 135, 135, 135, 135, 135, 135, 3, 5,
- 75, 76, 129, 142, 74, 125, 125, 125, 125, 125,
- 125, 7, 78, 88, 121, 138, 121, 77, 139, 74,
- 128, 119, 103, 125, 104, 105, 125, 104, 107, 140,
- 142, 96, 102, 105, 106, 125, 89, 74, 53, 74,
- 125, 74, 125, 74, 125, 77, 74, 7, 125, 76,
- 78, 74, 79, 56, 125, 74, 125, 125, 75, 74,
- 78, 79, 78, 79, 78, 78, 74, 138, 88, 74,
- 74, 74, 74, 75, 74, 78, 105, 74, 74, 74,
- 79, 125, 77, 135, 78, 74, 79, 139, 77, 77,
- 77, 101, 101, 3, 91, 91, 105, 91, 103, 74,
- 79, 77, 74, 91, 91, 92, 23, 24, 97, 97,
- 74, 99, 78, 91, 99, 99, 94, 91, 75, 91,
- 101, 99, 77, 105, 99, 106, 74, 74, 91, 91,
- 97
+ 0, 90, 94, 0, 98, 14, 15, 17, 18, 47,
+ 97, 115, 116, 118, 119, 128, 129, 122, 120, 4,
+ 120, 120, 13, 99, 105, 106, 114, 4, 117, 4,
+ 123, 81, 130, 123, 1, 3, 4, 5, 6, 7,
+ 8, 10, 11, 12, 16, 19, 20, 21, 22, 26,
+ 27, 28, 29, 30, 32, 33, 34, 35, 36, 41,
+ 42, 43, 44, 45, 46, 48, 50, 55, 67, 68,
+ 69, 74, 75, 78, 79, 81, 83, 84, 85, 86,
+ 87, 88, 91, 100, 102, 103, 131, 132, 133, 136,
+ 137, 138, 139, 140, 141, 142, 147, 148, 149, 150,
+ 151, 152, 91, 7, 124, 4, 124, 92, 4, 9,
+ 91, 148, 153, 153, 78, 141, 121, 121, 78, 78,
+ 78, 78, 46, 78, 148, 78, 78, 91, 141, 78,
+ 78, 78, 91, 141, 4, 132, 144, 148, 153, 153,
+ 4, 91, 141, 148, 81, 131, 4, 141, 78, 143,
+ 148, 149, 150, 141, 153, 132, 141, 141, 141, 141,
+ 141, 77, 131, 82, 131, 141, 141, 153, 153, 153,
+ 153, 25, 104, 81, 19, 20, 21, 22, 26, 52,
+ 53, 54, 56, 3, 78, 79, 31, 37, 38, 39,
+ 40, 57, 58, 60, 61, 62, 63, 64, 65, 66,
+ 71, 72, 73, 76, 78, 3, 79, 3, 79, 3,
+ 49, 125, 4, 125, 98, 144, 78, 132, 91, 124,
+ 92, 92, 92, 92, 92, 92, 78, 92, 92, 77,
+ 77, 131, 131, 145, 153, 132, 78, 78, 80, 81,
+ 144, 77, 131, 49, 126, 79, 77, 82, 91, 131,
+ 110, 131, 131, 131, 131, 131, 131, 131, 141, 131,
+ 77, 131, 131, 141, 141, 141, 141, 141, 141, 141,
+ 141, 141, 141, 141, 141, 141, 141, 141, 3, 5,
+ 78, 79, 135, 148, 77, 131, 131, 131, 131, 131,
+ 131, 7, 81, 91, 127, 144, 127, 80, 145, 77,
+ 134, 125, 109, 131, 110, 111, 131, 110, 113, 146,
+ 148, 100, 108, 111, 112, 131, 92, 93, 111, 77,
+ 56, 77, 131, 77, 131, 77, 131, 80, 77, 7,
+ 131, 79, 81, 77, 82, 59, 131, 77, 131, 131,
+ 78, 77, 81, 82, 81, 82, 81, 81, 77, 144,
+ 91, 77, 77, 77, 77, 78, 77, 81, 111, 111,
+ 77, 77, 77, 77, 82, 131, 80, 141, 81, 77,
+ 82, 145, 80, 80, 80, 107, 107, 3, 95, 95,
+ 111, 95, 109, 77, 77, 95, 82, 80, 77, 95,
+ 95, 96, 23, 24, 101, 101, 77, 104, 81, 95,
+ 95, 104, 104, 98, 95, 78, 95, 107, 104, 80,
+ 111, 104, 112, 77, 77, 95, 95, 101
};
diff --git a/perly.y b/perly.y
index 250176ac9e..c81cee35ba 100644
--- a/perly.y
+++ b/perly.y
@@ -41,6 +41,7 @@
%token <pval> LABEL
%token <ival> FORMAT SUB ANONSUB PACKAGE USE
%token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR
+%token <ival> GIVEN WHEN DEFAULT
%token <ival> LOOPEX DOTDOT
%token <ival> FUNC0 FUNC1 FUNC UNIOP LSTOP
%token <ival> RELOP EQOP MULOP ADDOP
@@ -49,7 +50,7 @@
%token COLONATTR
%type <ival> prog decl format startsub startanonsub startformsub mintro
-%type <ival> progstart remember mremember '&' savescope
+%type <ival> progstart remember mremember '&' savescope mydefsv
%type <opval> block mblock lineseq line loop cond else
%type <opval> expr term subscripted scalar ary hsh arylen star amper sideff
%type <opval> argexpr nexpr texpr iexpr mexpr mnexpr miexpr
@@ -57,6 +58,7 @@
%type <opval> formname subname proto subbody cont my_scalar
%type <opval> subattrlist myattrlist mysubrout myattrterm myterm
%type <opval> termbinop termunop anonymous termdo
+%type <opval> switch case
%type <pval> label
%nonassoc PREC_LOW
@@ -109,6 +111,10 @@ remember: /* NULL */ /* start a full lexical scope */
{ $$ = block_start(TRUE); }
;
+mydefsv: /* NULL */ /* lexicalize $_ */
+ { $$ = (I32) allocmy("$_"); }
+ ;
+
progstart:
{
PL_expect = XSTATE; $$ = block_start(TRUE);
@@ -146,6 +152,10 @@ lineseq : /* NULL */
line : label cond
{ $$ = newSTATEOP(0, $1, $2); }
| loop /* loops add their own labels */
+ | switch /* ... and so do switches */
+ { $$ = $1; }
+ | label case
+ { $$ = newSTATEOP(0, $1, $2); }
| label ';'
{ if ($1 != Nullch) {
$$ = newSTATEOP(0, $1, newOP(OP_NULL, 0));
@@ -200,6 +210,14 @@ cond : IF '(' remember mexpr ')' mblock else
newCONDOP(0, $4, scope($6), $7)); }
;
+/* Cases for a switch statement */
+case : WHEN '(' remember mexpr ')' mblock
+ { $$ = block_end($3,
+ newWHENOP($4, scope($6))); }
+ | DEFAULT block
+ { $$ = newWHENOP(0, scope($2)); }
+ ;
+
/* Continue blocks */
cont : /* NULL */
{ $$ = Nullop; }
@@ -253,6 +271,15 @@ loop : label WHILE '(' remember texpr ')' mintro mblock cont
NOLINE, Nullop, $2, $3, 0)); }
;
+/* Switch blocks */
+switch : label GIVEN '(' remember mydefsv mexpr ')' mblock
+ { PL_copline = (line_t) $2;
+ $$ = block_end($4,
+ newSTATEOP(0, $1,
+ newGIVENOP($6, scope($8),
+ (PADOFFSET) $5) )); }
+ ;
+
/* determine whether there are any new my declarations */
mintro : /* NULL */
{ $$ = (PL_min_intro_pending &&
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 5bc399fff2..8b50bd3065 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -491,6 +491,13 @@ to compress something else. See L<perlfunc/pack>.
(F) Only hard references may be blessed. This is how Perl "enforces"
encapsulation of objects. See L<perlobj>.
+=item Can't "break" in a loop topicaizer
+(F) You called C<break>, but you're in a C<foreach> block rather than
+a C<given> block. You probably meant to use C<next> or C<last>.
+
+=item Can't "break" outside a given block
+(F) You called C<break>, but you're not inside a C<given> block.
+
=item Can't call method "%s" in empty package "%s"
(F) You called a method correctly, and it correctly indicated a package
@@ -566,6 +573,10 @@ but then $foo no longer contains a glob.
(F) Certain types of SVs, in particular real symbol table entries
(typeglobs), can't be forced to stop being what they are.
+=item Can't "continue" outside a when block
+(F) You called C<continue>, but you're not inside a C<when>
+or C<default> block.
+
=item Can't create pipe mailbox
(P) An error peculiar to VMS. The process is suffering from exhausted
@@ -1144,6 +1155,12 @@ expression pattern. Trying to do this in ordinary Perl code produces a
value that prints out looking like SCALAR(0xdecaf). Use the $1 form
instead.
+=item Can't use "when" outside a topicalizer
+(F) You have used a when() block that is neither inside a C<foreach>
+loop nor a C<given> block. (Note that this error is issued on exit
+from the C<when> block, so you won't get the error if the match fails,
+or if you use an explicit C<continue>.)
+
=item Can't weaken a nonreference
(F) You attempted to weaken something that was not a reference. Only
diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod
index 2cb16d0149..0a87eceba4 100644
--- a/pod/perlfunc.pod
+++ b/pod/perlfunc.pod
@@ -134,7 +134,7 @@ X<I/O> X<input> X<output> X<dbm>
C<binmode>, C<close>, C<closedir>, C<dbmclose>, C<dbmopen>, C<die>, C<eof>,
C<fileno>, C<flock>, C<format>, C<getc>, C<print>, C<printf>, C<read>,
-C<readdir>, C<rewinddir>, C<seek>, C<seekdir>, C<select>, C<syscall>,
+C<readdir>, C<rewinddir>, C<say>, C<seek>, C<seekdir>, C<select>, C<syscall>,
C<sysread>, C<sysseek>, C<syswrite>, C<tell>, C<telldir>, C<truncate>,
C<warn>, C<write>
@@ -156,6 +156,13 @@ X<control flow>
C<caller>, C<continue>, C<die>, C<do>, C<dump>, C<eval>, C<exit>,
C<goto>, C<last>, C<next>, C<redo>, C<return>, C<sub>, C<wantarray>
+=item Keywords related to switch
+
+C<break>, C<continue>
+
+(These are only available if you enable the "switch" feature.
+See L<feature> and L<perlsyn/"Switch statements">.)
+
=item Keywords related to scoping
C<caller>, C<import>, C<local>, C<my>, C<our>, C<package>, C<use>
@@ -592,6 +599,13 @@ that CLASSNAME is a true value.
See L<perlmod/"Perl Modules">.
+=item break
+
+Break out of a C<given()> block.
+
+This keyword is enabled by the "switch" feature: see L<feature>
+for more information.
+
=item caller EXPR
X<caller> X<call stack> X<stack> X<stack trace>
@@ -890,6 +904,8 @@ L<perlipc/"Sockets: Client/Server Communication">.
=item continue BLOCK
X<continue>
+=item continue
+
C<continue> is actually a flow control statement rather than a function. If
there is a C<continue> BLOCK attached to a BLOCK (typically in a C<while> or
C<foreach>), it is always executed just before the conditional is about to
@@ -917,6 +933,12 @@ Omitting the C<continue> section is semantically equivalent to using an
empty one, logically enough. In that case, C<next> goes directly back
to check the condition at the top of the loop.
+If the "switch" feature is enabled, C<continue> is also a
+function that will break out of the current C<when> or C<default>
+block, and fall through to the next case. See L<feature> and
+L<perlsyn/"Switch statements"> for more information.
+
+
=item cos EXPR
X<cos> X<cosine> X<acos> X<arccosine>
@@ -4666,6 +4688,20 @@ sets C<$!> (errno). If FILENAME is omitted, uses C<$_>.
The substitution operator. See L<perlop>.
+=item say FILEHANDLE LIST
+X<say>
+
+=item say LIST
+
+=item say
+
+Just like C<print>, but implicitly appends a newline.
+C<say LIST> is simply an abbreviation for C<print LIST, "\n">,
+and C<say()> works just like C<print($_, "\n")>.
+
+This keyword is only available when the "say" feature is
+enabled: see L<feature>.
+
=item scalar EXPR
X<scalar> X<context>
diff --git a/pod/perlop.pod b/pod/perlop.pod
index 84cd866b24..db105e32ae 100644
--- a/pod/perlop.pod
+++ b/pod/perlop.pod
@@ -41,7 +41,7 @@ values only, not array values.
left << >>
nonassoc named unary operators
nonassoc < > <= >= lt gt le ge
- nonassoc == != <=> eq ne cmp
+ nonassoc == != <=> eq ne cmp ~~
left &
left | ^
left &&
@@ -430,6 +430,12 @@ argument is stringwise less than, equal to, or greater than the right
argument.
X<cmp>
+Binary "~~" does a smart match between its arguments. Smart matching
+is described in L<perlsyn/"Smart Matching in Detail">.
+This operator is only available if you enable the "~~" feature:
+see L<feature> for more information.
+X<~~>
+
"lt", "le", "ge", "gt" and "cmp" use the collation (sort) order specified
by the current locale if C<use locale> is in effect. See L<perllocale>.
diff --git a/pod/perlsyn.pod b/pod/perlsyn.pod
index c819b94a8d..cc91e31521 100644
--- a/pod/perlsyn.pod
+++ b/pod/perlsyn.pod
@@ -466,8 +466,8 @@ rather than merely terminating the inner one. And it's faster because
Perl executes a C<foreach> statement more rapidly than it would the
equivalent C<for> loop.
-=head2 Basic BLOCKs and Switch Statements
-X<switch> X<block> X<case>
+=head2 Basic BLOCKs
+X<block>
A BLOCK by itself (labeled or not) is semantically equivalent to a
loop that executes once. Thus you can use any of the loop control
@@ -476,7 +476,7 @@ I<NOT> true in C<eval{}>, C<sub{}>, or contrary to popular belief
C<do{}> blocks, which do I<NOT> count as loops.) The C<continue>
block is optional.
-The BLOCK construct is particularly nice for doing case
+The BLOCK construct can be used to emulate case
structures.
SWITCH: {
@@ -486,133 +486,146 @@ structures.
$nothing = 1;
}
-There is no official C<switch> statement in Perl, because there are
-already several ways to write the equivalent.
+Such constructs are quite frequently used, because older versions
+of Perl had no official C<switch> statement.
-However, starting from Perl 5.8 to get switch and case one can use
-the Switch extension and say:
- use Switch;
+=head2 Switch statements
+X<switch> X<case> X<given> X<when> X<default>
-after which one has switch and case. It is not as fast as it could be
-because it's not really part of the language (it's done using source
-filters) but it is available, and it's very flexible.
+Starting from Perl 5.10, you can say
-In addition to the above BLOCK construct, you could write
+ use feature "switch";
- SWITCH: {
- $abc = 1, last SWITCH if /^abc/;
- $def = 1, last SWITCH if /^def/;
- $xyz = 1, last SWITCH if /^xyz/;
- $nothing = 1;
+which enables a switch feature that is closely based on the
+Perl 6 proposal.
+
+The keywords C<given> and C<when> are analogous
+to C<switch> and C<case> in other languages, so the code
+above could be written as
+
+ given($_) {
+ when (/^abc/) { $abc = 1; }
+ when (/^def/) { $def = 1; }
+ when (/^xyz/) { $xyz = 1; }
+ default { $nothing = 1; }
}
-(That's actually not as strange as it looks once you realize that you can
-use loop control "operators" within an expression. That's just the binary
-comma operator in scalar context. See L<perlop/"Comma Operator">.)
+This construct is very flexible and powerful. For example:
-or
+ given() {
- SWITCH: {
- /^abc/ && do { $abc = 1; last SWITCH; };
- /^def/ && do { $def = 1; last SWITCH; };
- /^xyz/ && do { $xyz = 1; last SWITCH; };
- $nothing = 1;
+ xxxx
}
-or formatted so it stands out more as a "proper" C<switch> statement:
+Most of its power comes from the implicit smart matching:
- SWITCH: {
- /^abc/ && do {
- $abc = 1;
- last SWITCH;
- };
-
- /^def/ && do {
- $def = 1;
- last SWITCH;
- };
-
- /^xyz/ && do {
- $xyz = 1;
- last SWITCH;
- };
- $nothing = 1;
- }
+ when($foo) ...
-or
+is exactly equivalent to
- SWITCH: {
- /^abc/ and $abc = 1, last SWITCH;
- /^def/ and $def = 1, last SWITCH;
- /^xyz/ and $xyz = 1, last SWITCH;
- $nothing = 1;
- }
+ when($_ ~~ $foo) ...
-or even, horrors,
-
- if (/^abc/)
- { $abc = 1 }
- elsif (/^def/)
- { $def = 1 }
- elsif (/^xyz/)
- { $xyz = 1 }
- else
- { $nothing = 1 }
-
-A common idiom for a C<switch> statement is to use C<foreach>'s aliasing to make
-a temporary assignment to C<$_> for convenient matching:
-
- SWITCH: for ($where) {
- /In Card Names/ && do { push @flags, '-e'; last; };
- /Anywhere/ && do { push @flags, '-h'; last; };
- /In Rulings/ && do { last; };
- die "unknown value for form variable where: `$where'";
- }
+(though you need to enable the "~~" feature before you
+can use the C<~~> operator directly). In fact C<when(EXPR)>
+is treated as an implicit smart match most of the time. The
+exceptions are that when EXPR is:
+
+=over 4
+
+=item o
+
+a subroutine or method call
+
+=item o
+
+a regular expression match, i.e. C</REGEX/> or C<$foo =~ /REGEX/>,
+or a negated regular expression match C<$foo !~ /REGEX/>.
+
+=item o
+
+a comparison (such as C<$_ E<lt> 10> or C<$x gt "abc">
+
+=item o
+
+C<defined(...)>, C<exists(...)>, or C<eof(...)>
+
+=item o
-Another interesting approach to a switch statement is arrange
-for a C<do> block to return the proper value:
+A negated expression C<!(...)> or C<not (...)>, or a logical
+exclusive-or C<(...) xor (...)>.
- $amode = do {
- if ($flag & O_RDONLY) { "r" } # XXX: isn't this 0?
- elsif ($flag & O_WRONLY) { ($flag & O_APPEND) ? "a" : "w" }
- elsif ($flag & O_RDWR) {
- if ($flag & O_CREAT) { "w+" }
- else { ($flag & O_APPEND) ? "a+" : "r+" }
+=back
+
+then the value of EXPR is used directly as a boolean.
+Furthermore:
+
+=over 4
+
+=item o
+
+If EXPR is C<... && ...> or C<... and ...>, the test
+is applied recursively to both arguments. If I<both>
+arguments pass the test, then the argument is treated
+as boolean.
+
+=item o
+
+If EXPR is C<... || ...> or C<... or ...>, the test
+is applied recursively to the first argument.
+
+=back
+
+These rules look complicated, but usually they will do what
+you want. For example you could write:
+
+ when (/^\d$/ && $_ < 75) { ... }
+
+C<default> behaves exactly like C<when(1 == 1)>, which is
+to say that it always matches.
+
+See L</"Smart matching in detail"> for more information
+on smart matching.
+
+=head3 Fall-through
+
+You can use the C<continue> keyword to fall through from one
+case to the next:
+
+ given($foo) {
+ when (/x/) { print "\$foo contains an 'x'\n"; continue }
+ when (/y/) { print "\$foo contains a 'y'\n" }
+ default { print "\$foo contains neither an 'x' nor a 'y' }
}
- };
-
-Or
-
- print do {
- ($flags & O_WRONLY) ? "write-only" :
- ($flags & O_RDWR) ? "read-write" :
- "read-only";
- };
-
-Or if you are certain that all the C<&&> clauses are true, you can use
-something like this, which "switches" on the value of the
-C<HTTP_USER_AGENT> environment variable.
-
- #!/usr/bin/perl
- # pick out jargon file page based on browser
- $dir = 'http://www.wins.uva.nl/~mes/jargon';
- for ($ENV{HTTP_USER_AGENT}) {
- $page = /Mac/ && 'm/Macintrash.html'
- || /Win(dows )?NT/ && 'e/evilandrude.html'
- || /Win|MSIE|WebTV/ && 'm/MicroslothWindows.html'
- || /Linux/ && 'l/Linux.html'
- || /HP-UX/ && 'h/HP-SUX.html'
- || /SunOS/ && 's/ScumOS.html'
- || 'a/AppendixB.html';
+
+=head3 Switching in a loop
+
+Instead of using C<given()>, you can use a C<foreach()> loop.
+For example, here's one way to count how many times a particular
+string occurs in an array:
+
+ my $count = 0;
+ for (@array) {
+ when ("foo") { ++$count }
}
- print "Location: $dir/$page\015\012\015\012";
+ print "\@array contains $count copies of 'foo'\n";
+
+On exit from the C<when> block, there is an implicit C<next>.
+You can override that with an explicit C<last> if you're only
+interested in the first match.
+
+This doesn't work if you explicitly specify a loop variable,
+as in C<for $item (@array)>. You have to use the default
+variable C<$_>. (You can use C<for my $_ (@array)>.)
+
+=head3 Smart matching in detail
+
+
-That kind of switch statement only works when you know the C<&&> clauses
-will be true. If you don't, the previous C<?:> example should be used.
+=head3 Custom matching via overloading
-You might also consider writing a hash of subroutine references
-instead of synthesizing a C<switch> statement.
+You can change the way that an object is matched by overloading
+the C<'~~'> operator. This trumps the usual smart match semantics.
=head2 Goto
X<goto>
diff --git a/pp.sym b/pp.sym
index 19be260b70..1d1b876181 100644
--- a/pp.sym
+++ b/pp.sym
@@ -35,8 +35,10 @@ Perl_ck_return
Perl_ck_rfun
Perl_ck_rvconst
Perl_ck_sassign
+Perl_ck_say
Perl_ck_select
Perl_ck_shift
+Perl_ck_smartmatch
Perl_ck_sort
Perl_ck_spair
Perl_ck_split
@@ -394,5 +396,13 @@ Perl_pp_setstate
Perl_pp_method_named
Perl_pp_dor
Perl_pp_dorassign
+Perl_pp_entergiven
+Perl_pp_leavegiven
+Perl_pp_enterwhen
+Perl_pp_leavewhen
+Perl_pp_break
+Perl_pp_continue
+Perl_pp_smartmatch
+Perl_pp_say
# ex: set ro:
diff --git a/pp_ctl.c b/pp_ctl.c
index a3f76cf718..2f563ef7a2 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1193,7 +1193,9 @@ static const char * const context_name[] = {
"loop",
"substitution",
"block",
- "format"
+ "format",
+ "given",
+ "when"
};
STATIC I32
@@ -1209,6 +1211,8 @@ S_dopoptolabel(pTHX_ const char *label)
case CXt_FORMAT:
case CXt_EVAL:
case CXt_NULL:
+ case CXt_GIVEN:
+ case CXt_WHEN:
if (ckWARN(WARN_EXITING))
Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting %s via %s",
context_name[CxTYPE(cx)], OP_NAME(PL_op));
@@ -1228,6 +1232,8 @@ S_dopoptolabel(pTHX_ const char *label)
return i;
}
+
+
I32
Perl_dowantarray(pTHX)
{
@@ -1336,6 +1342,45 @@ S_dopoptoloop(pTHX_ I32 startingblock)
return i;
}
+STATIC I32
+S_dopoptogiven(pTHX_ I32 startingblock)
+{
+ I32 i;
+ for (i = startingblock; i >= 0; i--) {
+ register const PERL_CONTEXT *cx = &cxstack[i];
+ switch (CxTYPE(cx)) {
+ default:
+ continue;
+ case CXt_GIVEN:
+ DEBUG_l( Perl_deb(aTHX_ "(Found given #%ld)\n", (long)i));
+ return i;
+ case CXt_LOOP:
+ if (CxFOREACHDEF(cx)) {
+ DEBUG_l( Perl_deb(aTHX_ "(Found foreach #%ld)\n", (long)i));
+ return i;
+ }
+ }
+ }
+ return i;
+}
+
+STATIC I32
+S_dopoptowhen(pTHX_ I32 startingblock)
+{
+ I32 i;
+ for (i = startingblock; i >= 0; i--) {
+ register const PERL_CONTEXT *cx = &cxstack[i];
+ switch (CxTYPE(cx)) {
+ default:
+ continue;
+ case CXt_WHEN:
+ DEBUG_l( Perl_deb(aTHX_ "(Found when #%ld)\n", (long)i));
+ return i;
+ }
+ }
+ return i;
+}
+
void
Perl_dounwind(pTHX_ I32 cxix)
{
@@ -1727,7 +1772,7 @@ PP(pp_enteriter)
register PERL_CONTEXT *cx;
const I32 gimme = GIMME_V;
SV **svp;
- U32 cxtype = CXt_LOOP;
+ U32 cxtype = CXt_LOOP | CXp_FOREACH;
#ifdef USE_ITHREADS
void *iterdata;
#endif
@@ -1760,6 +1805,9 @@ PP(pp_enteriter)
#endif
}
+ if (PL_op->op_private & OPpITER_DEF)
+ cxtype |= CXp_FOR_DEF;
+
ENTER;
PUSHBLOCK(cx, cxtype, SP);
@@ -3388,7 +3436,7 @@ PP(pp_entereval)
{
dVAR; dSP;
register PERL_CONTEXT *cx;
- dPOPss;
+ SV *sv;
const I32 gimme = GIMME_V;
const I32 was = PL_sub_generation;
char tbuf[TYPE_DIGITS(long) + 12];
@@ -3398,6 +3446,12 @@ PP(pp_entereval)
OP *ret;
CV* runcv;
U32 seq;
+ HV *saved_hh = 0;
+
+ if (PL_op->op_private & OPpEVAL_HAS_HH) {
+ saved_hh = (HV*) SvREFCNT_inc(POPs);
+ }
+ sv = POPs;
if (!SvPV_nolen_const(sv))
RETPUSHUNDEF;
@@ -3432,6 +3486,8 @@ PP(pp_entereval)
SAVEDELETE(PL_defstash, safestr, len);
SAVEHINTS();
PL_hints = PL_op->op_targ;
+ if (saved_hh)
+ GvHV(PL_hintgv) = saved_hh;
SAVESPTR(PL_compiling.cop_warnings);
if (specialWARN(PL_curcop->cop_warnings))
PL_compiling.cop_warnings = PL_curcop->cop_warnings;
@@ -3604,6 +3660,610 @@ PP(pp_leavetry)
RETURN;
}
+PP(pp_entergiven)
+{
+ dVAR; dSP;
+ register PERL_CONTEXT *cx;
+ const I32 gimme = GIMME_V;
+
+ ENTER;
+ SAVETMPS;
+
+ if (PL_op->op_targ == 0) {
+ SV **defsv_p = &GvSV(PL_defgv);
+ *defsv_p = newSVsv(POPs);
+ SAVECLEARSV(*defsv_p);
+ }
+ else
+ sv_setsv(PAD_SV(PL_op->op_targ), POPs);
+
+ PUSHBLOCK(cx, CXt_GIVEN, SP);
+ PUSHGIVEN(cx);
+
+ RETURN;
+}
+
+PP(pp_leavegiven)
+{
+ dVAR; dSP;
+ register PERL_CONTEXT *cx;
+ I32 gimme;
+ SV **newsp;
+ PMOP *newpm;
+ SV **mark;
+
+ POPBLOCK(cx,newpm);
+ assert(CxTYPE(cx) == CXt_GIVEN);
+ mark = newsp;
+
+ SP = newsp;
+ PUTBACK;
+
+ PL_curpm = newpm; /* pop $1 et al */
+
+ LEAVE;
+
+ 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);
+ PM_SETRE(matcher, ReREFCNT_inc(re));
+
+ SAVEFREEOP((OP *) matcher);
+ ENTER; SAVETMPS;
+ SAVEOP();
+ return matcher;
+}
+
+STATIC
+bool
+S_matcher_matches_sv(pTHX_ PMOP *matcher, SV *sv)
+{
+ dSP;
+
+ PL_op = (OP *) matcher;
+ XPUSHs(sv);
+ PUTBACK;
+ (void) pp_match();
+ SPAGAIN;
+ return (SvTRUEx(POPs));
+}
+
+STATIC
+void
+S_destroy_matcher(pTHX_ PMOP *matcher)
+{
+ PERL_UNUSED_ARG(matcher);
+ FREETMPS;
+ LEAVE;
+}
+
+/* Do a smart match */
+PP(pp_smartmatch)
+{
+ return do_smartmatch(Nullhv, Nullhv);
+}
+
+/* This version of do_smartmatch() implements the following
+ table of smart matches:
+
+ $a $b Type of Match Implied Matching Code
+ ====== ===== ===================== =============
+ (overloading trumps everything)
+
+ Code[+] Code[+] referential equality match if refaddr($a) == refaddr($b)
+ Any Code[+] scalar sub truth match if $b->($a)
+
+ Hash Hash hash keys identical match if sort(keys(%$a)) ÈeqÇ sort(keys(%$b))
+ Hash Array hash value slice truth match if $a->{any(@$b)}
+ Hash Regex hash key grep match if any(keys(%$a)) =~ /$b/
+ Hash Any hash entry existence match if exists $a->{$b}
+
+ Array Array arrays are identical[*] match if $a È~~Ç $b
+ Array Regex array grep match if any(@$a) =~ /$b/
+ Array Num array contains number match if any($a) == $b
+ Array Any array contains string match if any($a) eq $b
+
+ Any undef undefined match if !defined $a
+ Any Regex pattern match match if $a =~ /$b/
+ Code() Code() results are equal match if $a->() eq $b->()
+ Any Code() simple closure truth match if $b->() (ignoring $a)
+ Num numish[!] numeric equality match if $a == $b
+ Any Str string equality match if $a eq $b
+ Any Num numeric equality match if $a == $b
+
+ Any Any string equality match if $a eq $b
+
+
+ + - this must be a code reference whose prototype (if present) is not ""
+ (subs with a "" prototype are dealt with by the 'Code()' entry lower down)
+ * - if a circular reference is found, we fall back to referential equality
+ ! - either a real number, or a string that looks_like_number()
+
+ */
+STATIC
+OP *
+S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
+{
+ dSP;
+
+ SV *e = TOPs; /* e is for 'expression' */
+ SV *d = TOPm1s; /* d is for 'default', as in PL_defgv */
+ SV *this, *other;
+ MAGIC *mg;
+ regexp *this_regex, *other_regex;
+
+# define NOT_EMPTY_PROTO(cv) (!SvPOK(cv) || SvCUR(cv) == 0)
+
+# define SM_REF(type) ( \
+ (SvROK(d) && (SvTYPE(this = SvRV(d)) == SVt_##type) && (other = e)) \
+ || (SvROK(e) && (SvTYPE(this = SvRV(e)) == SVt_##type) && (other = d)))
+
+# define SM_CV_NEP /* Find a code ref without an empty prototype */ \
+ ((SvROK(d) && (SvTYPE(this = SvRV(d)) == SVt_PVCV) \
+ && NOT_EMPTY_PROTO(this) && (other = e)) \
+ || (SvROK(e) && (SvTYPE(this = SvRV(e)) == SVt_PVCV) \
+ && NOT_EMPTY_PROTO(this) && (other = d)))
+
+# define SM_REGEX ( \
+ (SvROK(d) && SvMAGICAL(this = SvRV(d)) \
+ && (mg = mg_find(this, PERL_MAGIC_qr)) \
+ && (this_regex = (regexp *)mg->mg_obj) \
+ && (other = e)) \
+ || \
+ (SvROK(e) && SvMAGICAL(this = SvRV(e)) \
+ && (mg = mg_find(this, PERL_MAGIC_qr)) \
+ && (this_regex = (regexp *)mg->mg_obj) \
+ && (other = d)) )
+
+
+# define SM_OTHER_REF(type) \
+ (SvROK(other) && SvTYPE(SvRV(other)) == SVt_##type)
+
+# define SM_OTHER_REGEX (SvROK(other) && SvMAGICAL(SvRV(other)) \
+ && (mg = mg_find(SvRV(other), PERL_MAGIC_qr)) \
+ && (other_regex = (regexp *)mg->mg_obj))
+
+
+# define SM_SEEN_THIS(sv) hv_exists_ent(seen_this, \
+ sv_2mortal(newSViv((IV) sv)), 0)
+
+# define SM_SEEN_OTHER(sv) hv_exists_ent(seen_other, \
+ sv_2mortal(newSViv((IV) sv)), 0)
+
+ tryAMAGICbinSET(smart, 0);
+
+ SP -= 2; /* Pop the values */
+
+ /* 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 (SvGMAGICAL(d))
+ d = sv_mortalcopy(d);
+ }
+ else
+ d = &PL_sv_undef;
+
+ assert(e);
+ if (SvGMAGICAL(e))
+ e = sv_mortalcopy(e);
+
+ if (SM_CV_NEP) {
+ I32 c;
+
+ if ( SM_OTHER_REF(PVCV) && NOT_EMPTY_PROTO(SvRV(other)) )
+ {
+ if (this == SvRV(other))
+ RETPUSHYES;
+ else
+ RETPUSHNO;
+ }
+
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ PUSHs(other);
+ PUTBACK;
+ c = call_sv(this, G_SCALAR);
+ SPAGAIN;
+ if (c == 0)
+ PUSHs(&PL_sv_no);
+ else if (SvTEMP(TOPs))
+ SvREFCNT_inc(TOPs);
+ FREETMPS;
+ LEAVE;
+ RETURN;
+ }
+ else if (SM_REF(PVHV)) {
+ if (SM_OTHER_REF(PVHV)) {
+ /* Check that the key-sets are identical */
+ HE *he;
+ HV *other_hv = (HV *) SvRV(other);
+ bool tied = FALSE;
+ bool other_tied = FALSE;
+ U32 this_key_count = 0,
+ other_key_count = 0;
+
+ /* Tied hashes don't know how many keys they have. */
+ if (SvTIED_mg(this, PERL_MAGIC_tied)) {
+ tied = TRUE;
+ }
+ else if (SvTIED_mg((SV *) other_hv, PERL_MAGIC_tied)) {
+ HV * temp = other_hv;
+ other_hv = (HV *) this;
+ this = (SV *) temp;
+ tied = TRUE;
+ }
+ if (SvTIED_mg((SV *) other_hv, PERL_MAGIC_tied))
+ other_tied = TRUE;
+
+ if (!tied && HvUSEDKEYS((HV *) this) != 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 *) this);
+ while ( (he = hv_iternext((HV *) this)) ) {
+ I32 key_len;
+ char *key = hv_iterkey(he, &key_len);
+
+ ++ this_key_count;
+
+ if(!hv_exists(other_hv, key, key_len)) {
+ (void) hv_iterinit((HV *) this); /* 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 (SM_OTHER_REF(PVAV)) {
+ AV *other_av = (AV *) SvRV(other);
+ I32 other_len = av_len(other_av) + 1;
+ I32 i;
+
+ if (HvUSEDKEYS((HV *) this) != other_len)
+ RETPUSHNO;
+
+ for(i = 0; i < other_len; ++i) {
+ SV **svp = av_fetch(other_av, i, FALSE);
+ char *key;
+ STRLEN key_len;
+
+ if (!svp) /* ??? When can this happen? */
+ RETPUSHNO;
+
+ key = SvPV(*svp, key_len);
+ if(!hv_exists((HV *) this, key, key_len))
+ RETPUSHNO;
+ }
+ RETPUSHYES;
+ }
+ else if (SM_OTHER_REGEX) {
+ PMOP *matcher = make_matcher(other_regex);
+ HE *he;
+
+ (void) hv_iterinit((HV *) this);
+ while ( (he = hv_iternext((HV *) this)) ) {
+ if (matcher_matches_sv(matcher, hv_iterkeysv(he))) {
+ (void) hv_iterinit((HV *) this);
+ destroy_matcher(matcher);
+ RETPUSHYES;
+ }
+ }
+ destroy_matcher(matcher);
+ RETPUSHNO;
+ }
+ else {
+ if (hv_exists_ent((HV *) this, other, 0))
+ RETPUSHYES;
+ else
+ RETPUSHNO;
+ }
+ }
+ else if (SM_REF(PVAV)) {
+ if (SM_OTHER_REF(PVAV)) {
+ AV *other_av = (AV *) SvRV(other);
+ if (av_len((AV *) this) != av_len(other_av))
+ RETPUSHNO;
+ else {
+ I32 i;
+ I32 other_len = av_len(other_av);
+
+ if (Nullhv == seen_this) {
+ seen_this = newHV();
+ (void) sv_2mortal((SV *) seen_this);
+ }
+ if (Nullhv == seen_other) {
+ seen_this = newHV();
+ (void) sv_2mortal((SV *) seen_other);
+ }
+ for(i = 0; i <= other_len; ++i) {
+ SV **this_elem = av_fetch((AV *)this, i, FALSE);
+ SV **other_elem = av_fetch(other_av, i, FALSE);
+
+ if (!this_elem || !other_elem) {
+ if (this_elem || other_elem)
+ RETPUSHNO;
+ }
+ else if (SM_SEEN_THIS(*this_elem)
+ || SM_SEEN_OTHER(*other_elem))
+ {
+ if (*this_elem != *other_elem)
+ RETPUSHNO;
+ }
+ else {
+ hv_store_ent(seen_this,
+ sv_2mortal(newSViv((IV) *this_elem)),
+ &PL_sv_undef, 0);
+ hv_store_ent(seen_other,
+ sv_2mortal(newSViv((IV) *other_elem)),
+ &PL_sv_undef, 0);
+ PUSHs(*this_elem);
+ PUSHs(*other_elem);
+
+ PUTBACK;
+ (void) do_smartmatch(seen_this, seen_other);
+ SPAGAIN;
+
+ if (!SvTRUEx(POPs))
+ RETPUSHNO;
+ }
+ }
+ RETPUSHYES;
+ }
+ }
+ else if (SM_OTHER_REGEX) {
+ PMOP *matcher = make_matcher(other_regex);
+ I32 i;
+ I32 this_len = av_len((AV *) this);
+
+ for(i = 0; i <= this_len; ++i) {
+ SV ** svp = av_fetch((AV *)this, i, FALSE);
+ if (svp && matcher_matches_sv(matcher, *svp)) {
+ destroy_matcher(matcher);
+ RETPUSHYES;
+ }
+ }
+ destroy_matcher(matcher);
+ RETPUSHNO;
+ }
+ else if (SvIOK(other) || SvNOK(other)) {
+ I32 i;
+
+ for(i = 0; i <= AvFILL((AV *) this); ++i) {
+ SV ** svp = av_fetch((AV *)this, i, FALSE);
+ if (!svp)
+ continue;
+
+ PUSHs(other);
+ PUSHs(*svp);
+ PUTBACK;
+ if ((PL_curcop->op_private & HINT_INTEGER) == HINT_INTEGER)
+ (void) pp_i_eq();
+ else
+ (void) pp_eq();
+ SPAGAIN;
+ if (SvTRUEx(POPs))
+ RETPUSHYES;
+ }
+ RETPUSHNO;
+ }
+ else if (SvPOK(other)) {
+ I32 i;
+ I32 this_len = av_len((AV *) this);
+
+ for(i = 0; i <= this_len; ++i) {
+ SV ** svp = av_fetch((AV *)this, i, FALSE);
+ if (!svp)
+ continue;
+
+ PUSHs(other);
+ PUSHs(*svp);
+ PUTBACK;
+ (void) pp_seq();
+ SPAGAIN;
+ if (SvTRUEx(POPs))
+ RETPUSHYES;
+ }
+ RETPUSHNO;
+ }
+ }
+ else if (!SvOK(d) || !SvOK(e)) {
+ if (!SvOK(d) && !SvOK(e))
+ RETPUSHYES;
+ else
+ RETPUSHNO;
+ }
+ else if (SM_REGEX) {
+ PMOP *matcher = make_matcher(this_regex);
+
+ PUTBACK;
+ PUSHs(matcher_matches_sv(matcher, other)
+ ? &PL_sv_yes
+ : &PL_sv_no);
+ destroy_matcher(matcher);
+ RETURN;
+ }
+ else if (SM_REF(PVCV)) {
+ I32 c;
+ /* This must be a null-prototyped sub, because we
+ already checked for the other kind. */
+
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ PUTBACK;
+ c = call_sv(this, G_SCALAR);
+ SPAGAIN;
+ if (c == 0)
+ PUSHs(&PL_sv_undef);
+ else if (SvTEMP(TOPs))
+ SvREFCNT_inc(TOPs);
+
+ if (SM_OTHER_REF(PVCV)) {
+ /* This one has to be null-proto'd too.
+ Call both of 'em, and compare the results */
+ PUSHMARK(SP);
+ c = call_sv(SvRV(other), G_SCALAR);
+ SPAGAIN;
+ if (c == 0)
+ PUSHs(&PL_sv_undef);
+ else if (SvTEMP(TOPs))
+ SvREFCNT_inc(TOPs);
+ FREETMPS;
+ LEAVE;
+ PUTBACK;
+ return pp_eq();
+ }
+
+ FREETMPS;
+ LEAVE;
+ RETURN;
+ }
+ else if ( ((SvIOK(d) || SvNOK(d)) && (this = d) && (other = e))
+ || ((SvIOK(e) || SvNOK(e)) && (this = e) && (other = d)) )
+ {
+ if (SvPOK(other) && !looks_like_number(other)) {
+ /* String comparison */
+ PUSHs(d); PUSHs(e);
+ PUTBACK;
+ return pp_seq();
+ }
+ /* Otherwise, numeric comparison */
+ PUSHs(d); PUSHs(e);
+ PUTBACK;
+ if ((PL_curcop->op_private & HINT_INTEGER) == HINT_INTEGER)
+ (void) pp_i_eq();
+ else
+ (void) pp_eq();
+ SPAGAIN;
+ if (SvTRUEx(POPs))
+ RETPUSHYES;
+ else
+ RETPUSHNO;
+ }
+
+ /* As a last resort, use string comparison */
+ PUSHs(d); PUSHs(e);
+ PUTBACK;
+ return pp_seq();
+}
+
+PP(pp_enterwhen)
+{
+ dVAR; dSP;
+ register PERL_CONTEXT *cx;
+ const I32 gimme = GIMME_V;
+
+ /* 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 leavewhen.
+ */
+ if ((0 == (PL_op->op_flags & OPf_SPECIAL)) && !SvTRUEx(POPs))
+ return cLOGOP->op_other->op_next;
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHBLOCK(cx, CXt_WHEN, SP);
+ PUSHWHEN(cx);
+
+ RETURN;
+}
+
+PP(pp_leavewhen)
+{
+ dVAR; dSP;
+ register PERL_CONTEXT *cx;
+ I32 gimme;
+ SV **newsp;
+ PMOP *newpm;
+
+ POPBLOCK(cx,newpm);
+ assert(CxTYPE(cx) == CXt_WHEN);
+
+ SP = newsp;
+ PUTBACK;
+
+ PL_curpm = newpm; /* pop $1 et al */
+
+ LEAVE;
+ return NORMAL;
+}
+
+PP(pp_continue)
+{
+ dVAR;
+ I32 cxix;
+ register PERL_CONTEXT *cx;
+ I32 inner;
+
+ cxix = dopoptowhen(cxstack_ix);
+ if (cxix < 0)
+ DIE(aTHX_ "Can't \"continue\" outside a when block");
+ if (cxix < cxstack_ix)
+ dounwind(cxix);
+
+ /* clear off anything above the scope we're re-entering */
+ inner = PL_scopestack_ix;
+ TOPBLOCK(cx);
+ if (PL_scopestack_ix < inner)
+ leave_scope(PL_scopestack[PL_scopestack_ix]);
+ PL_curcop = cx->blk_oldcop;
+ return cx->blk_givwhen.leave_op;
+}
+
+PP(pp_break)
+{
+ dVAR;
+ I32 cxix;
+ register PERL_CONTEXT *cx;
+ I32 inner;
+
+ cxix = dopoptogiven(cxstack_ix);
+ if (cxix < 0) {
+ if (PL_op->op_flags & OPf_SPECIAL)
+ DIE(aTHX_ "Can't use when() outside a topicalizer");
+ else
+ DIE(aTHX_ "Can't \"break\" outside a given block");
+ }
+ if (CxFOREACH(&cxstack[cxix]) && (0 == (PL_op->op_flags & OPf_SPECIAL)))
+ DIE(aTHX_ "Can't \"break\" in a loop topicalizer");
+
+ if (cxix < cxstack_ix)
+ dounwind(cxix);
+
+ /* clear off anything above the scope we're re-entering */
+ inner = PL_scopestack_ix;
+ TOPBLOCK(cx);
+ if (PL_scopestack_ix < inner)
+ leave_scope(PL_scopestack[PL_scopestack_ix]);
+ PL_curcop = cx->blk_oldcop;
+
+ if (CxFOREACH(cx))
+ return cx->blk_loop.next_op;
+ else
+ return cx->blk_givwhen.leave_op;
+}
+
STATIC OP *
S_doparseform(pTHX_ SV *sv)
{
diff --git a/pp_proto.h b/pp_proto.h
index dddb013eeb..a64e335f61 100644
--- a/pp_proto.h
+++ b/pp_proto.h
@@ -34,8 +34,10 @@ PERL_CKDEF(Perl_ck_return)
PERL_CKDEF(Perl_ck_rfun)
PERL_CKDEF(Perl_ck_rvconst)
PERL_CKDEF(Perl_ck_sassign)
+PERL_CKDEF(Perl_ck_say)
PERL_CKDEF(Perl_ck_select)
PERL_CKDEF(Perl_ck_shift)
+PERL_CKDEF(Perl_ck_smartmatch)
PERL_CKDEF(Perl_ck_sort)
PERL_CKDEF(Perl_ck_spair)
PERL_CKDEF(Perl_ck_split)
@@ -395,5 +397,13 @@ PERL_PPDEF(Perl_pp_setstate)
PERL_PPDEF(Perl_pp_method_named)
PERL_PPDEF(Perl_pp_dor)
PERL_PPDEF(Perl_pp_dorassign)
+PERL_PPDEF(Perl_pp_entergiven)
+PERL_PPDEF(Perl_pp_leavegiven)
+PERL_PPDEF(Perl_pp_enterwhen)
+PERL_PPDEF(Perl_pp_leavewhen)
+PERL_PPDEF(Perl_pp_break)
+PERL_PPDEF(Perl_pp_continue)
+PERL_PPDEF(Perl_pp_smartmatch)
+PERL_PPDEF(Perl_pp_say)
/* ex: set ro: */
diff --git a/proto.h b/proto.h
index f8b64bb23d..6106bb7a44 100644
--- a/proto.h
+++ b/proto.h
@@ -1383,6 +1383,12 @@ PERL_CALLCONV OP* Perl_newFOROP(pTHX_ I32 flags, char* label, line_t forline, OP
__attribute__warn_unused_result__
__attribute__nonnull__(pTHX_5);
+PERL_CALLCONV OP* Perl_newGIVENOP(pTHX_ OP* cond, OP* block, PADOFFSET defsv_off)
+ __attribute__malloc__
+ __attribute__warn_unused_result__
+ __attribute__nonnull__(pTHX_1)
+ __attribute__nonnull__(pTHX_2);
+
PERL_CALLCONV OP* Perl_newLOGOP(pTHX_ I32 optype, I32 flags, OP* left, OP* right)
__attribute__malloc__
__attribute__warn_unused_result__
@@ -1568,6 +1574,11 @@ PERL_CALLCONV OP* Perl_newUNOP(pTHX_ I32 type, I32 flags, OP* first)
__attribute__malloc__
__attribute__warn_unused_result__;
+PERL_CALLCONV OP* Perl_newWHENOP(pTHX_ OP* cond, OP* block)
+ __attribute__malloc__
+ __attribute__warn_unused_result__
+ __attribute__nonnull__(pTHX_2);
+
PERL_CALLCONV OP* Perl_newWHILEOP(pTHX_ I32 flags, I32 debuggable, LOOP* loop, I32 whileline, OP* expr, OP* block, OP* cont, I32 has_my)
__attribute__malloc__
__attribute__warn_unused_result__;
@@ -3016,6 +3027,10 @@ PERL_CALLCONV OP* Perl_ck_sassign(pTHX_ OP *o)
__attribute__warn_unused_result__
__attribute__nonnull__(pTHX_1);
+PERL_CALLCONV OP* Perl_ck_say(pTHX_ OP *o)
+ __attribute__warn_unused_result__
+ __attribute__nonnull__(pTHX_1);
+
PERL_CALLCONV OP* Perl_ck_select(pTHX_ OP *o)
__attribute__warn_unused_result__
__attribute__nonnull__(pTHX_1);
@@ -3124,6 +3139,13 @@ STATIC OP* S_too_many_arguments(pTHX_ OP *o, const char* name)
__attribute__nonnull__(pTHX_1)
__attribute__nonnull__(pTHX_2);
+STATIC bool S_looks_like_bool(pTHX_ OP* o)
+ __attribute__nonnull__(pTHX_1);
+
+STATIC OP* S_newGIVWHENOP(pTHX_ OP* cond, OP *block, I32 enter_opcode, I32 leave_opcode, PADOFFSET entertarg)
+ __attribute__nonnull__(pTHX_2);
+
+STATIC OP* S_ref_array_or_hash(pTHX_ OP* cond);
#endif
#if defined(PL_OP_SLAB_ALLOC)
PERL_CALLCONV void* Perl_Slab_Alloc(pTHX_ int m, size_t sz)
@@ -3265,6 +3287,9 @@ STATIC bool S_num_overflow(NV value, I32 fldsize, I32 frcsize)
STATIC I32 S_dopoptoeval(pTHX_ I32 startingblock)
__attribute__warn_unused_result__;
+STATIC I32 S_dopoptogiven(pTHX_ I32 startingblock)
+ __attribute__warn_unused_result__;
+
STATIC I32 S_dopoptolabel(pTHX_ const char *label)
__attribute__warn_unused_result__
__attribute__nonnull__(pTHX_1);
@@ -3279,6 +3304,9 @@ STATIC I32 S_dopoptosub_at(pTHX_ const PERL_CONTEXT* cxstk, I32 startingblock)
__attribute__warn_unused_result__
__attribute__nonnull__(pTHX_1);
+STATIC I32 S_dopoptowhen(pTHX_ I32 startingblock)
+ __attribute__warn_unused_result__;
+
STATIC void S_save_lines(pTHX_ AV *array, SV *sv)
__attribute__nonnull__(pTHX_2);
@@ -3303,6 +3331,19 @@ STATIC I32 S_run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
__attribute__warn_unused_result__
__attribute__nonnull__(pTHX_2);
+STATIC PMOP* S_make_matcher(pTHX_ regexp* re)
+ __attribute__warn_unused_result__
+ __attribute__nonnull__(pTHX_1);
+
+STATIC bool S_matcher_matches_sv(pTHX_ PMOP* matcher, SV* sv)
+ __attribute__warn_unused_result__
+ __attribute__nonnull__(pTHX_1)
+ __attribute__nonnull__(pTHX_2);
+
+STATIC void S_destroy_matcher(pTHX_ PMOP* matcher)
+ __attribute__nonnull__(pTHX_1);
+
+STATIC OP* S_do_smartmatch(pTHX_ HV* seen_this, HV* seen_other);
#endif
#if defined(PERL_IN_PP_HOT_C) || defined(PERL_DECL_PROT)
@@ -3719,6 +3760,9 @@ STATIC void S_checkcomma(pTHX_ char *s, const char *name, const char *what)
__attribute__nonnull__(pTHX_2)
__attribute__nonnull__(pTHX_3);
+STATIC bool S_feature_is_enabled(pTHX_ char* name, STRLEN namelen)
+ __attribute__nonnull__(pTHX_1);
+
STATIC void S_force_ident(pTHX_ const char *s, int kind)
__attribute__nonnull__(pTHX_1);
diff --git a/t/io/say.t b/t/io/say.t
new file mode 100644
index 0000000000..62cec80237
--- /dev/null
+++ b/t/io/say.t
@@ -0,0 +1,49 @@
+#!./perl
+
+BEGIN {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+}
+
+# Just a few very basic tests cribbed from t/io/print.t,
+# with some minor additions. say is actually compiled to
+# a print opcode, so it's more or less guaranteed to behave
+# the same way as print in any case.
+
+use strict 'vars';
+eval 'use Errno';
+die $@ if $@ and !$ENV{PERL_CORE_MINITEST};
+
+use feature "say";
+
+say "1..11";
+
+my $foo = 'STDOUT';
+say $foo "ok 1";
+
+say "ok 2\n","ok 3\n","ok 4";
+say STDOUT "ok 5";
+
+open(FOO,">-");
+say FOO "ok 6";
+
+open(my $bar,">-");
+say $bar "ok 7";
+
+say {"STDOUT"} "ok 8";
+
+if (!exists &Errno::EBADF) {
+ print "ok 9 # skipped: no EBADF\n";
+} else {
+ $! = 0;
+ no warnings 'unopened';
+ say NONEXISTENT "foo";
+ print "not " if ($! != &Errno::EBADF);
+ say "ok 9";
+}
+
+$_ = "ok 10";
+say;
+
+$_ = "ok 11";
+say STDOUT;
diff --git a/t/lib/feature/nonesuch b/t/lib/feature/nonesuch
new file mode 100644
index 0000000000..1de44f621b
--- /dev/null
+++ b/t/lib/feature/nonesuch
@@ -0,0 +1,12 @@
+Test that non-existent features fail as expected.
+
+__END__
+use feature "nonesuch";
+EXPECT
+OPTIONS regex
+^Feature "nonesuch" is not supported by Perl [v0-9.]+ at - line 1
+########
+no feature "nonesuch";
+EXPECT
+OPTIONS regex
+^Feature "nonesuch" is not supported by Perl [v0-9.]+ at - line 1
diff --git a/t/lib/feature/say b/t/lib/feature/say
new file mode 100644
index 0000000000..4b507e6d57
--- /dev/null
+++ b/t/lib/feature/say
@@ -0,0 +1,64 @@
+Check the lexical scoping of the say keyword.
+(The actual behaviour is tested in t/op/say.t)
+
+__END__
+# No say; should be a syntax error.
+use warnings;
+say "Hello", "world";
+EXPECT
+Unquoted string "say" may clash with future reserved word at - line 3.
+String found where operator expected at - line 3, near "say "Hello""
+ (Do you need to predeclare say?)
+syntax error at - line 3, near "say "Hello""
+Execution of - aborted due to compilation errors.
+########
+# With say, should work
+use warnings;
+use feature "say";
+say "Hello", "world";
+EXPECT
+Helloworld
+########
+# With say, should work in eval too
+use warnings;
+use feature "say";
+eval q(say "Hello", "world");
+EXPECT
+Helloworld
+########
+# feature out of scope; should be a syntax error.
+use warnings;
+{ use feature 'say'; }
+say "Hello", "world";
+EXPECT
+Unquoted string "say" may clash with future reserved word at - line 4.
+String found where operator expected at - line 4, near "say "Hello""
+ (Do you need to predeclare say?)
+syntax error at - line 4, near "say "Hello""
+Execution of - aborted due to compilation errors.
+########
+# 'no feature' should work
+use warnings;
+use feature 'say';
+say "Hello", "world";
+no feature;
+say "Hello", "world";
+EXPECT
+Unquoted string "say" may clash with future reserved word at - line 6.
+String found where operator expected at - line 6, near "say "Hello""
+ (Do you need to predeclare say?)
+syntax error at - line 6, near "say "Hello""
+Execution of - aborted due to compilation errors.
+########
+# 'no feature "say"' should work too
+use warnings;
+use feature 'say';
+say "Hello", "world";
+no feature 'say';
+say "Hello", "world";
+EXPECT
+Unquoted string "say" may clash with future reserved word at - line 6.
+String found where operator expected at - line 6, near "say "Hello""
+ (Do you need to predeclare say?)
+syntax error at - line 6, near "say "Hello""
+Execution of - aborted due to compilation errors.
diff --git a/t/lib/feature/smartmatch b/t/lib/feature/smartmatch
new file mode 100644
index 0000000000..16ea7f8a92
--- /dev/null
+++ b/t/lib/feature/smartmatch
@@ -0,0 +1,45 @@
+Check the lexical scoping of the switch keywords.
+(The actual behaviour is tested in t/op/smartmatch.t)
+
+__END__
+# No ~~; should be a syntax error.
+use warnings;
+print +(2 ~~ 2);
+EXPECT
+syntax error at - line 3, near "2 ~"
+Execution of - aborted due to compilation errors.
+########
+# With ~~, should work
+use warnings;
+use feature "~~";
+print +(2 ~~ 2);
+EXPECT
+1
+########
+# ~~ out of scope; should be a syntax error.
+use warnings;
+{ use feature '~~'; }
+print +(2 ~~ 2);
+EXPECT
+syntax error at - line 4, near "2 ~"
+Execution of - aborted due to compilation errors.
+########
+# 'no feature' should work
+use warnings;
+use feature '~~';
+print +(2 ~~ 2), "\n";
+no feature;
+print +(2 ~~ 2), "\n";
+EXPECT
+syntax error at - line 6, near "2 ~"
+Execution of - aborted due to compilation errors.
+########
+# 'no feature "~~"' should work too
+use warnings;
+use feature '~~';
+print +(2 ~~ 2), "\n";
+no feature "~~";
+print +(2 ~~ 2), "\n";
+EXPECT
+syntax error at - line 6, near "2 ~"
+Execution of - aborted due to compilation errors.
diff --git a/t/lib/feature/switch b/t/lib/feature/switch
new file mode 100644
index 0000000000..022cbd1761
--- /dev/null
+++ b/t/lib/feature/switch
@@ -0,0 +1,158 @@
+Check the lexical scoping of the switch keywords.
+(The actual behaviour is tested in t/op/switch.t)
+
+__END__
+# No switch; given should be a bareword.
+use warnings;
+print STDOUT given;
+EXPECT
+Unquoted string "given" may clash with future reserved word at - line 3.
+given
+########
+# No switch; when should be a bareword.
+use warnings;
+print STDOUT when;
+EXPECT
+Unquoted string "when" may clash with future reserved word at - line 3.
+when
+########
+# No switch; default should be a bareword.
+use warnings;
+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;
+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
+syntax error at - line 2, near "STDOUT continue"
+Execution of - aborted due to compilation errors.
+########
+# Use switch; so given is a keyword
+use feature 'switch';
+given("okay\n") { print }
+EXPECT
+okay
+########
+# Use switch; so when is a keyword
+use feature 'switch';
+given(1) { when(1) { print "okay" } }
+EXPECT
+okay
+########
+# Use switch; so default is a keyword
+use feature 'switch';
+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.
+########
+# Use switch; so continue is a keyword
+use feature 'switch';
+continue;
+EXPECT
+Can't "continue" outside a when block at - line 3.
+########
+# switch out of scope; given should be a bareword.
+use warnings;
+{ use feature 'switch';
+ given (1) {print "Okay here\n";}
+}
+print STDOUT given;
+EXPECT
+Unquoted string "given" may clash with future reserved word at - line 6.
+Okay here
+given
+########
+# switch out of scope; when should be a bareword.
+use warnings;
+{ use feature 'switch';
+ given (1) { when(1) {print "Okay here\n";} }
+}
+print STDOUT when;
+EXPECT
+Unquoted string "when" may clash with future reserved word at - line 6.
+Okay here
+when
+########
+# switch out of scope; default should be a bareword.
+use warnings;
+{ 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;
+{ use feature 'switch';
+ given (1) { break }
+}
+print STDOUT break;
+EXPECT
+Unquoted string "break" may clash with future reserved word at - line 6.
+break
+########
+# switch out of scope; continue should not work
+{ use feature 'switch';
+ given (1) { default {continue} }
+}
+print STDOUT continue;
+EXPECT
+syntax error at - line 5, near "STDOUT continue"
+Execution of - aborted due to compilation errors.
+########
+# C<no feature 'switch'> should work
+use warnings;
+use feature 'switch';
+given (1) { when(1) {print "Okay here\n";} }
+no feature 'switch';
+print STDOUT when;
+EXPECT
+Unquoted string "when" may clash with future reserved word at - line 6.
+Okay here
+when
+########
+# C<no feature> should work too
+use warnings;
+use feature 'switch';
+given (1) { when(1) {print "Okay here\n";} }
+no feature;
+print STDOUT when;
+EXPECT
+Unquoted string "when" may clash with future reserved word at - line 6.
+Okay here
+when
+########
+# Without the feature, no 'Unambiguous use of' warning:
+use warnings;
+@break = ($break = "break");
+print ${break}, ${break[0]};
+EXPECT
+breakbreak
+########
+# With the feature, we get an 'Unambiguous use of' warning:
+use warnings;
+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/op/cproto.t b/t/op/cproto.t
index d37118e045..3f3e871fa8 100644
--- a/t/op/cproto.t
+++ b/t/op/cproto.t
@@ -47,7 +47,7 @@ close (;*)
closedir (*)
cmp unknown
connect (*$)
-continue unknown
+continue ()
cos (;$)
crypt ($$)
dbmclose (\%)
diff --git a/t/op/smartmatch.t b/t/op/smartmatch.t
new file mode 100644
index 0000000000..6275f40b0f
--- /dev/null
+++ b/t/op/smartmatch.t
@@ -0,0 +1,163 @@
+#!./perl
+
+BEGIN {
+ chdir 't';
+ @INC = '../lib';
+ require './test.pl';
+}
+use strict;
+
+use Tie::Array;
+use Tie::Hash;
+
+# The feature mechanism is tested in t/lib/feature/smartmatch:
+# This file tests the semantics of the operator, without worrying
+# about feature issues such as scoping etc.
+
+# Predeclare vars used in the tests:
+my $deep1 = []; push @$deep1, \$deep1;
+my $deep2 = []; push @$deep2, \$deep2;
+
+{my $const = "a constant"; sub a_const () {$const}}
+
+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;
+
+# Load and run the tests
+my @tests = map [chomp and split /\t+/, $_, 3], grep !/^#/ && /\S/, <DATA>;
+plan tests => 2 * @tests;
+
+for my $test (@tests) {
+ my ($yn, $left, $right) = @$test;
+
+ match_test($yn, $left, $right);
+ match_test($yn, $right, $left);
+}
+
+sub match_test {
+ my ($yn, $left, $right) = @_;
+
+ die "Bad test spec: ($yn, $left, $right)"
+ unless $yn eq "" || $yn eq "!";
+
+ my $tstr = "$left ~~ $right";
+
+ my $res;
+ {
+ use feature "~~";
+ $res = eval $tstr // ""; #/ <- fix syntax colouring
+ }
+
+ die $@ if $@ ne "";
+ ok( ($yn =~ /!/ xor $res), "$tstr: $res");
+}
+
+
+
+sub foo {}
+sub bar {2}
+sub fatal {die}
+
+sub a_const() {die if @_; "a constant"}
+sub b_const() {die if @_; "a constant"}
+
+__DATA__
+# CODE ref against argument
+# - arg is code ref
+ \&foo \&foo
+! \&foo sub {}
+! \&foo \&bar
+
+# - arg is not code ref
+ 1 sub{shift}
+! 0 sub{shift}
+ 1 sub{scalar @_}
+ [] \&bar
+ {} \&bar
+ qr// \&bar
+
+# - null-prototyped subs
+ a_const "a constant"
+ a_const a_const
+ a_const b_const
+
+# 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
+
+# - an array ref
+ \%:: [keys %main::]
+! \%:: []
+ {"" => 1} [undef]
+
+# - a regex
+ {foo => 1} qr/^(fo[ox])$/
+! +{0..100} qr/[13579]$/
+
+# - a string
+ +{foo => 1, bar => 2} "foo"
+! +{foo => 1, bar => 2} "baz"
+
+
+# ARRAY ref against:
+# - another array ref
+ [] []
+! [] [1]
+ [["foo"], ["bar"]] [qr/o/, qr/a/]
+ ["foo", "bar"] [qr/o/, qr/a/]
+ $deep1 $deep1
+! $deep1 $deep2
+
+ \@nums \@tied_nums
+
+# - a regex
+ [qw(foo bar baz quux)] qr/x/
+! [qw(foo bar baz quux)] qr/y/
+
+# - a number
+ [qw(1foo 2bar)] 2
+
+# - a string
+! [qw(1foo 2bar)] "2"
+
+# Number against number
+ 2 2
+! 2 3
+
+# Number against string
+ 2 "2"
+ 2 "2.0"
+! 2 "2bananas"
+! 2_3 "2_3"
+
+# Regex against string
+ qr/x/ "x"
+! qr/y/ "x"
+
+# Regex against number
+ 12345 qr/3/
+
+
+# Test the implicit referencing
+ @nums 7
+ @nums \@nums
+! @nums \\@nums
+ @nums [1..10]
+! @nums [0..9]
+
+ %hash "foo"
+ %hash /bar/
diff --git a/t/op/switch.t b/t/op/switch.t
new file mode 100644
index 0000000000..fc88a13956
--- /dev/null
+++ b/t/op/switch.t
@@ -0,0 +1,801 @@
+#!./perl
+
+BEGIN {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+}
+
+use strict;
+use warnings;
+
+use Test::More tests => 107;
+
+# The behaviour of the feature pragma should be tested by lib/switch.t
+# using the tests in t/lib/switch/*. This file tests the behaviour of
+# the switch ops themselves.
+
+
+use feature 'switch';
+no warnings "numeric";
+
+eval { continue };
+like($@, qr/^Can't "continue" outside/, "continue outside");
+
+eval { break };
+like($@, qr/^Can't "break" outside/, "break outside");
+
+# Scoping rules
+
+{
+ my $x = "foo";
+ given(my $x = "bar") {
+ is($x, "bar", "given scope starts");
+ }
+ is($x, "foo", "given scope ends");
+}
+
+sub be_true {1}
+
+given(my $x = "foo") {
+ when(be_true(my $x = "bar")) {
+ is($x, "bar", "given scope starts");
+ }
+ is($x, "foo", "given scope ends");
+}
+
+$_ = "outside";
+given("inside") { check_outside1() }
+sub check_outside1 { is($_, "outside", "\$_ lexically scoped") }
+
+{
+ my $_ = "outside";
+ given("inside") { check_outside2() }
+ sub check_outside2 {
+ is($_, "outside", "\$_ lexically scoped (lexical \$_)")
+ }
+}
+
+# Basic string/numeric comparisons and control flow
+
+{
+ my $ok = 0;
+ given(3) {
+ when(2) { $ok = 0; }
+ when(3) { $ok = 1; }
+ when(4) { $ok = 0; }
+ default { $ok = 0; }
+ }
+ ok($ok, "numeric comparison");
+}
+
+{
+ my $ok = 0;
+ use integer;
+ given(3.14159265) {
+ when(2) { $ok = 0; }
+ when(3) { $ok = 1; }
+ when(4) { $ok = 0; }
+ default { $ok = 0; }
+ }
+ ok($ok, "integer comparison");
+}
+
+{
+ my ($ok1, $ok2) = (0, 0);
+ given(3) {
+ when(3.1) { $ok1 = 0; }
+ when(3.0) { $ok1 = 1; continue }
+ when("3.0") { $ok2 = 1; }
+ default { $ok2 = 0; }
+ }
+ ok($ok1, "more numeric (pt. 1)");
+ ok($ok2, "more numeric (pt. 2)");
+}
+
+{
+ my $ok = 0;
+ given("c") {
+ when("b") { $ok = 0; }
+ when("c") { $ok = 1; }
+ when("d") { $ok = 0; }
+ default { $ok = 0; }
+ }
+ ok($ok, "string comparison");
+}
+
+{
+ my $ok = 0;
+ given("c") {
+ when("b") { $ok = 0; }
+ when("c") { $ok = 0; continue }
+ when("c") { $ok = 1; }
+ default { $ok = 0; }
+ }
+ ok($ok, "simple continue");
+}
+
+# Definedness
+{
+ my $ok = 1;
+ given (0) { when(undef) {$ok = 0} }
+ ok($ok, "Given(0) when(undef)");
+}
+{
+ my $undef;
+ my $ok = 1;
+ given (0) { when($undef) {$ok = 0} }
+ ok($ok, 'Given(0) when($undef)');
+}
+{
+ my $undef;
+ my $ok = 0;
+ given (0) { when($undef++) {$ok = 1} }
+ ok($ok, "Given(0) when($undef++)");
+}
+{
+ my $ok = 1;
+ given (undef) { when(0) {$ok = 0} }
+ ok($ok, "Given(undef) when(0)");
+}
+{
+ my $undef;
+ my $ok = 1;
+ given ($undef) { when(0) {$ok = 0} }
+ ok($ok, 'Given($undef) when(0)');
+}
+########
+{
+ my $ok = 1;
+ given ("") { when(undef) {$ok = 0} }
+ ok($ok, 'Given("") when(undef)');
+}
+{
+ my $undef;
+ my $ok = 1;
+ given ("") { when($undef) {$ok = 0} }
+ ok($ok, 'Given("") when($undef)');
+}
+{
+ my $ok = 1;
+ given (undef) { when("") {$ok = 0} }
+ ok($ok, 'Given(undef) when("")');
+}
+{
+ my $undef;
+ my $ok = 1;
+ given ($undef) { when("") {$ok = 0} }
+ ok($ok, 'Given($undef) when("")');
+}
+########
+{
+ my $ok = 0;
+ given (undef) { when(undef) {$ok = 1} }
+ ok($ok, "Given(undef) when(undef)");
+}
+{
+ my $undef;
+ my $ok = 0;
+ given (undef) { when($undef) {$ok = 1} }
+ ok($ok, 'Given(undef) when($undef)');
+}
+{
+ my $undef;
+ my $ok = 0;
+ given ($undef) { when(undef) {$ok = 1} }
+ ok($ok, 'Given($undef) when(undef)');
+}
+{
+ my $undef;
+ my $ok = 0;
+ given ($undef) { when($undef) {$ok = 1} }
+ ok($ok, 'Given($undef) when($undef)');
+}
+
+
+# Regular expressions
+{
+ my ($ok1, $ok2) = 0;
+ given("Hello, world!") {
+ when(/lo/)
+ { $ok1 = 1; continue}
+ when(/no/)
+ { $ok1 = 0; continue}
+ when(/^(Hello,|Goodbye cruel) world[!.?]/)
+ { $ok2 = 1; continue}
+ when(/^(Hello cruel|Goodbye,) world[!.?]/)
+ { $ok2 = 0; continue}
+ }
+ ok($ok1, "regex 1");
+ ok($ok2, "regex 2");
+}
+
+# Comparisons
+{
+ my $test = "explicit numeric comparison (<)";
+ my $twenty_five = 25;
+ given($twenty_five) {
+ when ($_ < 10) { fail($test) }
+ when ($_ < 20) { fail($test) }
+ when ($_ < 30) { pass($test) }
+ when ($_ < 40) { fail($test) }
+ default { fail($test) }
+ }
+}
+
+{
+ use integer;
+ my $test = "explicit numeric comparison (integer <)";
+ my $twenty_five = 25;
+ given($twenty_five) {
+ when ($_ < 10) { fail($test) }
+ when ($_ < 20) { fail($test) }
+ when ($_ < 30) { pass($test) }
+ when ($_ < 40) { fail($test) }
+ default { fail($test) }
+ }
+}
+
+{
+ my $test = "explicit numeric comparison (<=)";
+ my $twenty_five = 25;
+ given($twenty_five) {
+ when ($_ <= 10) { fail($test) }
+ when ($_ <= 20) { fail($test) }
+ when ($_ <= 30) { pass($test) }
+ when ($_ <= 40) { fail($test) }
+ default { fail($test) }
+ }
+}
+
+{
+ use integer;
+ my $test = "explicit numeric comparison (integer <=)";
+ my $twenty_five = 25;
+ given($twenty_five) {
+ when ($_ <= 10) { fail($test) }
+ when ($_ <= 20) { fail($test) }
+ when ($_ <= 30) { pass($test) }
+ when ($_ <= 40) { fail($test) }
+ default { fail($test) }
+ }
+}
+
+
+{
+ my $test = "explicit numeric comparison (>)";
+ my $twenty_five = 25;
+ given($twenty_five) {
+ when ($_ > 40) { fail($test) }
+ when ($_ > 30) { fail($test) }
+ when ($_ > 20) { pass($test) }
+ when ($_ > 10) { fail($test) }
+ default { fail($test) }
+ }
+}
+
+{
+ my $test = "explicit numeric comparison (>=)";
+ my $twenty_five = 25;
+ given($twenty_five) {
+ when ($_ >= 40) { fail($test) }
+ when ($_ >= 30) { fail($test) }
+ when ($_ >= 20) { pass($test) }
+ when ($_ >= 10) { fail($test) }
+ default { fail($test) }
+ }
+}
+
+{
+ use integer;
+ my $test = "explicit numeric comparison (integer >)";
+ my $twenty_five = 25;
+ given($twenty_five) {
+ when ($_ > 40) { fail($test) }
+ when ($_ > 30) { fail($test) }
+ when ($_ > 20) { pass($test) }
+ when ($_ > 10) { fail($test) }
+ default { fail($test) }
+ }
+}
+
+{
+ use integer;
+ my $test = "explicit numeric comparison (integer >=)";
+ my $twenty_five = 25;
+ given($twenty_five) {
+ when ($_ >= 40) { fail($test) }
+ when ($_ >= 30) { fail($test) }
+ when ($_ >= 20) { pass($test) }
+ when ($_ >= 10) { fail($test) }
+ default { fail($test) }
+ }
+}
+
+
+{
+ my $test = "explicit string comparison (lt)";
+ my $twenty_five = "25";
+ given($twenty_five) {
+ when ($_ lt "10") { fail($test) }
+ when ($_ lt "20") { fail($test) }
+ when ($_ lt "30") { pass($test) }
+ when ($_ lt "40") { fail($test) }
+ default { fail($test) }
+ }
+}
+
+{
+ my $test = "explicit string comparison (le)";
+ my $twenty_five = "25";
+ given($twenty_five) {
+ when ($_ le "10") { fail($test) }
+ when ($_ le "20") { fail($test) }
+ when ($_ le "30") { pass($test) }
+ when ($_ le "40") { fail($test) }
+ default { fail($test) }
+ }
+}
+
+{
+ my $test = "explicit string comparison (gt)";
+ my $twenty_five = 25;
+ given($twenty_five) {
+ when ($_ ge "40") { fail($test) }
+ when ($_ ge "30") { fail($test) }
+ when ($_ ge "20") { pass($test) }
+ when ($_ ge "10") { fail($test) }
+ default { fail($test) }
+ }
+}
+
+{
+ my $test = "explicit string comparison (ge)";
+ my $twenty_five = 25;
+ given($twenty_five) {
+ when ($_ ge "40") { fail($test) }
+ when ($_ ge "30") { fail($test) }
+ when ($_ ge "20") { pass($test) }
+ when ($_ ge "10") { fail($test) }
+ default { fail($test) }
+ }
+}
+
+# Make sure it still works with a lexical $_:
+{
+ my $_;
+ my $test = "explicit comparison with lexical \$_";
+ my $twenty_five = 25;
+ given($twenty_five) {
+ when ($_ ge "40") { fail($test) }
+ when ($_ ge "30") { fail($test) }
+ when ($_ ge "20") { pass($test) }
+ when ($_ ge "10") { fail($test) }
+ default { fail($test) }
+ }
+}
+
+# Optimized-away comparisons
+{
+ my $ok = 0;
+ given(23) {
+ when (2 + 2 == 4) { $ok = 1; continue }
+ when (2 + 2 == 5) { $ok = 0 }
+ }
+ ok($ok, "Optimized-away comparison");
+}
+
+# File tests
+# (How to be both thorough and portable? Pinch a few ideas
+# from t/op/filetest.t. We err on the side of portability for
+# the time being.)
+
+{
+ my ($ok_d, $ok_f, $ok_r);
+ given("op") {
+ 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");
+ ok($ok_r, "Filetest -r");
+}
+
+# Sub and method calls
+sub bar {"bar"}
+{
+ my $ok = 0;
+ given("foo") {
+ when(bar()) {$ok = 1}
+ }
+ ok($ok, "Sub call acts as boolean")
+}
+
+{
+ my $ok = 0;
+ given("foo") {
+ when(main->bar()) {$ok = 1}
+ }
+ ok($ok, "Class-method call acts as boolean")
+}
+
+{
+ my $ok = 0;
+ my $obj = bless [];
+ given("foo") {
+ when($obj->bar()) {$ok = 1}
+ }
+ ok($ok, "Object-method call acts as boolean")
+}
+
+# Other things that should not be smart matched
+{
+ my $ok = 0;
+ given(0) {
+ when(eof(DATA)) {
+ $ok = 1;
+ }
+ }
+ ok($ok, "eof() not smartmatched");
+}
+
+{
+ my $ok = 0;
+ my %foo = ("bar", 0);
+ given(0) {
+ when(exists $foo{bar}) {
+ $ok = 1;
+ }
+ }
+ ok($ok, "exists() not smartmatched");
+}
+
+{
+ my $ok = 0;
+ given(0) {
+ when(defined $ok) {
+ $ok = 1;
+ }
+ }
+ ok($ok, "defined() not smartmatched");
+}
+
+{
+ my $ok = 1;
+ given("foo") {
+ when((1 == 1) && "bar") {
+ $ok = 0;
+ }
+ when((1 == 1) && $_ eq "foo") {
+ $ok = 2;
+ }
+ }
+ is($ok, 2, "((1 == 1) && \"bar\") not smartmatched");
+}
+
+{
+ my $ok = 1;
+ given(0) {
+ when((1 == $ok) || "foo") {
+ $ok = 0;
+ }
+ }
+ ok($ok, '((1 == $ok) || "foo") not smartmatched');
+}
+
+
+# Make sure we aren't invoking the get-magic more than once
+
+{ # A helper class to count the number of accesses.
+ package FetchCounter;
+ sub TIESCALAR {
+ my ($class) = @_;
+ bless {value => undef, count => 0}, $class;
+ }
+ sub STORE {
+ my ($self, $val) = @_;
+ $self->{count} = 0;
+ $self->{value} = $val;
+ }
+ sub FETCH {
+ my ($self) = @_;
+ # Avoid pre/post increment here
+ $self->{count} = 1 + $self->{count};
+ $self->{value};
+ }
+ sub count {
+ my ($self) = @_;
+ $self->{count};
+ }
+}
+
+my $f = tie my $v, "FetchCounter";
+
+{ my $test_name = "Only one FETCH (in given)";
+ my $ok = 0;
+ given($v = 23) {
+ when(undef) {}
+ when(sub{0}->()) {}
+ when(21) {}
+ when("22") {}
+ when(23) {$ok = 1}
+ when(/24/) {$ok = 0}
+ }
+ ok($ok, "precheck: $test_name");
+ is($f->count(), 1, $test_name);
+}
+
+{ my $test_name = "Only one FETCH (numeric when)";
+ my $ok = 0;
+ $v = 23;
+ is($f->count(), 0, "Sanity check: $test_name");
+ given(23) {
+ when(undef) {}
+ when(sub{0}->()) {}
+ when(21) {}
+ when("22") {}
+ when($v) {$ok = 1}
+ when(/24/) {$ok = 0}
+ }
+ ok($ok, "precheck: $test_name");
+ is($f->count(), 1, $test_name);
+}
+
+{ my $test_name = "Only one FETCH (string when)";
+ my $ok = 0;
+ $v = "23";
+ is($f->count(), 0, "Sanity check: $test_name");
+ given("23") {
+ when(undef) {}
+ when(sub{0}->()) {}
+ when("21") {}
+ when("22") {}
+ when($v) {$ok = 1}
+ when(/24/) {$ok = 0}
+ }
+ ok($ok, "precheck: $test_name");
+ is($f->count(), 1, $test_name);
+}
+
+{ my $test_name = "Only one FETCH (undef)";
+ my $ok = 0;
+ $v = undef;
+ is($f->count(), 0, "Sanity check: $test_name");
+ given(my $undef) {
+ when(sub{0}->()) {}
+ when("21") {}
+ when("22") {}
+ when($v) {$ok = 1}
+ when(undef) {$ok = 0}
+ }
+ ok($ok, "precheck: $test_name");
+ is($f->count(), 1, $test_name);
+}
+
+# Loop topicalizer
+{
+ my $first = 1;
+ for (1, "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});
+ }
+ when (1) {
+ is($first, 1, "Loop: first");
+ $first = 0;
+ # Implicit break is okay
+ }
+ }
+}
+
+{
+ my $first = 1;
+ for $_ (1, "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});
+ }
+ when (1) {
+ is($first, 1, "Explicit \$_: first");
+ $first = 0;
+ # Implicit break is okay
+ }
+ }
+}
+
+{
+ my $first = 1;
+ my $_;
+ for (1, "two") {
+ when ("two") {
+ is($first, 0, "Implicitly lexical loop: second");
+ eval {break};
+ like($@, qr/^Can't "break" in a loop topicalizer/,
+ q{Can't "break" in a loop topicalizer});
+ }
+ when (1) {
+ is($first, 1, "Implicitly lexical loop: first");
+ $first = 0;
+ # Implicit break is okay
+ }
+ }
+}
+
+{
+ my $first = 1;
+ my $_;
+ for $_ (1, "two") {
+ when ("two") {
+ is($first, 0, "Implicitly lexical, explicit \$_: second");
+ eval {break};
+ like($@, qr/^Can't "break" in a loop topicalizer/,
+ q{Can't "break" in a loop topicalizer});
+ }
+ when (1) {
+ is($first, 1, "Implicitly lexical, explicit \$_: first");
+ $first = 0;
+ # Implicit break is okay
+ }
+ }
+}
+
+{
+ my $first = 1;
+ for my $_ (1, "two") {
+ when ("two") {
+ is($first, 0, "Lexical loop: second");
+ eval {break};
+ like($@, qr/^Can't "break" in a loop topicalizer/,
+ q{Can't "break" in a loop topicalizer});
+ }
+ when (1) {
+ is($first, 1, "Lecical loop: first");
+ $first = 0;
+ # Implicit break is okay
+ }
+ }
+}
+
+
+# Code references
+{
+ no warnings "redefine";
+ my $called_foo = 0;
+ sub foo {$called_foo = 1}
+ my $called_bar = 0;
+ sub bar {$called_bar = 1}
+ my ($matched_foo, $matched_bar) = (0, 0);
+ given(\&foo) {
+ when(\&bar) {$matched_bar = 1}
+ when(\&foo) {$matched_foo = 1}
+ }
+ is($called_foo, 0, "Code ref comparison: foo not called");
+ is($called_bar, 0, "Code ref comparison: bar not called");
+ is($matched_bar, 0, "Code ref didn't match different one");
+ is($matched_foo, 1, "Code ref did match itself");
+}
+
+sub contains_x {
+ my $x = shift;
+ return ($x =~ /x/);
+}
+{
+ my ($ok1, $ok2) = (0,0);
+ given("foxy!") {
+ when(contains_x($_))
+ { $ok1 = 1; continue }
+ when(\&contains_x)
+ { $ok2 = 1; continue }
+ }
+ is($ok1, 1, "Calling sub directly (true)");
+ is($ok2, 1, "Calling sub indirectly (true)");
+
+ given("foggy") {
+ when(contains_x($_))
+ { $ok1 = 2; continue }
+ when(\&contains_x)
+ { $ok2 = 2; continue }
+ }
+ is($ok1, 1, "Calling sub directly (false)");
+ is($ok2, 1, "Calling sub indirectly (false)");
+}
+
+# Test overloading
+{ package OverloadTest;
+
+ use overload '""' => sub{"string value of obj"};
+
+ 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");
+ is($obj->{left}, "string value of obj", "$test: left");
+ is($obj->{right}, "other arg", "$test: right");
+ ok(!$obj->{reversed}, "$test: not reversed");
+}
+
+{
+ 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");
+ is($obj->{left}, "string value of obj", "$test: left");
+ is($obj->{right}, "other arg", "$test: right");
+ ok(!$obj->{reversed}, "$test: not reversed");
+}
+
+{
+ 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");
+}
+
+# Okay, that'll do for now. The intricacies of the smartmatch
+# semantics are tested in t/op/smartmatch.t
+__END__
diff --git a/toke.c b/toke.c
index 820b3b85eb..ceb521fb44 100644
--- a/toke.c
+++ b/toke.c
@@ -219,6 +219,7 @@ static struct debug_tokens { const int token, type; const char *name; }
{ 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" },
@@ -234,6 +235,7 @@ static struct debug_tokens { const int token, type; const char *name; }
{ FUNC0SUB, TOKENTYPE_OPVAL, "FUNC0SUB" },
{ FUNC1, TOKENTYPE_OPNUM, "FUNC1" },
{ FUNCMETH, TOKENTYPE_OPVAL, "FUNCMETH" },
+ { GIVEN, TOKENTYPE_IVAL, "GIVEN" },
{ HASHBRACK, TOKENTYPE_NONE, "HASHBRACK" },
{ IF, TOKENTYPE_IVAL, "IF" },
{ LABEL, TOKENTYPE_PVAL, "LABEL" },
@@ -269,6 +271,7 @@ static struct debug_tokens { const int token, type; const char *name; }
{ UNLESS, TOKENTYPE_IVAL, "UNLESS" },
{ UNTIL, TOKENTYPE_IVAL, "UNTIL" },
{ USE, TOKENTYPE_IVAL, "USE" },
+ { WHEN, TOKENTYPE_IVAL, "WHEN" },
{ WHILE, TOKENTYPE_IVAL, "WHILE" },
{ WORD, TOKENTYPE_OPVAL, "WORD" },
{ 0, TOKENTYPE_NONE, 0 }
@@ -454,6 +457,20 @@ S_missingterm(pTHX_ char *s)
Perl_croak(aTHX_ "Can't find string terminator %c%s%c anywhere before EOF",q,s,q);
}
+#define FEATURE_IS_ENABLED(name, namelen) \
+ ((0 != (PL_hints & HINT_LOCALIZE_HH)) \
+ && feature_is_enabled(name, namelen))
+/*
+ * S_feature_is_enabled
+ * Check whether the named feature is enabled.
+ */
+STATIC bool
+S_feature_is_enabled(pTHX_ char *name, STRLEN namelen)
+{
+ HV * const hinthv = GvHV(PL_hintgv);
+ return (hinthv && hv_exists(hinthv, name, namelen));
+}
+
/*
* Perl_deprecate
*/
@@ -3195,6 +3212,13 @@ Perl_yylex(pTHX)
PL_lex_brackets++;
/* FALL THROUGH */
case '~':
+ if (s[1] == '~'
+ && (PL_expect == XOPERATOR || PL_expect == XTERMORDORDOR)
+ && FEATURE_IS_ENABLED("~~", 2))
+ {
+ s += 2;
+ Eop(OP_SMARTMATCH);
+ }
case ',':
tmp = *s++;
OPERATOR(tmp);
@@ -4552,11 +4576,31 @@ Perl_yylex(pTHX)
case KEY_bless:
LOP(OP_BLESS,XTERM);
+ case KEY_break:
+ FUN0(OP_BREAK);
+
case KEY_chop:
UNI(OP_CHOP);
case KEY_continue:
+ /* When 'use switch' is in effect, continue has a dual
+ life as a control operator. */
+ {
+ if (!FEATURE_IS_ENABLED("switch", 6))
+ PREBLOCK(CONTINUE);
+ else {
+ /* We have to disambiguate the two senses of
+ "continue". If the next token is a '{' then
+ treat it as the start of a continue block;
+ otherwise treat it as a control operator.
+ */
+ s = skipspace(s);
+ if (*s == '{')
PREBLOCK(CONTINUE);
+ else
+ FUN0(OP_CONTINUE);
+ }
+ }
case KEY_chdir:
(void)gv_fetchpv("ENV",TRUE, SVt_PVHV); /* may use HOME */
@@ -4601,6 +4645,9 @@ Perl_yylex(pTHX)
case KEY_chroot:
UNI(OP_CHROOT);
+ case KEY_default:
+ PREBLOCK(DEFAULT);
+
case KEY_do:
s = skipspace(s);
if (*s == '{')
@@ -4823,6 +4870,10 @@ Perl_yylex(pTHX)
case KEY_getlogin:
FUN0(OP_GETLOGIN);
+ case KEY_given:
+ yylval.ival = CopLINE(PL_curcop);
+ OPERATOR(GIVEN);
+
case KEY_glob:
set_csh();
LOP(OP_GLOB,XTERM);
@@ -5180,6 +5231,10 @@ Perl_yylex(pTHX)
else
TOKEN(1); /* force error */
+ case KEY_say:
+ checkcomma(s,PL_tokenbuf,"filehandle");
+ LOP(OP_SAY,XREF);
+
case KEY_chomp:
UNI(OP_CHOMP);
@@ -5495,6 +5550,10 @@ Perl_yylex(pTHX)
case KEY_vec:
LOP(OP_VEC,XTERM);
+ case KEY_when:
+ yylval.ival = CopLINE(PL_curcop);
+ OPERATOR(WHEN);
+
case KEY_while:
yylval.ival = CopLINE(PL_curcop);
OPERATOR(WHILE);
@@ -5871,7 +5930,7 @@ Perl_keyword (pTHX_ const char *name, I32 len)
goto unknown;
}
- case 3: /* 28 tokens of length 3 */
+ case 3: /* 29 tokens of length 3 */
switch (name[0])
{
case 'E':
@@ -6096,6 +6155,14 @@ Perl_keyword (pTHX_ const char *name, I32 len)
case 's':
switch (name[1])
{
+ case 'a':
+ if (name[2] == 'y')
+ { /* say */
+ return (FEATURE_IS_ENABLED("say", 3) ? -KEY_say : 0);
+ }
+
+ goto unknown;
+
case 'i':
if (name[2] == 'n')
{ /* sin */
@@ -6156,7 +6223,7 @@ Perl_keyword (pTHX_ const char *name, I32 len)
goto unknown;
}
- case 4: /* 40 tokens of length 4 */
+ case 4: /* 41 tokens of length 4 */
switch (name[0])
{
case 'C':
@@ -6586,8 +6653,9 @@ Perl_keyword (pTHX_ const char *name, I32 len)
}
case 'w':
- if (name[1] == 'a')
+ switch (name[1])
{
+ case 'a':
switch (name[2])
{
case 'i':
@@ -6609,6 +6677,12 @@ Perl_keyword (pTHX_ const char *name, I32 len)
default:
goto unknown;
}
+
+ case 'h':
+ if (name[2] == 'e' &&
+ name[3] == 'n')
+ { /* when */
+ return (FEATURE_IS_ENABLED("switch", 6) ? KEY_when : 0);
}
goto unknown;
@@ -6617,7 +6691,11 @@ Perl_keyword (pTHX_ const char *name, I32 len)
goto unknown;
}
- case 5: /* 36 tokens of length 5 */
+ default:
+ goto unknown;
+ }
+
+ case 5: /* 38 tokens of length 5 */
switch (name[0])
{
case 'B':
@@ -6670,8 +6748,10 @@ Perl_keyword (pTHX_ const char *name, I32 len)
}
case 'b':
- if (name[1] == 'l' &&
- name[2] == 'e' &&
+ switch (name[1])
+ {
+ case 'l':
+ if (name[2] == 'e' &&
name[3] == 's' &&
name[4] == 's')
{ /* bless */
@@ -6680,6 +6760,20 @@ Perl_keyword (pTHX_ const char *name, I32 len)
goto unknown;
+ case 'r':
+ if (name[2] == 'e' &&
+ name[3] == 'a' &&
+ name[4] == 'k')
+ { /* break */
+ return (FEATURE_IS_ENABLED("switch", 6) ? -KEY_break : 0);
+ }
+
+ goto unknown;
+
+ default:
+ goto unknown;
+ }
+
case 'c':
switch (name[1])
{
@@ -6793,6 +6887,17 @@ Perl_keyword (pTHX_ const char *name, I32 len)
goto unknown;
}
+ case 'g':
+ if (name[1] == 'i' &&
+ name[2] == 'v' &&
+ name[3] == 'e' &&
+ name[4] == 'n')
+ { /* given */
+ return (FEATURE_IS_ENABLED("switch", 6) ? KEY_given : 0);
+ }
+
+ goto unknown;
+
case 'i':
switch (name[1])
{
@@ -7529,7 +7634,7 @@ Perl_keyword (pTHX_ const char *name, I32 len)
goto unknown;
}
- case 7: /* 28 tokens of length 7 */
+ case 7: /* 29 tokens of length 7 */
switch (name[0])
{
case 'D':
@@ -7600,9 +7705,22 @@ Perl_keyword (pTHX_ const char *name, I32 len)
goto unknown;
case 'e':
- if (name[2] == 'f' &&
- name[3] == 'i' &&
- name[4] == 'n' &&
+ if (name[2] == 'f')
+ {
+ switch (name[3])
+ {
+ case 'a':
+ if (name[4] == 'u' &&
+ name[5] == 'l' &&
+ name[6] == 't')
+ { /* default */
+ return (FEATURE_IS_ENABLED("switch", 6) ? KEY_default : 0);
+ }
+
+ goto unknown;
+
+ case 'i':
+ if (name[4] == 'n' &&
name[5] == 'e' &&
name[6] == 'd')
{ /* defined */
@@ -7614,6 +7732,13 @@ Perl_keyword (pTHX_ const char *name, I32 len)
default:
goto unknown;
}
+ }
+
+ goto unknown;
+
+ default:
+ goto unknown;
+ }
case 'f':
if (name[1] == 'o' &&
@@ -9020,7 +9145,7 @@ S_checkcomma(pTHX_ register char *s, const char *name, const char *what)
while (s < PL_bufend && isSPACE(*s))
s++;
if (*s == ',') {
- int kw;
+ I32 kw;
*s = '\0'; /* XXX If we didn't do this, we could const a lot of toke.c */
kw = keyword(w, s - w) || get_cv(w, FALSE) != 0;
*s = ',';