X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=perly.y;h=a1f23ab7ce1be63e2584367be9f62ae6e7a78ed4;hb=70bef35c07950550d22b89ad8a4afb174aa8aece;hp=ad0e604543beb6a434d886497977e68a30c44585;hpb=2af555bf3f2b3ca8e114df3f5f680d40bd24d6bf;p=p5sagit%2Fp5-mst-13.2.git diff --git a/perly.y b/perly.y index ad0e604..a1f23ab 100644 --- a/perly.y +++ b/perly.y @@ -32,6 +32,10 @@ * The main job of of this grammar is to call the various newFOO() * functions in op.c to build a syntax tree of OP structs. * It relies on the lexer in toke.c to do the tokenizing. + * + * Note: due to the way that the cleanup code works WRT to freeing ops on + * the parse stack, it is dangerous to assign to the $n variables within + * an action. */ /* Make the parser re-entrant. */ @@ -48,7 +52,6 @@ char *pval; OP *opval; GV *gvval; - AV* padval; #ifdef PERL_IN_MADLY_C TOKEN* p_tkval; TOKEN* i_tkval; @@ -92,7 +95,6 @@ %type termbinop termunop anonymous termdo %type switch case %type label -%type remempad %nonassoc PREC_LOW %nonassoc LOOPEX @@ -386,13 +388,10 @@ loop : label WHILE '(' remember texpr ')' mintro mblock cont IVAL($2), scalar($7), $12, $10, $9)); #ifdef MAD - if (!$5) - $5 = newOP(OP_NULL, 0); forop = newUNOP(OP_NULL, 0, append_elem(OP_LINESEQ, newSTATEOP(0, - (($1)->tk_lval.pval - ?savepv(($1)->tk_lval.pval):Nullch), - $5), + CopLABEL_alloc(($1)->tk_lval.pval), + ($5 ? newOP(OP_NULL, 0) : $5) ), forop)); token_getmad($2,forop,'3'); @@ -404,8 +403,7 @@ loop : label WHILE '(' remember texpr ')' mintro mblock cont #else if ($5) { forop = append_elem(OP_LINESEQ, - newSTATEOP(0, ($1?savepv($1):Nullch), - $5), + newSTATEOP(0, CopLABEL_alloc($1), $5), forop); } @@ -504,15 +502,16 @@ peg : PEG } ; -format : FORMAT remempad startformsub formname block +format : FORMAT startformsub formname block { SvREFCNT_inc(PL_compcv); #ifdef MAD - $$ = newFORM($3, $4, $5); + $$ = newFORM($2, $3, $4); prepend_madprops($1->tk_mad, $$, 'F'); $1->tk_mad = 0; token_free($1); #else - newFORM($3, $4, $5); + newFORM($2, $3, $4); + $$ = Nullop; #endif } ; @@ -522,42 +521,39 @@ formname: WORD { $$ = $1; } ; /* Unimplemented "my sub foo { }" */ -mysubrout: MYSUB remempad startsub subname proto subattrlist subbody +mysubrout: MYSUB startsub subname proto subattrlist subbody { SvREFCNT_inc(PL_compcv); #ifdef MAD - $$ = newMYSUB($3, $4, $5, $6, $7); + $$ = newMYSUB($2, $3, $4, $5, $6); token_getmad($1,$$,'d'); #else - newMYSUB($3, $4, $5, $6, $7); + newMYSUB($2, $3, $4, $5, $6); + $$ = Nullop; #endif } ; /* Subroutine definition */ -subrout : SUB remempad startsub subname proto subattrlist subbody +subrout : SUB startsub subname proto subattrlist subbody { SvREFCNT_inc(PL_compcv); #ifdef MAD OP* o = newSVOP(OP_ANONCODE, 0, - (SV*)newATTRSUB($3, $4, $5, $6, $7)); + (SV*)newATTRSUB($2, $3, $4, $5, $6)); $$ = newOP(OP_NULL,0); op_getmad(o,$$,'&'); - op_getmad($4,$$,'n'); - op_getmad($5,$$,'s'); - op_getmad($6,$$,'a'); + op_getmad($3,$$,'n'); + op_getmad($4,$$,'s'); + op_getmad($5,$$,'a'); token_getmad($1,$$,'d'); - append_madprops($7->op_madprop, $$, 0); - $7->op_madprop = 0; + append_madprops($6->op_madprop, $$, 0); + $6->op_madprop = 0; #else - newATTRSUB($3, $4, $5, $6, $7); + newATTRSUB($2, $3, $4, $5, $6); $$ = Nullop; #endif } ; -remempad: /* NULL */ /* remember current value of PL_comppad */ - { $$ = PL_comppad; } - ; - startsub: /* NULL */ /* start a regular subroutine scope */ { $$ = start_subparse(FALSE, 0); SAVEFREESV(PL_compcv); } @@ -638,22 +634,24 @@ package : PACKAGE WORD ';' token_getmad($3,$$,';'); #else package($2); + $$ = Nullop; #endif } ; -use : USE remempad startsub +use : USE startsub { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ } WORD WORD listexpr ';' { SvREFCNT_inc(PL_compcv); #ifdef MAD - $$ = utilize(IVAL($1), $3, $5, $6, $7); + $$ = utilize(IVAL($1), $2, $4, $5, $6); token_getmad($1,$$,'o'); - token_getmad($8,$$,';'); + token_getmad($7,$$,';'); if (PL_rsfp_filters && AvFILLp(PL_rsfp_filters) >= 0) append_madprops(newMADPROP('!', MAD_PV, "", 0), $$, 0); #else - utilize(IVAL($1), $3, $5, $6, $7); + utilize(IVAL($1), $2, $4, $5, $6); + $$ = Nullop; #endif } ; @@ -687,11 +685,12 @@ argexpr : argexpr ',' } | argexpr ',' term { + OP* term = $3; DO_MAD( - $3 = newUNOP(OP_NULL, 0, $3); - token_getmad($2,$3,','); + term = newUNOP(OP_NULL, 0, term); + token_getmad($2,term,','); ) - $$ = append_elem(OP_LIST, $1, $3); + $$ = append_elem(OP_LIST, $1, term); } | term %prec PREC_LOW ; @@ -748,13 +747,13 @@ listop : LSTOP indirob argexpr /* map {...} @args or print $fh @args */ TOKEN_GETMAD($2,$$,'('); TOKEN_GETMAD($4,$$,')'); } - | LSTOPSUB remempad startanonsub block /* sub f(&@); f {foo} ... */ + | LSTOPSUB startanonsub block /* sub f(&@); f { foo } ... */ { SvREFCNT_inc(PL_compcv); - $4 = newANONATTRSUB($3, 0, Nullop, $4); } + $$ = newANONATTRSUB($2, 0, Nullop, $3); } listexpr %prec LSTOP /* ... @bar */ { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, - prepend_elem(OP_LIST, $4, $6), $1)); + prepend_elem(OP_LIST, $4, $5), $1)); } ; @@ -1002,12 +1001,12 @@ anonymous: '[' expr ']' TOKEN_GETMAD($2,$$,';'); TOKEN_GETMAD($3,$$,'}'); } - | ANONSUB remempad startanonsub proto subattrlist block %prec '(' + | ANONSUB startanonsub proto subattrlist block %prec '(' { SvREFCNT_inc(PL_compcv); - $$ = newANONATTRSUB($3, $4, $5, $6); + $$ = newANONATTRSUB($2, $3, $4, $5); TOKEN_GETMAD($1,$$,'o'); - OP_GETMAD($4,$$,'s'); - OP_GETMAD($5,$$,'a'); + OP_GETMAD($3,$$,'s'); + OP_GETMAD($4,$$,'a'); } ;