/* perly.y
*
- * Copyright (c) 1991-2001, Larry Wall
+ * Copyright (c) 1991-2002, Larry Wall
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
YYSTYPE oldyylval;
};
-static void yydestruct(pTHXo_ void *ptr);
+static void yydestruct(pTHX_ void *ptr);
%}
%token COLONATTR
%type <ival> prog decl format startsub startanonsub startformsub
-%type <ival> remember mremember '&'
+%type <ival> progstart remember mremember '&'
%type <opval> block mblock lineseq line loop cond else
%type <opval> expr term subscripted scalar ary hsh arylen star amper sideff
%type <opval> argexpr nexpr texpr iexpr mexpr mnexpr mtexpr miexpr
%nonassoc PREC_LOW
%nonassoc LOOPEX
-%left <ival> OROP
+%left <ival> OROP DOROP
%left ANDOP
%right NOTOP
%nonassoc LSTOP LSTOPSUB
%right <ival> ASSIGNOP
%right '?' ':'
%nonassoc DOTDOT
-%left OROR
+%left OROR DORDOR
%left ANDAND
%left <ival> BITOROP
%left <ival> BITANDOP
%% /* RULES */
/* The whole program */
-prog : /* NULL */
- {
-#if defined(YYDEBUG) && defined(DEBUGGING)
- yydebug = (DEBUG_p_TEST);
-#endif
- PL_expect = XSTATE; $$ = block_start(TRUE);
- }
+prog : progstart
/*CONTINUED*/ lineseq
- { newPROG(block_end($1,$2)); }
+ { $$ = $1; newPROG(block_end($1,$2)); }
;
/* An ordinary block */
block : '{' remember lineseq '}'
{ if (PL_copline > (line_t)$1)
- PL_copline = $1;
+ PL_copline = (line_t)$1;
$$ = block_end($2, $3); }
;
{ $$ = block_start(TRUE); }
;
+progstart:
+ {
+#if defined(YYDEBUG) && defined(DEBUGGING)
+ yydebug = (DEBUG_p_TEST);
+#endif
+ PL_expect = XSTATE; $$ = block_start(TRUE);
+ }
+ ;
+
+
mblock : '{' mremember lineseq '}'
{ if (PL_copline > (line_t)$1)
- PL_copline = $1;
+ PL_copline = (line_t)$1;
$$ = block_end($2, $3); }
;
| expr UNTIL iexpr
{ $$ = newLOOPOP(OPf_PARENS, 1, $3, $1);}
| expr FOR expr
- { $$ = newFOROP(0, Nullch, $2,
+ { $$ = newFOROP(0, Nullch, (line_t)$2,
Nullop, $3, $1, Nullop); }
;
| ELSE mblock
{ ($2)->op_flags |= OPf_PARENS; $$ = scope($2); }
| ELSIF '(' mexpr ')' mblock else
- { PL_copline = $1;
+ { PL_copline = (line_t)$1;
$$ = newCONDOP(0, $3, scope($5), $6);
PL_hints |= HINT_BLOCK_SCOPE; }
;
/* Real conditional expressions */
cond : IF '(' remember mexpr ')' mblock else
- { PL_copline = $1;
+ { PL_copline = (line_t)$1;
$$ = block_end($3,
newCONDOP(0, $4, scope($6), $7)); }
| UNLESS '(' remember miexpr ')' mblock else
- { PL_copline = $1;
+ { PL_copline = (line_t)$1;
$$ = block_end($3,
newCONDOP(0, $4, scope($6), $7)); }
;
/* Loops: while, until, for, and a bare block */
loop : label WHILE '(' remember mtexpr ')' mblock cont
- { PL_copline = $2;
+ { PL_copline = (line_t)$2;
$$ = block_end($4,
newSTATEOP(0, $1,
newWHILEOP(0, 1, (LOOP*)Nullop,
$2, $5, $7, $8))); }
| label UNTIL '(' remember miexpr ')' mblock cont
- { PL_copline = $2;
+ { PL_copline = (line_t)$2;
$$ = block_end($4,
newSTATEOP(0, $1,
newWHILEOP(0, 1, (LOOP*)Nullop,
$2, $5, $7, $8))); }
| label FOR MY remember my_scalar '(' mexpr ')' mblock cont
{ $$ = block_end($4,
- newFOROP(0, $1, $2, $5, $7, $9, $10)); }
+ newFOROP(0, $1, (line_t)$2, $5, $7, $9, $10)); }
| label FOR scalar '(' remember mexpr ')' mblock cont
{ $$ = block_end($5,
- newFOROP(0, $1, $2, mod($3, OP_ENTERLOOP),
+ newFOROP(0, $1, (line_t)$2, mod($3, OP_ENTERLOOP),
$6, $8, $9)); }
| label FOR '(' remember mexpr ')' mblock cont
{ $$ = block_end($4,
- newFOROP(0, $1, $2, Nullop, $5, $7, $8)); }
+ newFOROP(0, $1, (line_t)$2, Nullop, $5, $7, $8)); }
| label FOR '(' remember mnexpr ';' mtexpr ';' mnexpr ')' mblock
/* basically fake up an initialize-while lineseq */
{ OP *forop;
- PL_copline = $2;
+ PL_copline = (line_t)$2;
forop = newSTATEOP(0, $1,
newWHILEOP(0, 1, (LOOP*)Nullop,
$2, scalar($7),
{ $$ = newLOGOP(OP_AND, 0, $1, $3); }
| expr OROP expr
{ $$ = newLOGOP($2, 0, $1, $3); }
+ | expr DOROP expr
+ { $$ = newLOGOP(OP_DOR, 0, $1, $3); }
| argexpr %prec PREC_LOW
;
{ $$ = convert($1, 0, $2); }
| FUNC '(' listexprcom ')' /* print (@args) */
{ $$ = convert($1, 0, $3); }
- | LSTOPSUB startanonsub block /* map { foo } ... */
+ | LSTOPSUB startanonsub block /* map { foo } ... */
{ $3 = newANONATTRSUB($2, 0, Nullop, $3); }
listexpr %prec LSTOP /* ... @bar */
{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
{ $$ = newLOGOP(OP_AND, 0, $1, $3); }
| term OROR term /* $x || $y */
{ $$ = newLOGOP(OP_OR, 0, $1, $3); }
+ | term DORDOR term /* $x // $y */
+ { $$ = newLOGOP(OP_DOR, 0, $1, $3); }
| term MATCHOP term /* $x =~ /$y/ */
{ $$ = bind_match($2, $1, $3); }
;
| '[' ']'
{ $$ = newANONLIST(Nullop); }
| HASHBRACK expr ';' '}' %prec '(' /* { foo => "Bar" } */
- { $$ = newANONHASH($2); }
+ { $$ = newANONHASH($2); }
| HASHBRACK ';' '}' %prec '(' /* { } (';' by tokener) */
{ $$ = newANONHASH(Nullop); }
| ANONSUB startanonsub proto subattrlist block %prec '('
{ $$ = $1; }
| amper /* &foo; */
{ $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); }
- | amper '(' ')' /* &foo() */
+ | amper '(' ')' /* &foo() */
{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); }
| amper '(' expr ')' /* &foo(@args) */
{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,