summaryrefslogtreecommitdiff
path: root/perly.act
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2011-10-12 14:01:50 +0100
committerDavid Mitchell <davem@iabyn.com>2012-06-13 13:25:50 +0100
commitd63c20f27b4a88c274844b2b635deb3c6588cccd (patch)
tree419e8d46117855aa07627636841d9a7208f0320e /perly.act
parent2866decb530d50f622ad6853fed7f30562e474ce (diff)
downloadperl-d63c20f27b4a88c274844b2b635deb3c6588cccd.tar.gz
make qr/(?{})/ behave with closures
With this commit, qr// with a literal (compile-time) code block will Do the Right Thing as regards closures and the scope of lexical vars; in particular, the following now creates three regexes that match 1, 2 and 3: for my $i (0..2) { push @r, qr/^(??{$i})$/; } "1" =~ $r[1]; # matches Previously, $i would be evaluated as undef in all 3 patterns. This is achieved by wrapping the compilation of the pattern within a new anonymous CV, which is then attached to the pattern. At run-time pp_qr() clones the CV as well as copying the REGEXP; and when the code block is executed, it does so using the pad of the cloned CV. Which makes everything come out all right in the wash. The CV is stored in a new field of the REGEXP, called qr_anoncv. Note that run-time qr//s are still not fixed, e.g. qr/$foo(?{...})/; nor is it yet fixed where the qr// is embedded within another pattern: continuing with the code example from above, my $i = 99; "1" =~ $r[1]; # bare qr: matches: correct! "X99" =~ /X$r[1]/; # embedded qr: matches: whoops, it's still seeing the wrong $i
Diffstat (limited to 'perly.act')
-rw-r--r--perly.act114
1 files changed, 64 insertions, 50 deletions
diff --git a/perly.act b/perly.act
index 00ddadbd95..0b52df9016 100644
--- a/perly.act
+++ b/perly.act
@@ -1552,14 +1552,28 @@ case 2:
case 193:
#line 1261 "perly.y"
- { (yyval.opval) = pmruntime((ps[(1) - (4)].val.opval), (ps[(3) - (4)].val.opval), 1);
- TOKEN_GETMAD((ps[(2) - (4)].val.i_tkval),(yyval.opval),'(');
- TOKEN_GETMAD((ps[(4) - (4)].val.i_tkval),(yyval.opval),')');
+ {
+ if ( (ps[(1) - (1)].val.opval)->op_type != OP_TRANS
+ && (ps[(1) - (1)].val.opval)->op_type != OP_TRANSR
+ && (((PMOP*)(ps[(1) - (1)].val.opval))->op_pmflags & PMf_HAS_CV))
+ {
+ (yyval.ival) = start_subparse(FALSE, CVf_ANON);
+ SAVEFREESV(PL_compcv);
+ } else
+ (yyval.ival) = 0;
+ ;}
+ break;
+
+ case 194:
+#line 1272 "perly.y"
+ { (yyval.opval) = pmruntime((ps[(1) - (5)].val.opval), (ps[(4) - (5)].val.opval), 1, (ps[(2) - (5)].val.ival));
+ TOKEN_GETMAD((ps[(3) - (5)].val.i_tkval),(yyval.opval),'(');
+ TOKEN_GETMAD((ps[(5) - (5)].val.i_tkval),(yyval.opval),')');
;}
break;
- case 196:
-#line 1268 "perly.y"
+ case 197:
+#line 1279 "perly.y"
{
(yyval.opval) = newLISTOP(OP_DIE, 0, newOP(OP_PUSHMARK, 0),
newSVOP(OP_CONST, 0, newSVpvs("Unimplemented")));
@@ -1567,8 +1581,8 @@ case 2:
;}
break;
- case 198:
-#line 1278 "perly.y"
+ case 199:
+#line 1289 "perly.y"
{ (yyval.opval) = my_attrs((ps[(2) - (3)].val.opval),(ps[(3) - (3)].val.opval));
DO_MAD(
token_getmad((ps[(1) - (3)].val.i_tkval),(yyval.opval),'d');
@@ -1578,128 +1592,128 @@ case 2:
;}
break;
- case 199:
-#line 1286 "perly.y"
+ case 200:
+#line 1297 "perly.y"
{ (yyval.opval) = localize((ps[(2) - (2)].val.opval),IVAL((ps[(1) - (2)].val.i_tkval)));
TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'d');
;}
break;
- case 200:
-#line 1293 "perly.y"
+ case 201:
+#line 1304 "perly.y"
{ (yyval.opval) = sawparens((ps[(2) - (3)].val.opval));
TOKEN_GETMAD((ps[(1) - (3)].val.i_tkval),(yyval.opval),'(');
TOKEN_GETMAD((ps[(3) - (3)].val.i_tkval),(yyval.opval),')');
;}
break;
- case 201:
-#line 1298 "perly.y"
+ case 202:
+#line 1309 "perly.y"
{ (yyval.opval) = sawparens(newNULLLIST());
TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'(');
TOKEN_GETMAD((ps[(2) - (2)].val.i_tkval),(yyval.opval),')');
;}
break;
- case 202:
-#line 1303 "perly.y"
- { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
- break;
-
case 203:
-#line 1305 "perly.y"
+#line 1314 "perly.y"
{ (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
break;
case 204:
-#line 1307 "perly.y"
+#line 1316 "perly.y"
{ (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
break;
case 205:
-#line 1312 "perly.y"
- { (yyval.opval) = (OP*)NULL; ;}
+#line 1318 "perly.y"
+ { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
break;
case 206:
-#line 1314 "perly.y"
- { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
+#line 1323 "perly.y"
+ { (yyval.opval) = (OP*)NULL; ;}
break;
case 207:
-#line 1318 "perly.y"
- { (yyval.opval) = (OP*)NULL; ;}
+#line 1325 "perly.y"
+ { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
break;
case 208:
-#line 1320 "perly.y"
- { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
+#line 1329 "perly.y"
+ { (yyval.opval) = (OP*)NULL; ;}
break;
case 209:
-#line 1326 "perly.y"
- { PL_parser->in_my = 0; (yyval.opval) = my((ps[(1) - (1)].val.opval)); ;}
+#line 1331 "perly.y"
+ { (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
break;
case 210:
-#line 1330 "perly.y"
+#line 1337 "perly.y"
+ { PL_parser->in_my = 0; (yyval.opval) = my((ps[(1) - (1)].val.opval)); ;}
+ break;
+
+ case 211:
+#line 1341 "perly.y"
{ (yyval.opval) = newCVREF(IVAL((ps[(1) - (2)].val.i_tkval)),(ps[(2) - (2)].val.opval));
TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'&');
;}
break;
- case 211:
-#line 1336 "perly.y"
+ case 212:
+#line 1347 "perly.y"
{ (yyval.opval) = newSVREF((ps[(2) - (2)].val.opval));
TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'$');
;}
break;
- case 212:
-#line 1342 "perly.y"
+ case 213:
+#line 1353 "perly.y"
{ (yyval.opval) = newAVREF((ps[(2) - (2)].val.opval));
TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'@');
;}
break;
- case 213:
-#line 1348 "perly.y"
+ case 214:
+#line 1359 "perly.y"
{ (yyval.opval) = newHVREF((ps[(2) - (2)].val.opval));
TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'%');
;}
break;
- case 214:
-#line 1354 "perly.y"
+ case 215:
+#line 1365 "perly.y"
{ (yyval.opval) = newAVREF((ps[(2) - (2)].val.opval));
TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'l');
;}
break;
- case 215:
-#line 1360 "perly.y"
+ case 216:
+#line 1371 "perly.y"
{ (yyval.opval) = newGVREF(0,(ps[(2) - (2)].val.opval));
TOKEN_GETMAD((ps[(1) - (2)].val.i_tkval),(yyval.opval),'*');
;}
break;
- case 216:
-#line 1367 "perly.y"
+ case 217:
+#line 1378 "perly.y"
{ (yyval.opval) = scalar((ps[(1) - (1)].val.opval)); ;}
break;
- case 217:
-#line 1369 "perly.y"
+ case 218:
+#line 1380 "perly.y"
{ (yyval.opval) = scalar((ps[(1) - (1)].val.opval)); ;}
break;
- case 218:
-#line 1371 "perly.y"
+ case 219:
+#line 1382 "perly.y"
{ (yyval.opval) = op_scope((ps[(1) - (1)].val.opval)); ;}
break;
- case 219:
-#line 1374 "perly.y"
+ case 220:
+#line 1385 "perly.y"
{ (yyval.opval) = (ps[(1) - (1)].val.opval); ;}
break;
@@ -1707,6 +1721,6 @@ case 2:
/* Generated from:
- * ff01d43de6f749eba3bfeffd39928772fe7e1bebe039506b8465c05941209aa8 perly.y
+ * 27cce68ad4844f1b8053bfc11206fb9f559e08be6cefd4a986aaa606c0e5fb38 perly.y
* 53f57d7143a42b3c008841a14d158bcf9cab64b2904b07ef5e95051fe9a8a875 regen_perly.pl
* ex: set ro: */