summaryrefslogtreecommitdiff
path: root/op.c
diff options
context:
space:
mode:
authorVincent Pit <perl@profvince.com>2010-01-03 18:22:38 +0100
committerVincent Pit <perl@profvince.com>2010-01-03 18:37:37 +0100
commit25b991bf8caa94f23a64f9568f5ceee69781aa25 (patch)
tree77b6a52863d1c3a9cbcc3f323ea7f873e99a3d36 /op.c
parentfd909433c74372968d34d9cad8f4458ab60e19b4 (diff)
downloadperl-25b991bf8caa94f23a64f9568f5ceee69781aa25.tar.gz
Make given() statements return the last evaluated expression
Diffstat (limited to 'op.c')
-rw-r--r--op.c56
1 files changed, 31 insertions, 25 deletions
diff --git a/op.c b/op.c
index 88a31d33fa..e0d7fbbcd9 100644
--- a/op.c
+++ b/op.c
@@ -923,25 +923,28 @@ Perl_scalar(pTHX_ OP *o)
case OP_LEAVETRY:
kid = cLISTOPo->op_first;
scalar(kid);
- while ((kid = kid->op_sibling)) {
- if (kid->op_sibling)
- scalarvoid(kid);
- else
+ kid = kid->op_sibling;
+ do_kids:
+ while (kid) {
+ OP *sib = kid->op_sibling;
+ if (sib && kid->op_type != OP_LEAVEWHEN) {
+ if (sib->op_type == OP_BREAK && sib->op_flags & OPf_SPECIAL) {
+ scalar(kid);
+ scalarvoid(sib);
+ break;
+ } else
+ scalarvoid(kid);
+ } else
scalar(kid);
+ kid = sib;
}
PL_curcop = &PL_compiling;
break;
case OP_SCOPE:
case OP_LINESEQ:
case OP_LIST:
- for (kid = cLISTOPo->op_first; kid; kid = kid->op_sibling) {
- if (kid->op_sibling)
- scalarvoid(kid);
- else
- scalar(kid);
- }
- PL_curcop = &PL_compiling;
- break;
+ kid = cLISTOPo->op_first;
+ goto do_kids;
case OP_SORT:
Perl_ck_warner(aTHX_ packWARN(WARN_VOID), "Useless use of sort in scalar context");
break;
@@ -985,7 +988,7 @@ Perl_scalarvoid(pTHX_ OP *o)
want = o->op_flags & OPf_WANT;
if ((want && want != OPf_WANT_SCALAR)
|| (PL_parser && PL_parser->error_count)
- || o->op_type == OP_RETURN || o->op_type == OP_REQUIRE)
+ || o->op_type == OP_RETURN || o->op_type == OP_REQUIRE || o->op_type == OP_LEAVEWHEN)
{
return o;
}
@@ -1296,24 +1299,27 @@ Perl_list(pTHX_ OP *o)
case OP_LEAVETRY:
kid = cLISTOPo->op_first;
list(kid);
- while ((kid = kid->op_sibling)) {
- if (kid->op_sibling)
- scalarvoid(kid);
- else
+ kid = kid->op_sibling;
+ do_kids:
+ while (kid) {
+ OP *sib = kid->op_sibling;
+ if (sib && kid->op_type != OP_LEAVEWHEN) {
+ if (sib->op_type == OP_BREAK && sib->op_flags & OPf_SPECIAL) {
+ list(kid);
+ scalarvoid(sib);
+ break;
+ } else
+ scalarvoid(kid);
+ } else
list(kid);
+ kid = sib;
}
PL_curcop = &PL_compiling;
break;
case OP_SCOPE:
case OP_LINESEQ:
- for (kid = cLISTOPo->op_first; kid; kid = kid->op_sibling) {
- if (kid->op_sibling)
- scalarvoid(kid);
- else
- list(kid);
- }
- PL_curcop = &PL_compiling;
- break;
+ kid = cLISTOPo->op_first;
+ goto do_kids;
}
return o;
}