diff options
author | Father Chrysostomos <sprout@cpan.org> | 2012-06-30 23:20:25 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-09-15 22:44:53 -0700 |
commit | 764212cf73683dc2fdc86061a1e2cf4193b89919 (patch) | |
tree | cb60c2baba72a0945a0aa44120d8b17d9f2f226d /perly.y | |
parent | 9ccb8d54fdbdc68755020d2a7cce3b889106c1e1 (diff) | |
download | perl-764212cf73683dc2fdc86061a1e2cf4193b89919.tar.gz |
Allocate ‘our sub’ in the pad
Currently the name is only allocated there. Nothing fetches it yet.
Notes on the implementation:
S_pending_ident contains the logic for determining whether $foo or
@foo refers to a lexical or package variable.
yylex defers to S_pending_ident if PL_pending_ident is set.
The KEY_sub case in yylex is changed to set PL_pending_ident instead
of using force_word. For package variables (including our),
S_pending_ident returns a WORD token, which is the same thing that
force_word produces. So *that* aspect of this change does not affect
the grammar. However....
The barestmt rule’s SUB branch begins with ‘SUB startsub subname’.
startsub is a null rule that creates a new sub in PL_compcv via
start_subparse(). subname is defined in terms of WORD and also checks
whether this is a special block, turning on CvSPECIAL(PL_compcv) if
it is. That flag has to be visible during compilation of the sub.
But for a lexical name, such as ‘our foo’, to be allocated in the
right pad, it has to come *before* startsub, i.e., ‘SUB subname
startsub’.
But subname needs to modify the sub that startsub created, set-
ting the flag.
So I copied (not moved, because MYSUB still uses it) the name-checking
code from the subname rule into the SUB branch of barestmt. Now that
uses WORD directly instead of invoking subname. That allows the code
there to set everything up in the right order.
Diffstat (limited to 'perly.y')
-rw-r--r-- | perly.y | 26 |
1 files changed, 18 insertions, 8 deletions
@@ -314,26 +314,36 @@ barestmt: PLUGSTMT pad_add_anon(fmtcv, OP_NULL); } } - | SUB startsub subname proto subattrlist subbody + | SUB WORD startsub + { const char *const name = SvPV_nolen_const(((SVOP*)$2)->op_sv); + if (strEQ(name, "BEGIN") || strEQ(name, "END") + || strEQ(name, "INIT") || strEQ(name, "CHECK") + || strEQ(name, "UNITCHECK")) + CvSPECIAL_on(PL_compcv); + PL_parser->in_my = 0; + PL_parser->in_my_stash = NULL; + } + proto subattrlist subbody { SvREFCNT_inc_simple_void(PL_compcv); #ifdef MAD { OP* o = newSVOP(OP_ANONCODE, 0, - (SV*)newATTRSUB($2, $3, $4, $5, $6)); + (SV*)newATTRSUB($3, $2, $5, $6, $7)); $$ = newOP(OP_NULL,0); op_getmad(o,$$,'&'); - op_getmad($3,$$,'n'); - op_getmad($4,$$,'s'); - op_getmad($5,$$,'a'); + op_getmad($2,$$,'n'); + op_getmad($5,$$,'s'); + op_getmad($6,$$,'a'); token_getmad($1,$$,'d'); - append_madprops($6->op_madprop, $$, 0); - $6->op_madprop = 0; + append_madprops($7->op_madprop, $$, 0); + $7->op_madprop = 0; } #else - newATTRSUB($2, $3, $4, $5, $6); + newATTRSUB($3, $2, $5, $6, $7); $$ = (OP*)NULL; #endif + intro_my(); } | MYSUB startsub subname proto subattrlist subbody { |