X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=perly.y;h=9ca64a8757ff5ddbd09f61122ecf88f063131d34;hb=19b95bf092bc6fdb9455fe107fc46111b0a1ec31;hp=dd70c2bdeecd13c2cb8c579e23bf11335ea2b89e;hpb=30994c59813138744bd35d43a2330cafe5893149;p=p5sagit%2Fp5-mst-13.2.git diff --git a/perly.y b/perly.y index dd70c2b..9ca64a8 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. */ @@ -384,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 ? $5 : newOP(OP_NULL, 0)) ), forop)); token_getmad($2,forop,'3'); @@ -402,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); } @@ -685,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,11 +749,11 @@ listop : LSTOP indirob argexpr /* map {...} @args or print $fh @args */ } | LSTOPSUB startanonsub block /* sub f(&@); f { foo } ... */ { SvREFCNT_inc(PL_compcv); - $3 = newANONATTRSUB($2, 0, Nullop, $3); } + $$ = newANONATTRSUB($2, 0, Nullop, $3); } listexpr %prec LSTOP /* ... @bar */ { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, - prepend_elem(OP_LIST, $3, $5), $1)); + prepend_elem(OP_LIST, $4, $5), $1)); } ; @@ -1177,10 +1178,14 @@ term : termbinop { $$ = newUNOP(IVAL($1), 0, $2); TOKEN_GETMAD($1,$$,'o'); } - | REQUIRE /* require, $_ implied *//* FIMXE for MAD needed? */ - { $$ = newOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0); } - | REQUIRE term /* require Foo *//* FIMXE for MAD needed? */ - { $$ = newUNOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0, $2); } + | REQUIRE /* require, $_ implied */ + { $$ = newOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0); + TOKEN_GETMAD($1,$$,'o'); + } + | REQUIRE term /* require Foo */ + { $$ = newUNOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0, $2); + TOKEN_GETMAD($1,$$,'o'); + } | UNIOPSUB { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); } | UNIOPSUB term /* Sub treated as unop */