summaryrefslogtreecommitdiff
path: root/op.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2007-09-08 22:34:29 +0000
committerNicholas Clark <nick@ccl4.org>2007-09-08 22:34:29 +0000
commit6dbe9451abb7e30d650de45d484c69e6c34bbd36 (patch)
tree9ffa248394ec7c0919a7a814e2e1b1a461f0f674 /op.c
parentaab6a793686b4f073e16b436e1705cd0e9106ced (diff)
downloadperl-6dbe9451abb7e30d650de45d484c69e6c34bbd36.tar.gz
For now, forbid all list assignment initialisation of state variables,
as the precise semantics in Perl 6 are not clear. Better to make it a syntax error, than to have one behaviour now, but change it later. [I believe that this is the consensus. If not, it will be backed out] p4raw-id: //depot/perl@31824
Diffstat (limited to 'op.c')
-rw-r--r--op.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/op.c b/op.c
index 6975d83824..ca488a279b 100644
--- a/op.c
+++ b/op.c
@@ -3968,6 +3968,8 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
}
if (is_list_assignment(left)) {
+ static const char no_list_state[] = "Initialization of state variables"
+ " in list context currently forbidden";
OP *curop;
PL_modcount = 0;
@@ -4061,6 +4063,54 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
o->op_private |= OPpASSIGN_COMMON;
}
+ if ((left->op_type == OP_LIST
+ || (left->op_type == OP_NULL && left->op_targ == OP_LIST))) {
+ OP* lop = ((LISTOP*)left)->op_first;
+ while (lop) {
+ if (lop->op_type == OP_PADSV ||
+ lop->op_type == OP_PADAV ||
+ lop->op_type == OP_PADHV ||
+ lop->op_type == OP_PADANY) {
+ if (lop->op_private & OPpPAD_STATE) {
+ if (left->op_private & OPpLVAL_INTRO) {
+ /* Each variable in state($a, $b, $c) = ... */
+ }
+ else {
+ /* Each state variable in
+ (state $a, my $b, our $c, $d, undef) = ... */
+ }
+ yyerror(no_list_state);
+ } else {
+ /* Each my variable in
+ (state $a, my $b, our $c, $d, undef) = ... */
+ }
+ } else {
+ /* Other ops in the list. undef may be interesting in
+ (state $a, undef, state $c) */
+ }
+ lop = lop->op_sibling;
+ }
+ }
+ else if (((left->op_private & (OPpLVAL_INTRO | OPpPAD_STATE))
+ == (OPpLVAL_INTRO | OPpPAD_STATE))
+ && ( left->op_type == OP_PADSV
+ || left->op_type == OP_PADAV
+ || left->op_type == OP_PADHV
+ || left->op_type == OP_PADANY))
+ {
+ /* All single variable list context state assignments, hence
+ state ($a) = ...
+ (state $a) = ...
+ state @a = ...
+ state (@a) = ...
+ (state @a) = ...
+ state %a = ...
+ state (%a) = ...
+ (state %a) = ...
+ */
+ yyerror(no_list_state);
+ }
+
if (right && right->op_type == OP_SPLIT && !PL_madskills) {
OP* tmpop = ((LISTOP*)right)->op_first;
if (tmpop && (tmpop->op_type == OP_PUSHRE)) {