summaryrefslogtreecommitdiff
path: root/perly.y
diff options
context:
space:
mode:
authorZefram <zefram@fysh.org>2010-10-16 22:22:57 +0100
committerFather Chrysostomos <sprout@cpan.org>2010-10-23 23:25:21 -0700
commit5f211341d665e81a03fbd4935e4e87f70d937fc3 (patch)
tree154fcb4845377ffc122e365199a98db48478c3ab /perly.y
parent74401f9c0e7d7248493d3f2bb0f4fdb0b20a92aa (diff)
downloadperl-5f211341d665e81a03fbd4935e4e87f70d937fc3.tar.gz
permit labels to appear before declarations
Include <label> in productions before <decl> and <package_block>. This means that labels can now appear at the beginning of all statement-like things. There was no technical reason for the restriction of labels to substantive statements, and that restriction in any case couldn't be applied to PLUGSTMT-based plugged-in declarations.
Diffstat (limited to 'perly.y')
-rw-r--r--perly.y52
1 files changed, 24 insertions, 28 deletions
diff --git a/perly.y b/perly.y
index a70122d101..33dbb1f885 100644
--- a/perly.y
+++ b/perly.y
@@ -95,7 +95,7 @@
%type <ival> mydefsv mintro
%type <opval> fullstmt decl format subrout mysubrout package use peg
-%type <opval> block package_block mblock lineseq line loop cond else
+%type <opval> block package_block mblock stmtseq loop cond else
%type <opval> expr term subscripted scalar ary hsh arylen star amper sideff
%type <opval> argexpr nexpr texpr iexpr mexpr mnexpr miexpr
%type <opval> listexpr listexprcom indirob listop method
@@ -149,6 +149,7 @@ grammar : GRAMPROG prog
}
block
{
+ PL_pad_reset_pending = TRUE;
PL_eval_root = $3;
$$ = 0;
yyunlex();
@@ -160,6 +161,7 @@ grammar : GRAMPROG prog
}
fullstmt
{
+ PL_pad_reset_pending = TRUE;
PL_eval_root = $3;
$$ = 0;
yyunlex();
@@ -169,7 +171,7 @@ grammar : GRAMPROG prog
{
parser->expect = XSTATE;
}
- lineseq
+ stmtseq
{
PL_eval_root = $3;
$$ = 0;
@@ -178,12 +180,12 @@ grammar : GRAMPROG prog
/* The whole program */
prog : progstart
- /*CONTINUED*/ lineseq
+ /*CONTINUED*/ stmtseq
{ $$ = $1; newPROG(block_end($1,$2)); }
;
/* An ordinary block */
-block : '{' remember lineseq '}'
+block : '{' remember stmtseq '}'
{ if (PL_parser->copline > (line_t)IVAL($1))
PL_parser->copline = (line_t)IVAL($1);
$$ = block_end($2, $3);
@@ -207,7 +209,7 @@ progstart:
;
-mblock : '{' mremember lineseq '}'
+mblock : '{' mremember stmtseq '}'
{ if (PL_parser->copline > (line_t)IVAL($1))
PL_parser->copline = (line_t)IVAL($1);
$$ = block_end($2, $3);
@@ -221,13 +223,9 @@ mremember: /* NULL */ /* start a partial lexical scope */
;
/* A collection of "lines" in the program */
-lineseq : /* NULL */
+stmtseq : /* NULL */
{ $$ = (OP*)NULL; }
- | lineseq decl
- {
- $$ = IF_MAD(op_append_list(OP_LINESEQ, $1, $2), $1);
- }
- | lineseq line
+ | stmtseq fullstmt
{ $$ = op_append_list(OP_LINESEQ, $1, $2);
PL_pad_reset_pending = TRUE;
if ($1 && $2)
@@ -235,18 +233,8 @@ lineseq : /* NULL */
}
;
-/* A statement, or "line", in the program */
-fullstmt: decl
- { $$ = $1; }
- | line
- {
- PL_pad_reset_pending = TRUE;
- $$ = $1;
- }
- ;
-
-/* A non-declaration statement */
-line : label cond
+/* A statement in the program */
+fullstmt: label cond
{ $$ = newSTATEOP(0, PVAL($1), $2);
TOKEN_GETMAD($1,((LISTOP*)$$)->op_first,'L'); }
| loop /* loops add their own labels */
@@ -287,13 +275,21 @@ line : label cond
}
})
}
- | package_block
- { $$ = newSTATEOP(0, NULL,
+ | label package_block
+ { $$ = newSTATEOP(0, PVAL($1),
newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
- NOLINE, (OP*)NULL, $1,
+ NOLINE, (OP*)NULL, $2,
(OP*)NULL, 0)); }
| label PLUGSTMT
{ $$ = newSTATEOP(0, PVAL($1), $2); }
+ | label decl
+ {
+ if (PVAL($1)) {
+ $$ = newSTATEOP(0, PVAL($1), $2);
+ } else {
+ $$ = IF_MAD($2 ? $2 : newOP(OP_NULL, 0), $2);
+ }
+ }
;
/* An expression which may have a side-effect */
@@ -438,7 +434,7 @@ loop : label WHILE lpar_or_qw remember texpr ')' mintro mblock cont
}
| label FOR lpar_or_qw remember mnexpr ';' texpr ';' mintro mnexpr ')'
mblock
- /* basically fake up an initialize-while lineseq */
+ /* basically fake up an initialize-while stmtseq */
{ OP *forop;
PL_parser->copline = (line_t)IVAL($2);
forop = newSTATEOP(0, PVAL($1),
@@ -722,7 +718,7 @@ package_block: PACKAGE WORD WORD '{' remember
$2->op_latefree = save_2_latefree;
}
}
- lineseq '}'
+ stmtseq '}'
{ if (PL_parser->copline > (line_t)IVAL($4))
PL_parser->copline = (line_t)IVAL($4);
$$ = block_end($5, $7);