Re: [perl #41071] require stringifies code references in tied @INC
[p5sagit/p5-mst-13.2.git] / perly.y
CommitLineData
a0d0e21e 1/* perly.y
a687059c 2 *
f05e27e5 3 * Copyright (c) 1991-2002, 2003, 2004, 2005, 2006 Larry Wall
a687059c 4 *
9ef589d8 5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
8d063cd8 7 *
a0d0e21e 8 */
9
10/*
11 * 'I see,' laughed Strider. 'I look foul and feel fair. Is that it?
14a38fd5 12 * All that is gold does not glitter, not all those who wander are lost.'
f05e27e5 13 *
14 * This file holds the grammar for the Perl language. If edited, you need
166f8a29 15 * to run regen_perly.pl, which re-creates the files perly.h, perly.tab
16 * and perly.act which are derived from this.
17 *
f05e27e5 18 * Note that these derived files are included and compiled twice; once
19 * from perly.c, and once from madly.c. The second time, a number of MAD
20 * macros are defined, which compile in extra code that allows the parse
21 * tree to be accurately dumped. In particular:
22 *
23 * MAD defined if compiling madly.c
24 * DO_MAD(A) expands to A under madly.c, to null otherwise
25 * IF_MAD(a,b) expands to A under madly.c, to B otherwise
26 * TOKEN_GETMAD() expands to token_getmad() under madly.c, to null otherwise
27 * TOKEN_FREE() similarly
28 * OP_GETMAD() similarly
29 * IVAL(i) expands to (i)->tk_lval.ival or (i)
30 * PVAL(p) expands to (p)->tk_lval.pval or (p)
31 *
166f8a29 32 * The main job of of this grammar is to call the various newFOO()
33 * functions in op.c to build a syntax tree of OP structs.
61296642 34 * It relies on the lexer in toke.c to do the tokenizing.
29522234 35 *
36 * Note: due to the way that the cleanup code works WRT to freeing ops on
37 * the parse stack, it is dangerous to assign to the $n variables within
38 * an action.
166f8a29 39 */
40
0de566d7 41/* Make the parser re-entrant. */
8d063cd8 42
0de566d7 43%pure_parser
8d063cd8 44
f05e27e5 45/* FIXME for MAD - is the new mintro on while and until important? */
46
0de566d7 47%start prog
9d116dd7 48
8d063cd8 49%union {
d5c6462e 50 I32 ival; /* __DEFAULT__ (marker for regen_perly.pl;
51 must always be 1st union member) */
79072805 52 char *pval;
53 OP *opval;
54 GV *gvval;
f05e27e5 55#ifdef PERL_IN_MADLY_C
56 TOKEN* p_tkval;
123d08c9 57 TOKEN* i_tkval;
f05e27e5 58#else
59 char *p_tkval;
123d08c9 60 I32 i_tkval;
61#endif
62#ifdef PERL_MAD
63 TOKEN* tkval;
f05e27e5 64#endif
8d063cd8 65}
66
123d08c9 67%token <i_tkval> '{' '}' '[' ']' '-' '+' '$' '@' '%' '*' '&' ';'
f0fcb552 68
a0d0e21e 69%token <opval> WORD METHOD FUNCMETH THING PMFUNC PRIVATEREF
4633a7c4 70%token <opval> FUNC0SUB UNIOPSUB LSTOPSUB
f05e27e5 71%token <p_tkval> LABEL
123d08c9 72%token <i_tkval> FORMAT SUB ANONSUB PACKAGE USE
73%token <i_tkval> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR
74%token <i_tkval> GIVEN WHEN DEFAULT
75%token <i_tkval> LOOPEX DOTDOT
76%token <i_tkval> FUNC0 FUNC1 FUNC UNIOP LSTOP
77%token <i_tkval> RELOP EQOP MULOP ADDOP
78%token <i_tkval> DOLSHARP DO HASHBRACK NOAMP
79%token <i_tkval> LOCAL MY MYSUB REQUIRE
80%token <i_tkval> COLONATTR
f05e27e5 81
82%type <ival> prog progstart remember mremember savescope
83%type <ival> startsub startanonsub startformsub
84/* FIXME for MAD - are these two ival? */
85%type <ival> mydefsv mintro
86
87%type <opval> decl format subrout mysubrout package use peg
88
bbce6d69 89%type <opval> block mblock lineseq line loop cond else
fad39ff1 90%type <opval> expr term subscripted scalar ary hsh arylen star amper sideff
a034e688 91%type <opval> argexpr nexpr texpr iexpr mexpr mnexpr miexpr
44a8e56a 92%type <opval> listexpr listexprcom indirob listop method
93%type <opval> formname subname proto subbody cont my_scalar
f05e27e5 94%type <opval> subattrlist myattrlist myattrterm myterm
891be019 95%type <opval> termbinop termunop anonymous termdo
0d863452 96%type <opval> switch case
f05e27e5 97%type <p_tkval> label
79072805 98
123d08c9 99%nonassoc <i_tkval> PREC_LOW
fad39ff1 100%nonassoc LOOPEX
101
123d08c9 102%left <i_tkval> OROP DOROP
103%left <i_tkval> ANDOP
104%right <i_tkval> NOTOP
36477c24 105%nonassoc LSTOP LSTOPSUB
123d08c9 106%left <i_tkval> ','
107%right <i_tkval> ASSIGNOP
108%right <i_tkval> '?' ':'
8d063cd8 109%nonassoc DOTDOT
123d08c9 110%left <i_tkval> OROR DORDOR
111%left <i_tkval> ANDAND
112%left <i_tkval> BITOROP
113%left <i_tkval> BITANDOP
a687059c 114%nonassoc EQOP
115%nonassoc RELOP
36477c24 116%nonassoc UNIOP UNIOPSUB
20515881 117%nonassoc REQUIRE
123d08c9 118%left <i_tkval> SHIFTOP
a687059c 119%left ADDOP
120%left MULOP
123d08c9 121%left <i_tkval> MATCHOP
122%right <i_tkval> '!' '~' UMINUS REFGEN
123%right <i_tkval> POWOP
124%nonassoc <i_tkval> PREINC PREDEC POSTINC POSTDEC
125%left <i_tkval> ARROW
126%nonassoc <i_tkval> ')'
127%left <i_tkval> '('
fad39ff1 128%left '[' '{'
8d063cd8 129
123d08c9 130%token <i_tkval> PEG
7f46837f 131
8d063cd8 132%% /* RULES */
133
891be019 134/* The whole program */
ecb2f335 135prog : progstart
ae986130 136 /*CONTINUED*/ lineseq
ecb2f335 137 { $$ = $1; newPROG(block_end($1,$2)); }
8d063cd8 138 ;
139
891be019 140/* An ordinary block */
a687059c 141block : '{' remember lineseq '}'
f05e27e5 142 { if (PL_copline > (line_t)IVAL($1))
143 PL_copline = (line_t)IVAL($1);
144 $$ = block_end($2, $3);
145 TOKEN_GETMAD($1,$$,'{');
146 TOKEN_GETMAD($4,$$,'}');
147 }
a0d0e21e 148 ;
149
55497cff 150remember: /* NULL */ /* start a full lexical scope */
151 { $$ = block_start(TRUE); }
152 ;
153
0d863452 154mydefsv: /* NULL */ /* lexicalize $_ */
155 { $$ = (I32) allocmy("$_"); }
156 ;
157
ecb2f335 158progstart:
159 {
ecb2f335 160 PL_expect = XSTATE; $$ = block_start(TRUE);
161 }
162 ;
163
164
bbce6d69 165mblock : '{' mremember lineseq '}'
f05e27e5 166 { if (PL_copline > (line_t)IVAL($1))
167 PL_copline = (line_t)IVAL($1);
168 $$ = block_end($2, $3);
169 TOKEN_GETMAD($1,$$,'{');
170 TOKEN_GETMAD($4,$$,'}');
171 }
55497cff 172 ;
173
174mremember: /* NULL */ /* start a partial lexical scope */
175 { $$ = block_start(FALSE); }
8d063cd8 176 ;
177
500bedb6 178savescope: /* NULL */ /* remember stack pos in case of error */
179 { $$ = PL_savestack_ix; }
180
891be019 181/* A collection of "lines" in the program */
8d063cd8 182lineseq : /* NULL */
79072805 183 { $$ = Nullop; }
184 | lineseq decl
f05e27e5 185 {
186 $$ = IF_MAD(
187 append_list(OP_LINESEQ,
188 (LISTOP*)$1, (LISTOP*)$2),
189 $1);
190 }
500bedb6 191 | lineseq savescope line
192 { LEAVE_SCOPE($2);
193 $$ = append_list(OP_LINESEQ,
194 (LISTOP*)$1, (LISTOP*)$3);
3280af22 195 PL_pad_reset_pending = TRUE;
500bedb6 196 if ($1 && $3) PL_hints |= HINT_BLOCK_SCOPE; }
8d063cd8 197 ;
198
891be019 199/* A "line" in the program */
79072805 200line : label cond
f05e27e5 201 { $$ = newSTATEOP(0, PVAL($1), $2);
202 TOKEN_GETMAD($1,((LISTOP*)$$)->op_first,'L'); }
8d063cd8 203 | loop /* loops add their own labels */
0d863452 204 | switch /* ... and so do switches */
205 { $$ = $1; }
206 | label case
f05e27e5 207 { $$ = newSTATEOP(0, PVAL($1), $2); }
8d063cd8 208 | label ';'
f05e27e5 209 {
210 if (PVAL($1)) {
211 $$ = newSTATEOP(0, PVAL($1), newOP(OP_NULL, 0));
212 TOKEN_GETMAD($1,$$,'L');
213 TOKEN_GETMAD($2,((LISTOP*)$$)->op_first,';');
214 }
215 else {
216 $$ = IF_MAD(
217 newOP(OP_NULL, 0),
218 Nullop);
219 PL_copline = NOLINE;
220 TOKEN_FREE($1);
221 TOKEN_GETMAD($2,$$,';');
222 }
223 PL_expect = XSTATE;
224 }
8d063cd8 225 | label sideff ';'
f05e27e5 226 {
227 $$ = newSTATEOP(0, PVAL($1), $2);
228 PL_expect = XSTATE;
229 DO_MAD(
230 /* sideff might already have a nexstate */
231 OP* op = ((LISTOP*)$$)->op_first;
232 if (op) {
233 while (op->op_sibling &&
234 op->op_sibling->op_type == OP_NEXTSTATE)
235 op = op->op_sibling;
236 token_getmad($1,op,'L');
237 token_getmad($3,op,';');
238 }
239 )
240 }
8d063cd8 241 ;
242
891be019 243/* An expression which may have a side-effect */
a687059c 244sideff : error
79072805 245 { $$ = Nullop; }
a687059c 246 | expr
79072805 247 { $$ = $1; }
a687059c 248 | expr IF expr
f05e27e5 249 { $$ = newLOGOP(OP_AND, 0, $3, $1);
250 TOKEN_GETMAD($2,$$,'i');
251 }
a687059c 252 | expr UNLESS expr
f05e27e5 253 { $$ = newLOGOP(OP_OR, 0, $3, $1);
254 TOKEN_GETMAD($2,$$,'i');
255 }
a687059c 256 | expr WHILE expr
f05e27e5 257 { $$ = newLOOPOP(OPf_PARENS, 1, scalar($3), $1);
258 TOKEN_GETMAD($2,$$,'w');
259 }
55497cff 260 | expr UNTIL iexpr
f05e27e5 261 { $$ = newLOOPOP(OPf_PARENS, 1, $3, $1);
262 TOKEN_GETMAD($2,$$,'w');
263 }
ecca16b0 264 | expr FOR expr
f05e27e5 265 { $$ = newFOROP(0, Nullch, (line_t)IVAL($2),
266 Nullop, $3, $1, Nullop);
267 TOKEN_GETMAD($2,((LISTOP*)$$)->op_first->op_sibling,'w');
268 }
79072805 269 ;
270
891be019 271/* else and elsif blocks */
79072805 272else : /* NULL */
273 { $$ = Nullop; }
55497cff 274 | ELSE mblock
f05e27e5 275 { ($2)->op_flags |= OPf_PARENS; $$ = scope($2);
276 TOKEN_GETMAD($1,$$,'o');
277 }
55497cff 278 | ELSIF '(' mexpr ')' mblock else
f05e27e5 279 { PL_copline = (line_t)IVAL($1);
2c15bef3 280 $$ = newCONDOP(0, $3, scope($5), $6);
f05e27e5 281 PL_hints |= HINT_BLOCK_SCOPE;
282 TOKEN_GETMAD($1,$$,'I');
283 TOKEN_GETMAD($2,$$,'(');
284 TOKEN_GETMAD($4,$$,')');
285 }
79072805 286 ;
287
891be019 288/* Real conditional expressions */
55497cff 289cond : IF '(' remember mexpr ')' mblock else
f05e27e5 290 { PL_copline = (line_t)IVAL($1);
36477c24 291 $$ = block_end($3,
f05e27e5 292 newCONDOP(0, $4, scope($6), $7));
293 TOKEN_GETMAD($1,$$,'I');
294 TOKEN_GETMAD($2,$$,'(');
295 TOKEN_GETMAD($5,$$,')');
296 }
55497cff 297 | UNLESS '(' remember miexpr ')' mblock else
f05e27e5 298 { PL_copline = (line_t)IVAL($1);
36477c24 299 $$ = block_end($3,
f05e27e5 300 newCONDOP(0, $4, scope($6), $7));
301 TOKEN_GETMAD($1,$$,'I');
302 TOKEN_GETMAD($2,$$,'(');
303 TOKEN_GETMAD($5,$$,')');
304 }
79072805 305 ;
306
0d863452 307/* Cases for a switch statement */
308case : WHEN '(' remember mexpr ')' mblock
309 { $$ = block_end($3,
310 newWHENOP($4, scope($6))); }
311 | DEFAULT block
312 { $$ = newWHENOP(0, scope($2)); }
313 ;
314
891be019 315/* Continue blocks */
79072805 316cont : /* NULL */
317 { $$ = Nullop; }
318 | CONTINUE block
f05e27e5 319 { $$ = scope($2);
320 TOKEN_GETMAD($1,$$,'o');
321 }
79072805 322 ;
323
891be019 324/* Loops: while, until, for, and a bare block */
a034e688 325loop : label WHILE '(' remember texpr ')' mintro mblock cont
f05e27e5 326 { OP *innerop;
327 PL_copline = (line_t)$2;
36477c24 328 $$ = block_end($4,
f05e27e5 329 newSTATEOP(0, PVAL($1),
330 innerop = newWHILEOP(0, 1, (LOOP*)Nullop,
331 IVAL($2), $5, $8, $9, $7)));
332 TOKEN_GETMAD($1,innerop,'L');
333 TOKEN_GETMAD($2,innerop,'W');
334 TOKEN_GETMAD($3,innerop,'(');
335 TOKEN_GETMAD($6,innerop,')');
336 }
337
a034e688 338 | label UNTIL '(' remember iexpr ')' mintro mblock cont
f05e27e5 339 { OP *innerop;
340 PL_copline = (line_t)$2;
36477c24 341 $$ = block_end($4,
f05e27e5 342 newSTATEOP(0, PVAL($1),
343 innerop = newWHILEOP(0, 1, (LOOP*)Nullop,
344 IVAL($2), $5, $8, $9, $7)));
345 TOKEN_GETMAD($1,innerop,'L');
346 TOKEN_GETMAD($2,innerop,'W');
347 TOKEN_GETMAD($3,innerop,'(');
348 TOKEN_GETMAD($6,innerop,')');
349 }
bbce6d69 350 | label FOR MY remember my_scalar '(' mexpr ')' mblock cont
f05e27e5 351 { OP *innerop;
352 $$ = block_end($4,
353 innerop = newFOROP(0, PVAL($1), (line_t)IVAL($2),
354 $5, $7, $9, $10));
355 TOKEN_GETMAD($1,((LISTOP*)innerop)->op_first,'L');
356 TOKEN_GETMAD($2,((LISTOP*)innerop)->op_first->op_sibling,'W');
357 TOKEN_GETMAD($3,((LISTOP*)innerop)->op_first->op_sibling,'d');
358 TOKEN_GETMAD($6,((LISTOP*)innerop)->op_first->op_sibling,'(');
359 TOKEN_GETMAD($8,((LISTOP*)innerop)->op_first->op_sibling,')');
360 }
bbce6d69 361 | label FOR scalar '(' remember mexpr ')' mblock cont
f05e27e5 362 { OP *innerop;
363 $$ = block_end($5,
364 innerop = newFOROP(0, PVAL($1), (line_t)IVAL($2),
365 mod($3, OP_ENTERLOOP), $6, $8, $9));
366 TOKEN_GETMAD($1,((LISTOP*)innerop)->op_first,'L');
367 TOKEN_GETMAD($2,((LISTOP*)innerop)->op_first->op_sibling,'W');
368 TOKEN_GETMAD($4,((LISTOP*)innerop)->op_first->op_sibling,'(');
369 TOKEN_GETMAD($7,((LISTOP*)innerop)->op_first->op_sibling,')');
370 }
bbce6d69 371 | label FOR '(' remember mexpr ')' mblock cont
f05e27e5 372 { OP *innerop;
373 $$ = block_end($4,
374 innerop = newFOROP(0, PVAL($1), (line_t)IVAL($2),
375 Nullop, $5, $7, $8));
376 TOKEN_GETMAD($1,((LISTOP*)innerop)->op_first,'L');
377 TOKEN_GETMAD($2,((LISTOP*)innerop)->op_first->op_sibling,'W');
378 TOKEN_GETMAD($3,((LISTOP*)innerop)->op_first->op_sibling,'(');
379 TOKEN_GETMAD($6,((LISTOP*)innerop)->op_first->op_sibling,')');
380 }
a034e688 381 | label FOR '(' remember mnexpr ';' texpr ';' mintro mnexpr ')'
382 mblock
8d063cd8 383 /* basically fake up an initialize-while lineseq */
36c66720 384 { OP *forop;
f05e27e5 385 PL_copline = (line_t)IVAL($2);
386 forop = newSTATEOP(0, PVAL($1),
36c66720 387 newWHILEOP(0, 1, (LOOP*)Nullop,
f05e27e5 388 IVAL($2), scalar($7),
a034e688 389 $12, $10, $9));
f05e27e5 390#ifdef MAD
f05e27e5 391 forop = newUNOP(OP_NULL, 0, append_elem(OP_LINESEQ,
392 newSTATEOP(0,
393 (($1)->tk_lval.pval
394 ?savepv(($1)->tk_lval.pval):Nullch),
29522234 395 ($5 ? newOP(OP_NULL, 0) : $5) ),
f05e27e5 396 forop));
397
398 token_getmad($2,forop,'3');
399 token_getmad($3,forop,'(');
400 token_getmad($6,forop,'1');
401 token_getmad($8,forop,'2');
402 token_getmad($11,forop,')');
403 token_getmad($1,forop,'L');
404#else
36c66720 405 if ($5) {
406 forop = append_elem(OP_LINESEQ,
407 newSTATEOP(0, ($1?savepv($1):Nullch),
408 $5),
409 forop);
410 }
411
f05e27e5 412
413#endif
36c66720 414 $$ = block_end($4, forop); }
79072805 415 | label block cont /* a block is a loop that happens once */
f05e27e5 416 { $$ = newSTATEOP(0, PVAL($1),
fb73857a 417 newWHILEOP(0, 1, (LOOP*)Nullop,
f05e27e5 418 NOLINE, Nullop, $2, $3, 0));
419 TOKEN_GETMAD($1,((LISTOP*)$$)->op_first,'L'); }
8d063cd8 420 ;
421
0d863452 422/* Switch blocks */
423switch : label GIVEN '(' remember mydefsv mexpr ')' mblock
424 { PL_copline = (line_t) $2;
425 $$ = block_end($4,
f05e27e5 426 newSTATEOP(0, PVAL($1),
0d863452 427 newGIVENOP($6, scope($8),
428 (PADOFFSET) $5) )); }
429 ;
430
a034e688 431/* determine whether there are any new my declarations */
432mintro : /* NULL */
433 { $$ = (PL_min_intro_pending &&
434 PL_max_intro_pending >= PL_min_intro_pending);
435 intro_my(); }
436
891be019 437/* Normal expression */
8d063cd8 438nexpr : /* NULL */
79072805 439 { $$ = Nullop; }
8d063cd8 440 | sideff
441 ;
442
891be019 443/* Boolean expression */
8d063cd8 444texpr : /* NULL means true */
f05e27e5 445 { YYSTYPE tmplval;
446 (void)scan_num("1", &tmplval);
447 $$ = tmplval.opval; }
8d063cd8 448 | expr
449 ;
450
891be019 451/* Inverted boolean expression */
55497cff 452iexpr : expr
453 { $$ = invert(scalar($1)); }
454 ;
455
891be019 456/* Expression with its own lexical scope */
55497cff 457mexpr : expr
bbce6d69 458 { $$ = $1; intro_my(); }
459 ;
460
461mnexpr : nexpr
462 { $$ = $1; intro_my(); }
55497cff 463 ;
464
55497cff 465miexpr : iexpr
bbce6d69 466 { $$ = $1; intro_my(); }
55497cff 467 ;
468
891be019 469/* Optional "MAIN:"-style loop labels */
8d063cd8 470label : /* empty */
f05e27e5 471 {
472#ifdef MAD
473 YYSTYPE tmplval;
474 tmplval.pval = Nullch;
475 $$ = newTOKEN(OP_NULL, tmplval, 0);
476#else
477 $$ = Nullch;
478#endif
479 }
32c2e4fb 480 | LABEL
8d063cd8 481 ;
482
f05e27e5 483/* Some kind of declaration - just hang on peg in the parse tree */
8d063cd8 484decl : format
f05e27e5 485 { $$ = $1; }
8d063cd8 486 | subrout
f05e27e5 487 { $$ = $1; }
09bef843 488 | mysubrout
f05e27e5 489 { $$ = $1; }
a687059c 490 | package
f05e27e5 491 { $$ = $1; }
a0d0e21e 492 | use
f05e27e5 493 { $$ = $1; }
494
495 /* these two are only used by MAD */
496
497 | peg
498 { $$ = $1; }
499 ;
500
501peg : PEG
502 { $$ = newOP(OP_NULL,0);
503 TOKEN_GETMAD($1,$$,'p');
504 }
8d063cd8 505 ;
506
718a7425 507format : FORMAT startformsub formname block
a8ff2fa6 508 { SvREFCNT_inc(PL_compcv);
f05e27e5 509#ifdef MAD
718a7425 510 $$ = newFORM($2, $3, $4);
f05e27e5 511 prepend_madprops($1->tk_mad, $$, 'F');
512 $1->tk_mad = 0;
513 token_free($1);
514#else
718a7425 515 newFORM($2, $3, $4);
30994c59 516 $$ = Nullop;
f05e27e5 517#endif
518 }
44a8e56a 519 ;
520
521formname: WORD { $$ = $1; }
522 | /* NULL */ { $$ = Nullop; }
8d063cd8 523 ;
524
891be019 525/* Unimplemented "my sub foo { }" */
718a7425 526mysubrout: MYSUB startsub subname proto subattrlist subbody
a8ff2fa6 527 { SvREFCNT_inc(PL_compcv);
f05e27e5 528#ifdef MAD
718a7425 529 $$ = newMYSUB($2, $3, $4, $5, $6);
f05e27e5 530 token_getmad($1,$$,'d');
531#else
718a7425 532 newMYSUB($2, $3, $4, $5, $6);
30994c59 533 $$ = Nullop;
f05e27e5 534#endif
535 }
09bef843 536 ;
537
891be019 538/* Subroutine definition */
718a7425 539subrout : SUB startsub subname proto subattrlist subbody
a8ff2fa6 540 { SvREFCNT_inc(PL_compcv);
f05e27e5 541#ifdef MAD
542 OP* o = newSVOP(OP_ANONCODE, 0,
718a7425 543 (SV*)newATTRSUB($2, $3, $4, $5, $6));
f05e27e5 544 $$ = newOP(OP_NULL,0);
545 op_getmad(o,$$,'&');
718a7425 546 op_getmad($3,$$,'n');
547 op_getmad($4,$$,'s');
548 op_getmad($5,$$,'a');
f05e27e5 549 token_getmad($1,$$,'d');
718a7425 550 append_madprops($6->op_madprop, $$, 0);
551 $6->op_madprop = 0;
f05e27e5 552#else
718a7425 553 newATTRSUB($2, $3, $4, $5, $6);
f05e27e5 554 $$ = Nullop;
555#endif
556 }
28757baa 557 ;
558
fa83b5b6 559startsub: /* NULL */ /* start a regular subroutine scope */
a8ff2fa6 560 { $$ = start_subparse(FALSE, 0);
561 SAVEFREESV(PL_compcv); }
f05e27e5 562
28757baa 563 ;
564
565startanonsub: /* NULL */ /* start an anonymous subroutine scope */
a8ff2fa6 566 { $$ = start_subparse(FALSE, CVf_ANON);
567 SAVEFREESV(PL_compcv); }
28757baa 568 ;
569
44a8e56a 570startformsub: /* NULL */ /* start a format subroutine scope */
a8ff2fa6 571 { $$ = start_subparse(TRUE, 0);
572 SAVEFREESV(PL_compcv); }
44a8e56a 573 ;
574
891be019 575/* Name of a subroutine - must be a bareword, could be special */
2596d9fe 576subname : WORD { const char *const name = SvPV_nolen_const(((SVOP*)$1)->op_sv);
e858de61 577 if (strEQ(name, "BEGIN") || strEQ(name, "END")
3c10abe3 578 || strEQ(name, "INIT") || strEQ(name, "CHECK")
579 || strEQ(name, "UNITCHECK"))
1aff0e91 580 CvSPECIAL_on(PL_compcv);
28757baa 581 $$ = $1; }
a0d0e21e 582 ;
583
891be019 584/* Subroutine prototype */
4633a7c4 585proto : /* NULL */
586 { $$ = Nullop; }
587 | THING
588 ;
28757baa 589
891be019 590/* Optional list of subroutine attributes */
09bef843 591subattrlist: /* NULL */
592 { $$ = Nullop; }
593 | COLONATTR THING
f05e27e5 594 { $$ = $2;
595 TOKEN_GETMAD($1,$$,':');
596 }
09bef843 597 | COLONATTR
f05e27e5 598 { $$ = IF_MAD(
599 newOP(OP_NULL, 0),
600 Nullop
601 );
602 TOKEN_GETMAD($1,$$,':');
603 }
09bef843 604 ;
605
891be019 606/* List of attributes for a "my" variable declaration */
09bef843 607myattrlist: COLONATTR THING
f05e27e5 608 { $$ = $2;
609 TOKEN_GETMAD($1,$$,':');
610 }
09bef843 611 | COLONATTR
f05e27e5 612 { $$ = IF_MAD(
613 newOP(OP_NULL, 0),
614 Nullop
615 );
616 TOKEN_GETMAD($1,$$,':');
617 }
09bef843 618 ;
619
891be019 620/* Subroutine body - either null or a block */
28757baa 621subbody : block { $$ = $1; }
f05e27e5 622 | ';' { $$ = IF_MAD(
623 newOP(OP_NULL,0),
624 Nullop
625 );
626 PL_expect = XSTATE;
627 TOKEN_GETMAD($1,$$,';');
628 }
8d063cd8 629 ;
630
a687059c 631package : PACKAGE WORD ';'
f05e27e5 632 {
633#ifdef MAD
634 $$ = package($2);
635 token_getmad($1,$$,'o');
636 token_getmad($3,$$,';');
637#else
638 package($2);
30994c59 639 $$ = Nullop;
f05e27e5 640#endif
641 }
a687059c 642 ;
643
718a7425 644use : USE startsub
1aff0e91 645 { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ }
28757baa 646 WORD WORD listexpr ';'
f05e27e5 647 { SvREFCNT_inc(PL_compcv);
648#ifdef MAD
718a7425 649 $$ = utilize(IVAL($1), $2, $4, $5, $6);
f05e27e5 650 token_getmad($1,$$,'o');
718a7425 651 token_getmad($7,$$,';');
f05e27e5 652 if (PL_rsfp_filters && AvFILLp(PL_rsfp_filters) >= 0)
653 append_madprops(newMADPROP('!', MAD_PV, "", 0), $$, 0);
654#else
718a7425 655 utilize(IVAL($1), $2, $4, $5, $6);
30994c59 656 $$ = Nullop;
f05e27e5 657#endif
658 }
85e6fe83 659 ;
660
891be019 661/* Ordinary expressions; logical combinations */
a0d0e21e 662expr : expr ANDOP expr
f05e27e5 663 { $$ = newLOGOP(OP_AND, 0, $1, $3);
664 TOKEN_GETMAD($2,$$,'o');
665 }
a0d0e21e 666 | expr OROP expr
f05e27e5 667 { $$ = newLOGOP(IVAL($2), 0, $1, $3);
668 TOKEN_GETMAD($2,$$,'o');
669 }
c963b151 670 | expr DOROP expr
f05e27e5 671 { $$ = newLOGOP(OP_DOR, 0, $1, $3);
672 TOKEN_GETMAD($2,$$,'o');
673 }
fad39ff1 674 | argexpr %prec PREC_LOW
a0d0e21e 675 ;
676
891be019 677/* Expressions are a list of terms joined by commas */
a0d0e21e 678argexpr : argexpr ','
f05e27e5 679 {
680#ifdef MAD
681 OP* op = newNULLLIST();
682 token_getmad($2,op,',');
683 $$ = append_elem(OP_LIST, $1, op);
684#else
685 $$ = $1;
686#endif
687 }
a0d0e21e 688 | argexpr ',' term
f05e27e5 689 {
29522234 690 OP* term = $3;
f05e27e5 691 DO_MAD(
29522234 692 term = newUNOP(OP_NULL, 0, term);
693 token_getmad($2,term,',');
f05e27e5 694 )
29522234 695 $$ = append_elem(OP_LIST, $1, term);
f05e27e5 696 }
fad39ff1 697 | term %prec PREC_LOW
8d063cd8 698 ;
699
891be019 700/* List operators */
ad4673e5 701listop : LSTOP indirob argexpr /* map {...} @args or print $fh @args */
f05e27e5 702 { $$ = convert(IVAL($1), OPf_STACKED,
703 prepend_elem(OP_LIST, newGVREF(IVAL($1),$2), $3) );
704 TOKEN_GETMAD($1,$$,'o');
705 }
891be019 706 | FUNC '(' indirob expr ')' /* print ($fh @args */
f05e27e5 707 { $$ = convert(IVAL($1), OPf_STACKED,
708 prepend_elem(OP_LIST, newGVREF(IVAL($1),$3), $4) );
709 TOKEN_GETMAD($1,$$,'o');
710 TOKEN_GETMAD($2,$$,'(');
711 TOKEN_GETMAD($5,$$,')');
712 }
891be019 713 | term ARROW method '(' listexprcom ')' /* $foo->bar(list) */
4633a7c4 714 { $$ = convert(OP_ENTERSUB, OPf_STACKED,
a0d0e21e 715 append_elem(OP_LIST,
55497cff 716 prepend_elem(OP_LIST, scalar($1), $5),
f05e27e5 717 newUNOP(OP_METHOD, 0, $3)));
718 TOKEN_GETMAD($2,$$,'A');
719 TOKEN_GETMAD($4,$$,'(');
720 TOKEN_GETMAD($6,$$,')');
721 }
891be019 722 | term ARROW method /* $foo->bar */
b1524f17 723 { $$ = convert(OP_ENTERSUB, OPf_STACKED,
724 append_elem(OP_LIST, scalar($1),
f05e27e5 725 newUNOP(OP_METHOD, 0, $3)));
726 TOKEN_GETMAD($2,$$,'A');
727 }
891be019 728 | METHOD indirob listexpr /* new Class @args */
4633a7c4 729 { $$ = convert(OP_ENTERSUB, OPf_STACKED,
a0d0e21e 730 append_elem(OP_LIST,
4633a7c4 731 prepend_elem(OP_LIST, $2, $3),
f05e27e5 732 newUNOP(OP_METHOD, 0, $1)));
733 }
891be019 734 | FUNCMETH indirob '(' listexprcom ')' /* method $object (@args) */
4633a7c4 735 { $$ = convert(OP_ENTERSUB, OPf_STACKED,
a0d0e21e 736 append_elem(OP_LIST,
4633a7c4 737 prepend_elem(OP_LIST, $2, $4),
f05e27e5 738 newUNOP(OP_METHOD, 0, $1)));
739 TOKEN_GETMAD($3,$$,'(');
740 TOKEN_GETMAD($5,$$,')');
741 }
891be019 742 | LSTOP listexpr /* print @args */
f05e27e5 743 { $$ = convert(IVAL($1), 0, $2);
744 TOKEN_GETMAD($1,$$,'o');
745 }
891be019 746 | FUNC '(' listexprcom ')' /* print (@args) */
f05e27e5 747 { $$ = convert(IVAL($1), 0, $3);
748 TOKEN_GETMAD($1,$$,'o');
749 TOKEN_GETMAD($2,$$,'(');
750 TOKEN_GETMAD($4,$$,')');
751 }
718a7425 752 | LSTOPSUB startanonsub block /* sub f(&@); f { foo } ... */
a8ff2fa6 753 { SvREFCNT_inc(PL_compcv);
29522234 754 $<opval>$ = newANONATTRSUB($2, 0, Nullop, $3); }
891be019 755 listexpr %prec LSTOP /* ... @bar */
4633a7c4 756 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
28757baa 757 append_elem(OP_LIST,
29522234 758 prepend_elem(OP_LIST, $<opval>4, $5), $1));
f05e27e5 759 }
a687059c 760 ;
761
891be019 762/* Names of methods. May use $object->$methodname */
a0d0e21e 763method : METHOD
764 | scalar
765 ;
766
891be019 767/* Some kind of subscripted expression */
768subscripted: star '{' expr ';' '}' /* *main::{something} */
769 /* In this and all the hash accessors, ';' is
770 * provided by the tokeniser */
264e1af3 771 { $$ = newBINOP(OP_GELEM, 0, $1, scalar($3));
f05e27e5 772 PL_expect = XOPERATOR;
773 TOKEN_GETMAD($2,$$,'{');
774 TOKEN_GETMAD($4,$$,';');
775 TOKEN_GETMAD($5,$$,'}');
776 }
891be019 777 | scalar '[' expr ']' /* $array[$element] */
f05e27e5 778 { $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3));
779 TOKEN_GETMAD($2,$$,'[');
780 TOKEN_GETMAD($4,$$,']');
781 }
891be019 782 | term ARROW '[' expr ']' /* somearef->[$element] */
fad39ff1 783 { $$ = newBINOP(OP_AELEM, 0,
784 ref(newAVREF($1),OP_RV2AV),
f05e27e5 785 scalar($4));
786 TOKEN_GETMAD($2,$$,'a');
787 TOKEN_GETMAD($3,$$,'[');
788 TOKEN_GETMAD($5,$$,']');
789 }
891be019 790 | subscripted '[' expr ']' /* $foo->[$bar]->[$baz] */
fad39ff1 791 { $$ = newBINOP(OP_AELEM, 0,
792 ref(newAVREF($1),OP_RV2AV),
f05e27e5 793 scalar($3));
794 TOKEN_GETMAD($2,$$,'[');
795 TOKEN_GETMAD($4,$$,']');
796 }
891be019 797 | scalar '{' expr ';' '}' /* $foo->{bar();} */
fad39ff1 798 { $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3));
f05e27e5 799 PL_expect = XOPERATOR;
800 TOKEN_GETMAD($2,$$,'{');
801 TOKEN_GETMAD($4,$$,';');
802 TOKEN_GETMAD($5,$$,'}');
803 }
891be019 804 | term ARROW '{' expr ';' '}' /* somehref->{bar();} */
fad39ff1 805 { $$ = newBINOP(OP_HELEM, 0,
806 ref(newHVREF($1),OP_RV2HV),
807 jmaybe($4));
f05e27e5 808 PL_expect = XOPERATOR;
809 TOKEN_GETMAD($2,$$,'a');
810 TOKEN_GETMAD($3,$$,'{');
811 TOKEN_GETMAD($5,$$,';');
812 TOKEN_GETMAD($6,$$,'}');
813 }
891be019 814 | subscripted '{' expr ';' '}' /* $foo->[bar]->{baz;} */
fad39ff1 815 { $$ = newBINOP(OP_HELEM, 0,
816 ref(newHVREF($1),OP_RV2HV),
817 jmaybe($3));
f05e27e5 818 PL_expect = XOPERATOR;
819 TOKEN_GETMAD($2,$$,'{');
820 TOKEN_GETMAD($4,$$,';');
821 TOKEN_GETMAD($5,$$,'}');
822 }
891be019 823 | term ARROW '(' ')' /* $subref->() */
fad39ff1 824 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
f05e27e5 825 newCVREF(0, scalar($1)));
826 TOKEN_GETMAD($2,$$,'a');
827 TOKEN_GETMAD($3,$$,'(');
828 TOKEN_GETMAD($4,$$,')');
829 }
891be019 830 | term ARROW '(' expr ')' /* $subref->(@args) */
fad39ff1 831 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
832 append_elem(OP_LIST, $4,
f05e27e5 833 newCVREF(0, scalar($1))));
834 TOKEN_GETMAD($2,$$,'a');
835 TOKEN_GETMAD($3,$$,'(');
836 TOKEN_GETMAD($5,$$,')');
837 }
fad39ff1 838
891be019 839 | subscripted '(' expr ')' /* $foo->{bar}->(@args) */
fad39ff1 840 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
841 append_elem(OP_LIST, $3,
f05e27e5 842 newCVREF(0, scalar($1))));
843 TOKEN_GETMAD($2,$$,'(');
844 TOKEN_GETMAD($4,$$,')');
845 }
891be019 846 | subscripted '(' ')' /* $foo->{bar}->() */
fad39ff1 847 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
f05e27e5 848 newCVREF(0, scalar($1)));
849 TOKEN_GETMAD($2,$$,'(');
850 TOKEN_GETMAD($3,$$,')');
851 }
9a9798c2 852 | '(' expr ')' '[' expr ']' /* list slice */
f05e27e5 853 { $$ = newSLICEOP(0, $5, $2);
854 TOKEN_GETMAD($1,$$,'(');
855 TOKEN_GETMAD($3,$$,')');
856 TOKEN_GETMAD($4,$$,'[');
857 TOKEN_GETMAD($6,$$,']');
858 }
9a9798c2 859 | '(' ')' '[' expr ']' /* empty list slice! */
f05e27e5 860 { $$ = newSLICEOP(0, $4, Nullop);
861 TOKEN_GETMAD($1,$$,'(');
862 TOKEN_GETMAD($2,$$,')');
863 TOKEN_GETMAD($3,$$,'[');
864 TOKEN_GETMAD($5,$$,']');
865 }
891be019 866 ;
fad39ff1 867
891be019 868/* Binary operators between terms */
f05e27e5 869termbinop: term ASSIGNOP term /* $x = $y */
870 { $$ = newASSIGNOP(OPf_STACKED, $1, IVAL($2), $3);
871 TOKEN_GETMAD($2,$$,'o');
872 }
891be019 873 | term POWOP term /* $x ** $y */
f05e27e5 874 { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
875 TOKEN_GETMAD($2,$$,'o');
876 }
891be019 877 | term MULOP term /* $x * $y, $x x $y */
f05e27e5 878 { if (IVAL($2) != OP_REPEAT)
79072805 879 scalar($1);
f05e27e5 880 $$ = newBINOP(IVAL($2), 0, $1, scalar($3));
881 TOKEN_GETMAD($2,$$,'o');
882 }
891be019 883 | term ADDOP term /* $x + $y */
f05e27e5 884 { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
885 TOKEN_GETMAD($2,$$,'o');
886 }
891be019 887 | term SHIFTOP term /* $x >> $y, $x << $y */
f05e27e5 888 { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
889 TOKEN_GETMAD($2,$$,'o');
890 }
891be019 891 | term RELOP term /* $x > $y, etc. */
f05e27e5 892 { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
893 TOKEN_GETMAD($2,$$,'o');
894 }
891be019 895 | term EQOP term /* $x == $y, $x eq $y */
f05e27e5 896 { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
897 TOKEN_GETMAD($2,$$,'o');
898 }
891be019 899 | term BITANDOP term /* $x & $y */
f05e27e5 900 { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
901 TOKEN_GETMAD($2,$$,'o');
902 }
891be019 903 | term BITOROP term /* $x | $y */
f05e27e5 904 { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
905 TOKEN_GETMAD($2,$$,'o');
906 }
891be019 907 | term DOTDOT term /* $x..$y, $x...$y */
f05e27e5 908 {
909 $$ = newRANGE(IVAL($2), scalar($1), scalar($3));
910 DO_MAD(
911 UNOP *op;
912 op = (UNOP*)$$;
913 op = (UNOP*)op->op_first; /* get to flop */
914 op = (UNOP*)op->op_first; /* get to flip */
915 op = (UNOP*)op->op_first; /* get to range */
916 token_getmad($2,(OP*)op,'o');
917 )
918 }
891be019 919 | term ANDAND term /* $x && $y */
f05e27e5 920 { $$ = newLOGOP(OP_AND, 0, $1, $3);
921 TOKEN_GETMAD($2,$$,'o');
922 }
891be019 923 | term OROR term /* $x || $y */
f05e27e5 924 { $$ = newLOGOP(OP_OR, 0, $1, $3);
925 TOKEN_GETMAD($2,$$,'o');
926 }
c963b151 927 | term DORDOR term /* $x // $y */
f05e27e5 928 { $$ = newLOGOP(OP_DOR, 0, $1, $3);
929 TOKEN_GETMAD($2,$$,'o');
930 }
891be019 931 | term MATCHOP term /* $x =~ /$y/ */
f05e27e5 932 { $$ = bind_match(IVAL($2), $1, $3);
933 TOKEN_GETMAD($2,
934 ($$->op_type == OP_NOT
935 ? ((UNOP*)$$)->op_first : $$),
936 '~');
937 }
891be019 938 ;
8d063cd8 939
891be019 940/* Unary operators and terms */
941termunop : '-' term %prec UMINUS /* -$x */
f05e27e5 942 { $$ = newUNOP(OP_NEGATE, 0, scalar($2));
943 TOKEN_GETMAD($1,$$,'o');
944 }
891be019 945 | '+' term %prec UMINUS /* +$x */
f05e27e5 946 { $$ = IF_MAD(
947 newUNOP(OP_NULL, 0, $2),
948 $2
949 );
950 TOKEN_GETMAD($1,$$,'+');
951 }
891be019 952 | '!' term /* !$x */
f05e27e5 953 { $$ = newUNOP(OP_NOT, 0, scalar($2));
954 TOKEN_GETMAD($1,$$,'o');
955 }
891be019 956 | '~' term /* ~$x */
f05e27e5 957 { $$ = newUNOP(OP_COMPLEMENT, 0, scalar($2));
958 TOKEN_GETMAD($1,$$,'o');
959 }
891be019 960 | term POSTINC /* $x++ */
79072805 961 { $$ = newUNOP(OP_POSTINC, 0,
f05e27e5 962 mod(scalar($1), OP_POSTINC));
963 TOKEN_GETMAD($2,$$,'o');
964 }
891be019 965 | term POSTDEC /* $x-- */
79072805 966 { $$ = newUNOP(OP_POSTDEC, 0,
f05e27e5 967 mod(scalar($1), OP_POSTDEC));
968 TOKEN_GETMAD($2,$$,'o');
969 }
891be019 970 | PREINC term /* ++$x */
79072805 971 { $$ = newUNOP(OP_PREINC, 0,
f05e27e5 972 mod(scalar($2), OP_PREINC));
973 TOKEN_GETMAD($1,$$,'o');
974 }
891be019 975 | PREDEC term /* --$x */
79072805 976 { $$ = newUNOP(OP_PREDEC, 0,
f05e27e5 977 mod(scalar($2), OP_PREDEC));
978 TOKEN_GETMAD($1,$$,'o');
979 }
891be019 980
981 ;
982
983/* Constructors for anonymous data */
984anonymous: '[' expr ']'
f05e27e5 985 { $$ = newANONLIST($2);
986 TOKEN_GETMAD($1,$$,'[');
987 TOKEN_GETMAD($3,$$,']');
988 }
891be019 989 | '[' ']'
f05e27e5 990 { $$ = newANONLIST(Nullop);
991 TOKEN_GETMAD($1,$$,'[');
992 TOKEN_GETMAD($2,$$,']');
993 }
891be019 994 | HASHBRACK expr ';' '}' %prec '(' /* { foo => "Bar" } */
f05e27e5 995 { $$ = newANONHASH($2);
996 TOKEN_GETMAD($1,$$,'{');
997 TOKEN_GETMAD($3,$$,';');
998 TOKEN_GETMAD($4,$$,'}');
999 }
891be019 1000 | HASHBRACK ';' '}' %prec '(' /* { } (';' by tokener) */
f05e27e5 1001 { $$ = newANONHASH(Nullop);
1002 TOKEN_GETMAD($1,$$,'{');
1003 TOKEN_GETMAD($2,$$,';');
1004 TOKEN_GETMAD($3,$$,'}');
1005 }
718a7425 1006 | ANONSUB startanonsub proto subattrlist block %prec '('
a8ff2fa6 1007 { SvREFCNT_inc(PL_compcv);
718a7425 1008 $$ = newANONATTRSUB($2, $3, $4, $5);
f05e27e5 1009 TOKEN_GETMAD($1,$$,'o');
718a7425 1010 OP_GETMAD($3,$$,'s');
1011 OP_GETMAD($4,$$,'a');
f05e27e5 1012 }
891be019 1013
1014 ;
1015
1016/* Things called with "do" */
1017termdo : DO term %prec UNIOP /* do $filename */
123d08c9 1018 { $$ = dofile($2, IVAL($1));
f05e27e5 1019 TOKEN_GETMAD($1,$$,'o');
1020 }
891be019 1021 | DO block %prec '(' /* do { code */
f05e27e5 1022 { $$ = newUNOP(OP_NULL, OPf_SPECIAL, scope($2));
1023 TOKEN_GETMAD($1,$$,'D');
1024 }
891be019 1025 | DO WORD '(' ')' /* do somesub() */
1026 { $$ = newUNOP(OP_ENTERSUB,
1027 OPf_SPECIAL|OPf_STACKED,
1028 prepend_elem(OP_LIST,
1029 scalar(newCVREF(
1030 (OPpENTERSUB_AMPER<<8),
1031 scalar($2)
f05e27e5 1032 )),Nullop)); dep();
1033 TOKEN_GETMAD($1,$$,'o');
1034 TOKEN_GETMAD($3,$$,'(');
1035 TOKEN_GETMAD($4,$$,')');
1036 }
891be019 1037 | DO WORD '(' expr ')' /* do somesub(@args) */
1038 { $$ = newUNOP(OP_ENTERSUB,
1039 OPf_SPECIAL|OPf_STACKED,
1040 append_elem(OP_LIST,
1041 $4,
1042 scalar(newCVREF(
1043 (OPpENTERSUB_AMPER<<8),
1044 scalar($2)
f05e27e5 1045 )))); dep();
1046 TOKEN_GETMAD($1,$$,'o');
1047 TOKEN_GETMAD($3,$$,'(');
1048 TOKEN_GETMAD($5,$$,')');
1049 }
891be019 1050 | DO scalar '(' ')' /* do $subref () */
1051 { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
1052 prepend_elem(OP_LIST,
f05e27e5 1053 scalar(newCVREF(0,scalar($2))), Nullop)); dep();
1054 TOKEN_GETMAD($1,$$,'o');
1055 TOKEN_GETMAD($3,$$,'(');
1056 TOKEN_GETMAD($4,$$,')');
1057 }
891be019 1058 | DO scalar '(' expr ')' /* do $subref (@args) */
1059 { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
1060 prepend_elem(OP_LIST,
1061 $4,
f05e27e5 1062 scalar(newCVREF(0,scalar($2))))); dep();
1063 TOKEN_GETMAD($1,$$,'o');
1064 TOKEN_GETMAD($3,$$,'(');
1065 TOKEN_GETMAD($5,$$,')');
1066 }
891be019 1067
1068 ;
1069
1070term : termbinop
1071 | termunop
1072 | anonymous
1073 | termdo
e9bdcc27 1074 | term '?' term ':' term
f05e27e5 1075 { $$ = newCONDOP(0, $1, $3, $5);
1076 TOKEN_GETMAD($2,$$,'?');
1077 TOKEN_GETMAD($4,$$,':');
1078 }
891be019 1079 | REFGEN term /* \$x, \@y, \%z */
f05e27e5 1080 { $$ = newUNOP(OP_REFGEN, 0, mod($2,OP_REFGEN));
1081 TOKEN_GETMAD($1,$$,'o');
1082 }
09bef843 1083 | myattrterm %prec UNIOP
1084 { $$ = $1; }
1085 | LOCAL term %prec UNIOP
f05e27e5 1086 { $$ = localize($2,IVAL($1));
1087 TOKEN_GETMAD($1,$$,'d');
1088 }
a0d0e21e 1089 | '(' expr ')'
f05e27e5 1090 { $$ = sawparens(IF_MAD(newUNOP(OP_NULL,0,$2), $2));
1091 TOKEN_GETMAD($1,$$,'(');
1092 TOKEN_GETMAD($3,$$,')');
1093 }
8d063cd8 1094 | '(' ')'
f05e27e5 1095 { $$ = sawparens(newNULLLIST());
1096 TOKEN_GETMAD($1,$$,'(');
1097 TOKEN_GETMAD($2,$$,')');
1098 }
79072805 1099 | scalar %prec '('
8d063cd8 1100 { $$ = $1; }
79072805 1101 | star %prec '('
8d063cd8 1102 { $$ = $1; }
79072805 1103 | hsh %prec '('
8d063cd8 1104 { $$ = $1; }
79072805 1105 | ary %prec '('
8d063cd8 1106 { $$ = $1; }
891be019 1107 | arylen %prec '(' /* $#x, $#{ something } */
79072805 1108 { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));}
fad39ff1 1109 | subscripted
1110 { $$ = $1; }
891be019 1111 | ary '[' expr ']' /* array slice */
79072805 1112 { $$ = prepend_elem(OP_ASLICE,
1113 newOP(OP_PUSHMARK, 0),
79072805 1114 newLISTOP(OP_ASLICE, 0,
1115 list($3),
f05e27e5 1116 ref($1, OP_ASLICE)));
1117 TOKEN_GETMAD($2,$$,'[');
1118 TOKEN_GETMAD($4,$$,']');
1119 }
891be019 1120 | ary '{' expr ';' '}' /* @hash{@keys} */
79072805 1121 { $$ = prepend_elem(OP_HSLICE,
1122 newOP(OP_PUSHMARK, 0),
79072805 1123 newLISTOP(OP_HSLICE, 0,
1124 list($3),
a0d0e21e 1125 ref(oopsHV($1), OP_HSLICE)));
f05e27e5 1126 PL_expect = XOPERATOR;
1127 TOKEN_GETMAD($2,$$,'{');
1128 TOKEN_GETMAD($4,$$,';');
1129 TOKEN_GETMAD($5,$$,'}');
1130 }
79072805 1131 | THING %prec '('
1132 { $$ = $1; }
891be019 1133 | amper /* &foo; */
c07a80fd 1134 { $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); }
ecb2f335 1135 | amper '(' ')' /* &foo() */
f05e27e5 1136 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1));
1137 TOKEN_GETMAD($2,$$,'(');
1138 TOKEN_GETMAD($3,$$,')');
1139 }
891be019 1140 | amper '(' expr ')' /* &foo(@args) */
f05e27e5 1141 {
1142 $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1143 append_elem(OP_LIST, $3, scalar($1)));
1144 DO_MAD(
1145 OP* op = $$;
1146 if (op->op_type == OP_CONST) { /* defeat const fold */
1147 op = (OP*)op->op_madprop->mad_val;
1148 }
1149 token_getmad($2,op,'(');
1150 token_getmad($4,op,')');
1151 )
1152 }
891be019 1153 | NOAMP WORD listexpr /* foo(@args) */
a0d0e21e 1154 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
f05e27e5 1155 append_elem(OP_LIST, $3, scalar($2)));
1156 TOKEN_GETMAD($1,$$,'o');
1157 }
891be019 1158 | LOOPEX /* loop exiting command (goto, last, dump, etc) */
f05e27e5 1159 { $$ = newOP(IVAL($1), OPf_SPECIAL);
1160 PL_hints |= HINT_BLOCK_SCOPE;
1161 TOKEN_GETMAD($1,$$,'o');
1162 }
a0d0e21e 1163 | LOOPEX term
f05e27e5 1164 { $$ = newLOOPEX(IVAL($1),$2);
1165 TOKEN_GETMAD($1,$$,'o');
1166 }
891be019 1167 | NOTOP argexpr /* not $foo */
f05e27e5 1168 { $$ = newUNOP(OP_NOT, 0, scalar($2));
1169 TOKEN_GETMAD($1,$$,'o');
1170 }
891be019 1171 | UNIOP /* Unary op, $_ implied */
f05e27e5 1172 { $$ = newOP(IVAL($1), 0);
1173 TOKEN_GETMAD($1,$$,'o');
1174 }
1175 | UNIOP block /* eval { foo }* */
1176 { $$ = newUNOP(IVAL($1), 0, $2);
1177 TOKEN_GETMAD($1,$$,'o');
1178 }
891be019 1179 | UNIOP term /* Unary op */
f05e27e5 1180 { $$ = newUNOP(IVAL($1), 0, $2);
1181 TOKEN_GETMAD($1,$$,'o');
1182 }
1183 | REQUIRE /* require, $_ implied *//* FIMXE for MAD needed? */
a72a1c8b 1184 { $$ = newOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0); }
f05e27e5 1185 | REQUIRE term /* require Foo *//* FIMXE for MAD needed? */
a72a1c8b 1186 { $$ = newUNOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0, $2); }
3cd0a11a 1187 | UNIOPSUB
1188 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); }
891be019 1189 | UNIOPSUB term /* Sub treated as unop */
4633a7c4 1190 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1191 append_elem(OP_LIST, $2, scalar($1))); }
891be019 1192 | FUNC0 /* Nullary operator */
f05e27e5 1193 { $$ = newOP(IVAL($1), 0);
1194 TOKEN_GETMAD($1,$$,'o');
1195 }
ae986130 1196 | FUNC0 '(' ')'
f05e27e5 1197 { $$ = newOP(IVAL($1), 0);
1198 TOKEN_GETMAD($1,$$,'o');
1199 TOKEN_GETMAD($2,$$,'(');
1200 TOKEN_GETMAD($3,$$,')');
1201 }
891be019 1202 | FUNC0SUB /* Sub treated as nullop */
28757baa 1203 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
4633a7c4 1204 scalar($1)); }
891be019 1205 | FUNC1 '(' ')' /* not () */
f05e27e5 1206 { $$ = (IVAL($1) == OP_NOT)
1207 ? newUNOP(IVAL($1), 0, newSVOP(OP_CONST, 0, newSViv(0)))
1208 : newOP(IVAL($1), OPf_SPECIAL);
1209
1210 TOKEN_GETMAD($1,$$,'o');
1211 TOKEN_GETMAD($2,$$,'(');
1212 TOKEN_GETMAD($3,$$,')');
1213 }
891be019 1214 | FUNC1 '(' expr ')' /* not($foo) */
f05e27e5 1215 { $$ = newUNOP(IVAL($1), 0, $3);
1216 TOKEN_GETMAD($1,$$,'o');
1217 TOKEN_GETMAD($2,$$,'(');
1218 TOKEN_GETMAD($4,$$,')');
1219 }
1220 | PMFUNC '(' argexpr ')' /* m//, s///, tr/// */
1221 { $$ = pmruntime($1, $3, 1);
1222 TOKEN_GETMAD($2,$$,'(');
1223 TOKEN_GETMAD($4,$$,')');
1224 }
79072805 1225 | WORD
378cc40b 1226 | listop
8d063cd8 1227 ;
1228
891be019 1229/* "my" declarations, with optional attributes */
09bef843 1230myattrterm: MY myterm myattrlist
f05e27e5 1231 { $$ = my_attrs($2,$3);
1232 DO_MAD(
1233 token_getmad($1,$$,'d');
1234 append_madprops($3->op_madprop, $$, 'a');
1235 $3->op_madprop = 0;
1236 )
1237 }
09bef843 1238 | MY myterm
f05e27e5 1239 { $$ = localize($2,IVAL($1));
1240 TOKEN_GETMAD($1,$$,'d');
1241 }
09bef843 1242 ;
1243
891be019 1244/* Things that can be "my"'d */
09bef843 1245myterm : '(' expr ')'
f05e27e5 1246 { $$ = sawparens($2);
1247 TOKEN_GETMAD($1,$$,'(');
1248 TOKEN_GETMAD($3,$$,')');
1249 }
09bef843 1250 | '(' ')'
f05e27e5 1251 { $$ = sawparens(newNULLLIST());
1252 TOKEN_GETMAD($1,$$,'(');
1253 TOKEN_GETMAD($2,$$,')');
1254 }
09bef843 1255 | scalar %prec '('
1256 { $$ = $1; }
1257 | hsh %prec '('
1258 { $$ = $1; }
1259 | ary %prec '('
1260 { $$ = $1; }
1261 ;
1262
891be019 1263/* Basic list expressions */
fad39ff1 1264listexpr: /* NULL */ %prec PREC_LOW
8990e307 1265 { $$ = Nullop; }
fad39ff1 1266 | argexpr %prec PREC_LOW
a0d0e21e 1267 { $$ = $1; }
1268 ;
1269
1270listexprcom: /* NULL */
1271 { $$ = Nullop; }
79072805 1272 | expr
1273 { $$ = $1; }
a0d0e21e 1274 | expr ','
f05e27e5 1275 {
1276#ifdef MAD
1277 OP* op = newNULLLIST();
1278 token_getmad($2,op,',');
1279 $$ = append_elem(OP_LIST, $1, op);
1280#else
1281 $$ = $1;
1282#endif
1283
1284 }
79072805 1285 ;
1286
891be019 1287/* A little bit of trickery to make "for my $foo (@bar)" actually be
1288 lexical */
55497cff 1289my_scalar: scalar
3280af22 1290 { PL_in_my = 0; $$ = my($1); }
55497cff 1291 ;
1292
79072805 1293amper : '&' indirob
f05e27e5 1294 { $$ = newCVREF(IVAL($1),$2);
1295 TOKEN_GETMAD($1,$$,'&');
1296 }
a687059c 1297 ;
1298
79072805 1299scalar : '$' indirob
f05e27e5 1300 { $$ = newSVREF($2);
1301 TOKEN_GETMAD($1,$$,'$');
1302 }
a687059c 1303 ;
1304
79072805 1305ary : '@' indirob
f05e27e5 1306 { $$ = newAVREF($2);
1307 TOKEN_GETMAD($1,$$,'@');
1308 }
79072805 1309 ;
1310
1311hsh : '%' indirob
f05e27e5 1312 { $$ = newHVREF($2);
1313 TOKEN_GETMAD($1,$$,'%');
1314 }
79072805 1315 ;
1316
1317arylen : DOLSHARP indirob
f05e27e5 1318 { $$ = newAVREF($2);
1319 TOKEN_GETMAD($1,$$,'l');
1320 }
79072805 1321 ;
1322
1323star : '*' indirob
f05e27e5 1324 { $$ = newGVREF(0,$2);
1325 TOKEN_GETMAD($1,$$,'*');
1326 }
79072805 1327 ;
1328
891be019 1329/* Indirect objects */
79072805 1330indirob : WORD
1331 { $$ = scalar($1); }
fad39ff1 1332 | scalar %prec PREC_LOW
f05e27e5 1333 { $$ = scalar($1); }
79072805 1334 | block
a0d0e21e 1335 { $$ = scope($1); }
79072805 1336
93a17b20 1337 | PRIVATEREF
1338 { $$ = $1; }
8d063cd8 1339 ;