Commit | Line | Data |
---|---|---|
a0d0e21e | 1 | /* perly.y |
a687059c | 2 | * |
f05e27e5 | 3 | * Copyright (c) 1991-2002, 2003, 2004, 2005, 2006 Larry Wall |
2eee27d7 | 4 | * Copyright (c) 2007, 2008, 2009, 2010, 2011 by Larry Wall and others |
a687059c | 5 | * |
9ef589d8 LW |
6 | * You may distribute under the terms of either the GNU General Public |
7 | * License or the Artistic License, as specified in the README file. | |
8d063cd8 | 8 | * |
a0d0e21e LW |
9 | */ |
10 | ||
11 | /* | |
12 | * 'I see,' laughed Strider. 'I look foul and feel fair. Is that it? | |
4ac71550 | 13 | * All that is gold does not glitter, not all those who wander are lost.' |
f05e27e5 | 14 | * |
4ac71550 TC |
15 | * [p.171 of _The Lord of the Rings_, I/x: "Strider"] |
16 | */ | |
17 | ||
18 | /* | |
f05e27e5 | 19 | * This file holds the grammar for the Perl language. If edited, you need |
166f8a29 DM |
20 | * to run regen_perly.pl, which re-creates the files perly.h, perly.tab |
21 | * and perly.act which are derived from this. | |
22 | * | |
a3815e44 | 23 | * The main job of this grammar is to call the various newFOO() |
166f8a29 | 24 | * functions in op.c to build a syntax tree of OP structs. |
61296642 | 25 | * It relies on the lexer in toke.c to do the tokenizing. |
29522234 DM |
26 | * |
27 | * Note: due to the way that the cleanup code works WRT to freeing ops on | |
28 | * the parse stack, it is dangerous to assign to the $n variables within | |
29 | * an action. | |
166f8a29 DM |
30 | */ |
31 | ||
0de566d7 | 32 | /* Make the parser re-entrant. */ |
8d063cd8 | 33 | |
0a2b3d88 | 34 | %define api.pure |
8d063cd8 | 35 | |
28ac2b49 | 36 | %start grammar |
9d116dd7 | 37 | |
8d063cd8 | 38 | %union { |
d5c6462e DM |
39 | I32 ival; /* __DEFAULT__ (marker for regen_perly.pl; |
40 | must always be 1st union member) */ | |
79072805 LW |
41 | char *pval; |
42 | OP *opval; | |
43 | GV *gvval; | |
8d063cd8 LW |
44 | } |
45 | ||
996b0cb8 | 46 | %token <ival> GRAMPROG GRAMEXPR GRAMBLOCK GRAMBARESTMT GRAMFULLSTMT GRAMSTMTSEQ GRAMSUBSIGNATURE |
28ac2b49 | 47 | |
68670bd9 | 48 | /* Tokens emitted by toke.c for simple punctiation characters - &, {, }, etc... */ |
25a50500 | 49 | %token <ival> PERLY_AMPERSAND |
c588171e | 50 | %token <ival> PERLY_BRACE_OPEN |
d0a6a9c7 | 51 | %token <ival> PERLY_BRACE_CLOSE |
669dd22c | 52 | %token <ival> PERLY_BRACKET_OPEN |
fceeeb77 | 53 | %token <ival> PERLY_BRACKET_CLOSE |
581f9a7a | 54 | %token <ival> PERLY_COMMA |
bfa838cc | 55 | %token <ival> PERLY_DOLLAR |
da4bce7d | 56 | %token <ival> PERLY_DOT |
db83e45c | 57 | %token <ival> PERLY_EQUAL_SIGN |
68a66a8b | 58 | %token <ival> PERLY_MINUS |
0ba95c59 | 59 | %token <ival> PERLY_PERCENT_SIGN |
5776f3e5 | 60 | %token <ival> PERLY_PLUS |
5adeeefb | 61 | %token <ival> PERLY_SEMICOLON |
77b0379f | 62 | %token <ival> PERLY_SLASH |
9086c946 | 63 | %token <ival> PERLY_SNAIL |
d02b2fbf | 64 | %token <ival> PERLY_STAR |
f0fcb552 | 65 | |
68670bd9 PE |
66 | /* Tokens emitted by toke.c on simple keywords */ |
67 | %token <ival> KW_FORMAT KW_PACKAGE | |
68 | %token <ival> KW_LOCAL KW_MY | |
69 | %token <ival> KW_IF KW_ELSE KW_ELSIF KW_UNLESS | |
70 | %token <ival> KW_FOR KW_UNTIL KW_WHILE KW_CONTINUE | |
71 | %token <ival> KW_GIVEN KW_WHEN KW_DEFAULT | |
72 | %token <ival> KW_TRY KW_CATCH KW_FINALLY KW_DEFER | |
73 | %token <ival> KW_REQUIRE KW_DO | |
74 | ||
75 | /* The 'use' and 'no' keywords both emit this */ | |
76 | %token <ival> KW_USE_or_NO | |
77 | ||
78 | /* The 'sub' keyword is a bit special; four different tokens depending on | |
79 | * named-vs-anon, and whether signatures are in effect */ | |
80 | %token <ival> KW_SUB_named KW_SUB_named_sig KW_SUB_anon KW_SUB_anon_sig | |
81 | ||
82 | /* Tokens emitted in other situations */ | |
b179236d | 83 | %token <opval> BAREWORD METHCALL0 METHCALL THING PMFUNC PRIVATEREF QWLIST |
7eb971ee | 84 | %token <opval> FUNC0OP FUNC0SUB UNIOPSUB LSTOPSUB |
88e1f1a2 | 85 | %token <opval> PLUGEXPR PLUGSTMT |
01719201 | 86 | %token <opval> LABEL |
b5bbe64a JH |
87 | %token <ival> LOOPEX DOTDOT YADAYADA |
88 | %token <ival> FUNC0 FUNC1 FUNC UNIOP LSTOP | |
02b85d3d | 89 | %token <ival> MULOP ADDOP |
68670bd9 | 90 | %token <ival> DOLSHARP HASHBRACK NOAMP |
b5bbe64a | 91 | %token <ival> COLONATTR FORMLBRACK FORMRBRACK |
69afcc21 | 92 | %token <ival> SUBLEXSTART SUBLEXEND |
f05e27e5 | 93 | |
727a8fe5 | 94 | %type <ival> grammar remember mremember |
f05e27e5 | 95 | %type <ival> startsub startanonsub startformsub |
b5bbe64a | 96 | |
b5a64814 | 97 | %type <ival> mintro |
f05e27e5 | 98 | |
01f2495a | 99 | %type <opval> stmtseq fullstmt labfullstmt barestmt block mblock else finally |
fad39ff1 | 100 | %type <opval> expr term subscripted scalar ary hsh arylen star amper sideff |
53443c95 | 101 | %type <opval> condition |
0065df43 | 102 | %type <opval> catch_paren |
148f5aaf | 103 | %type <opval> empty |
76eba8ab | 104 | %type <opval> sliceme kvslice gelem |
08b3e84f | 105 | %type <opval> listexpr nexpr texpr iexpr mexpr mnexpr |
b179236d | 106 | %type <opval> optlistexpr optexpr optrepl indirob listop methodname |
75230cc1 | 107 | %type <opval> formname subname proto cont my_scalar my_var |
e92ce056 | 108 | %type <opval> list_of_scalars my_list_of_scalars refgen_topic formblock |
f05e27e5 | 109 | %type <opval> subattrlist myattrlist myattrterm myterm |
75230cc1 | 110 | %type <opval> termbinop termunop anonymous termdo |
02b85d3d | 111 | %type <opval> termrelop relopchain termeqop eqopchain |
d3d9da4a DM |
112 | %type <ival> sigslurpsigil |
113 | %type <opval> sigvarname sigdefault sigscalarelem sigslurpelem | |
6e9eef66 | 114 | %type <opval> sigelem siglist optsiglist subsigguts subsignature optsubsignature |
75230cc1 | 115 | %type <opval> subbody optsubbody sigsubbody optsigsubbody |
705fe0e5 | 116 | %type <opval> formstmtseq formline formarg |
79072805 | 117 | |
b5bbe64a | 118 | %nonassoc <ival> PREC_LOW |
fad39ff1 SM |
119 | %nonassoc LOOPEX |
120 | ||
6e9e8105 | 121 | %left <ival> OROP |
b5bbe64a JH |
122 | %left <ival> ANDOP |
123 | %right <ival> NOTOP | |
36477c24 | 124 | %nonassoc LSTOP LSTOPSUB |
581f9a7a | 125 | %left PERLY_COMMA |
b5bbe64a | 126 | %right <ival> ASSIGNOP |
a1ad62bf | 127 | %right <ival> PERLY_QUESTION_MARK PERLY_COLON |
29d69c3c | 128 | %nonassoc DOTDOT |
b5bbe64a JH |
129 | %left <ival> OROR DORDOR |
130 | %left <ival> ANDAND | |
131 | %left <ival> BITOROP | |
132 | %left <ival> BITANDOP | |
02b85d3d Z |
133 | %left <ival> CHEQOP NCEQOP |
134 | %left <ival> CHRELOP NCRELOP | |
36477c24 | 135 | %nonassoc UNIOP UNIOPSUB |
68670bd9 | 136 | %nonassoc KW_REQUIRE |
b5bbe64a | 137 | %left <ival> SHIFTOP |
a687059c LW |
138 | %left ADDOP |
139 | %left MULOP | |
b5bbe64a | 140 | %left <ival> MATCHOP |
3d92c6b8 | 141 | %right <ival> PERLY_EXCLAMATION_MARK PERLY_TILDE UMINUS REFGEN |
b5bbe64a JH |
142 | %right <ival> POWOP |
143 | %nonassoc <ival> PREINC PREDEC POSTINC POSTDEC POSTJOIN | |
144 | %left <ival> ARROW | |
04884b68 | 145 | %nonassoc <ival> PERLY_PAREN_CLOSE |
ee67f254 | 146 | %left <ival> PERLY_PAREN_OPEN |
669dd22c | 147 | %left PERLY_BRACKET_OPEN PERLY_BRACE_OPEN |
8d063cd8 LW |
148 | |
149 | %% /* RULES */ | |
150 | ||
28ac2b49 | 151 | /* Top-level choice of what kind of thing yyparse was called to parse */ |
727a8fe5 Z |
152 | grammar : GRAMPROG |
153 | { | |
624fa8bd | 154 | parser->expect = XSTATE; |
5a2060e2 | 155 | $<ival>$ = 0; |
727a8fe5 Z |
156 | } |
157 | remember stmtseq | |
158 | { | |
53443c95 | 159 | newPROG(block_end($remember,$stmtseq)); |
8635e3c2 | 160 | PL_compiling.cop_seq = 0; |
727a8fe5 Z |
161 | $$ = 0; |
162 | } | |
78cdf107 Z |
163 | | GRAMEXPR |
164 | { | |
165 | parser->expect = XTERM; | |
5a2060e2 | 166 | $<ival>$ = 0; |
78cdf107 | 167 | } |
09b1cffe | 168 | optexpr |
78cdf107 | 169 | { |
53443c95 | 170 | PL_eval_root = $optexpr; |
78cdf107 Z |
171 | $$ = 0; |
172 | } | |
e53d8f76 Z |
173 | | GRAMBLOCK |
174 | { | |
175 | parser->expect = XBLOCK; | |
5a2060e2 | 176 | $<ival>$ = 0; |
e53d8f76 Z |
177 | } |
178 | block | |
179 | { | |
5f211341 | 180 | PL_pad_reset_pending = TRUE; |
53443c95 | 181 | PL_eval_root = $block; |
8359b381 Z |
182 | $$ = 0; |
183 | yyunlex(); | |
0f8490d1 | 184 | parser->yychar = yytoken = YYEOF; |
8359b381 Z |
185 | } |
186 | | GRAMBARESTMT | |
187 | { | |
188 | parser->expect = XSTATE; | |
5a2060e2 | 189 | $<ival>$ = 0; |
8359b381 Z |
190 | } |
191 | barestmt | |
192 | { | |
193 | PL_pad_reset_pending = TRUE; | |
53443c95 | 194 | PL_eval_root = $barestmt; |
e53d8f76 Z |
195 | $$ = 0; |
196 | yyunlex(); | |
0f8490d1 | 197 | parser->yychar = yytoken = YYEOF; |
e53d8f76 | 198 | } |
9eb5c532 | 199 | | GRAMFULLSTMT |
28ac2b49 | 200 | { |
9eb5c532 | 201 | parser->expect = XSTATE; |
5a2060e2 | 202 | $<ival>$ = 0; |
9eb5c532 Z |
203 | } |
204 | fullstmt | |
205 | { | |
5f211341 | 206 | PL_pad_reset_pending = TRUE; |
53443c95 | 207 | PL_eval_root = $fullstmt; |
28ac2b49 Z |
208 | $$ = 0; |
209 | yyunlex(); | |
0f8490d1 | 210 | parser->yychar = yytoken = YYEOF; |
28ac2b49 | 211 | } |
07ffcb73 Z |
212 | | GRAMSTMTSEQ |
213 | { | |
214 | parser->expect = XSTATE; | |
5a2060e2 | 215 | $<ival>$ = 0; |
07ffcb73 | 216 | } |
5f211341 | 217 | stmtseq |
07ffcb73 | 218 | { |
53443c95 | 219 | PL_eval_root = $stmtseq; |
07ffcb73 Z |
220 | $$ = 0; |
221 | } | |
996b0cb8 PE |
222 | | GRAMSUBSIGNATURE |
223 | { | |
224 | parser->expect = XSTATE; | |
225 | $<ival>$ = 0; | |
226 | } | |
227 | subsigguts | |
228 | { | |
53443c95 | 229 | PL_eval_root = $subsigguts; |
996b0cb8 PE |
230 | $$ = 0; |
231 | } | |
07ffcb73 Z |
232 | ; |
233 | ||
891be019 | 234 | /* An ordinary block */ |
d0a6a9c7 | 235 | block : PERLY_BRACE_OPEN remember stmtseq PERLY_BRACE_CLOSE |
c588171e BZ |
236 | { if (parser->copline > (line_t)$PERLY_BRACE_OPEN) |
237 | parser->copline = (line_t)$PERLY_BRACE_OPEN; | |
53443c95 | 238 | $$ = block_end($remember, $stmtseq); |
f05e27e5 | 239 | } |
a0d0e21e LW |
240 | ; |
241 | ||
148f5aaf BZ |
242 | empty |
243 | : %empty { $$ = NULL; } | |
244 | ; | |
245 | ||
7c70caa5 | 246 | /* format body */ |
db83e45c BZ |
247 | formblock: PERLY_EQUAL_SIGN remember PERLY_SEMICOLON FORMRBRACK formstmtseq PERLY_SEMICOLON PERLY_DOT |
248 | { if (parser->copline > (line_t)$PERLY_EQUAL_SIGN) | |
249 | parser->copline = (line_t)$PERLY_EQUAL_SIGN; | |
53443c95 | 250 | $$ = block_end($remember, $formstmtseq); |
7c70caa5 FC |
251 | } |
252 | ; | |
253 | ||
a410a50e | 254 | remember: %empty /* start a full lexical scope */ |
34b54951 FC |
255 | { $$ = block_start(TRUE); |
256 | parser->parsed_sub = 0; } | |
55497cff | 257 | ; |
258 | ||
d0a6a9c7 | 259 | mblock : PERLY_BRACE_OPEN mremember stmtseq PERLY_BRACE_CLOSE |
c588171e BZ |
260 | { if (parser->copline > (line_t)$PERLY_BRACE_OPEN) |
261 | parser->copline = (line_t)$PERLY_BRACE_OPEN; | |
53443c95 | 262 | $$ = block_end($mremember, $stmtseq); |
f05e27e5 | 263 | } |
55497cff | 264 | ; |
265 | ||
a410a50e | 266 | mremember: %empty /* start a partial lexical scope */ |
34b54951 FC |
267 | { $$ = block_start(FALSE); |
268 | parser->parsed_sub = 0; } | |
8d063cd8 LW |
269 | ; |
270 | ||
0065df43 PE |
271 | /* The parenthesized variable of a catch block */ |
272 | catch_paren: empty | |
273 | /* not really valid grammar but we detect it in the | |
274 | * action block to throw a nicer error message */ | |
275 | | PERLY_PAREN_OPEN | |
276 | { parser->in_my = 1; } | |
277 | scalar | |
278 | { parser->in_my = 0; intro_my(); } | |
279 | PERLY_PAREN_CLOSE | |
280 | { $$ = $scalar; } | |
281 | ; | |
282 | ||
eae48c89 | 283 | /* A sequence of statements in the program */ |
148f5aaf BZ |
284 | stmtseq |
285 | : empty | |
53443c95 BZ |
286 | | stmtseq[list] fullstmt |
287 | { $$ = op_append_list(OP_LINESEQ, $list, $fullstmt); | |
3280af22 | 288 | PL_pad_reset_pending = TRUE; |
53443c95 | 289 | if ($list && $fullstmt) |
503de470 DM |
290 | PL_hints |= HINT_BLOCK_SCOPE; |
291 | } | |
8d063cd8 LW |
292 | ; |
293 | ||
705fe0e5 | 294 | /* A sequence of format lines */ |
148f5aaf BZ |
295 | formstmtseq |
296 | : empty | |
53443c95 BZ |
297 | | formstmtseq[list] formline |
298 | { $$ = op_append_list(OP_LINESEQ, $list, $formline); | |
705fe0e5 | 299 | PL_pad_reset_pending = TRUE; |
53443c95 | 300 | if ($list && $formline) |
705fe0e5 FC |
301 | PL_hints |= HINT_BLOCK_SCOPE; |
302 | } | |
303 | ; | |
304 | ||
8e720305 Z |
305 | /* A statement in the program, including optional labels */ |
306 | fullstmt: barestmt | |
eae48c89 | 307 | { |
53443c95 | 308 | $$ = $barestmt ? newSTATEOP(0, NULL, $barestmt) : NULL; |
eae48c89 | 309 | } |
8e720305 | 310 | | labfullstmt |
53443c95 | 311 | { $$ = $labfullstmt; } |
8e720305 Z |
312 | ; |
313 | ||
314 | labfullstmt: LABEL barestmt | |
315 | { | |
53443c95 | 316 | SV *label = cSVOPx_sv($LABEL); |
01719201 | 317 | $$ = newSTATEOP(SvFLAGS(label) & SVf_UTF8, |
53443c95 BZ |
318 | savepv(SvPVX_const(label)), $barestmt); |
319 | op_free($LABEL); | |
8e720305 | 320 | } |
53443c95 | 321 | | LABEL labfullstmt[list] |
8e720305 | 322 | { |
53443c95 | 323 | SV *label = cSVOPx_sv($LABEL); |
01719201 | 324 | $$ = newSTATEOP(SvFLAGS(label) & SVf_UTF8, |
53443c95 BZ |
325 | savepv(SvPVX_const(label)), $list); |
326 | op_free($LABEL); | |
8e720305 | 327 | } |
eae48c89 Z |
328 | ; |
329 | ||
330 | /* A bare statement, lacking label and other aspects of state op */ | |
331 | barestmt: PLUGSTMT | |
53443c95 | 332 | { $$ = $PLUGSTMT; } |
68670bd9 | 333 | | KW_FORMAT startformsub formname formblock |
f05e27e5 | 334 | { |
eae48c89 | 335 | CV *fmtcv = PL_compcv; |
53443c95 | 336 | newFORM($startformsub, $formname, $formblock); |
a9f5ab8d | 337 | $$ = NULL; |
4a273b91 | 338 | if (CvOUTSIDE(fmtcv) && !CvEVAL(CvOUTSIDE(fmtcv))) { |
74a9453a | 339 | pad_add_weakref(fmtcv); |
f05e27e5 | 340 | } |
8b9fb2f9 | 341 | parser->parsed_sub = 1; |
eae48c89 | 342 | } |
68670bd9 | 343 | | KW_SUB_named subname startsub |
75230cc1 DM |
344 | /* sub declaration or definition not within scope |
345 | of 'use feature "signatures"'*/ | |
50278755 | 346 | { |
53443c95 | 347 | init_named_cv(PL_compcv, $subname); |
624fa8bd FC |
348 | parser->in_my = 0; |
349 | parser->in_my_stash = NULL; | |
764212cf | 350 | } |
75230cc1 | 351 | proto subattrlist optsubbody |
eae48c89 Z |
352 | { |
353 | SvREFCNT_inc_simple_void(PL_compcv); | |
53443c95 BZ |
354 | $subname->op_type == OP_CONST |
355 | ? newATTRSUB($startsub, $subname, $proto, $subattrlist, $optsubbody) | |
356 | : newMYSUB($startsub, $subname, $proto, $subattrlist, $optsubbody) | |
50278755 | 357 | ; |
a9f5ab8d | 358 | $$ = NULL; |
764212cf | 359 | intro_my(); |
34b54951 | 360 | parser->parsed_sub = 1; |
f05e27e5 | 361 | } |
68670bd9 | 362 | | KW_SUB_named_sig subname startsub |
75230cc1 DM |
363 | /* sub declaration or definition under 'use feature |
364 | * "signatures"'. (Note that a signature isn't | |
365 | * allowed in a declaration) | |
366 | */ | |
436ddf68 | 367 | { |
53443c95 | 368 | init_named_cv(PL_compcv, $subname); |
436ddf68 DM |
369 | parser->in_my = 0; |
370 | parser->in_my_stash = NULL; | |
371 | } | |
75230cc1 | 372 | subattrlist optsigsubbody |
436ddf68 DM |
373 | { |
374 | SvREFCNT_inc_simple_void(PL_compcv); | |
53443c95 BZ |
375 | $subname->op_type == OP_CONST |
376 | ? newATTRSUB($startsub, $subname, NULL, $subattrlist, $optsigsubbody) | |
377 | : newMYSUB( $startsub, $subname, NULL, $subattrlist, $optsigsubbody) | |
436ddf68 DM |
378 | ; |
379 | $$ = NULL; | |
380 | intro_my(); | |
381 | parser->parsed_sub = 1; | |
382 | } | |
68670bd9 | 383 | | KW_PACKAGE BAREWORD[version] BAREWORD[package] PERLY_SEMICOLON |
5f211341 | 384 | { |
53443c95 BZ |
385 | package($package); |
386 | if ($version) | |
387 | package_version($version); | |
a9f5ab8d | 388 | $$ = NULL; |
eae48c89 | 389 | } |
68670bd9 | 390 | | KW_USE_or_NO startsub |
eae48c89 | 391 | { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ } |
5adeeefb | 392 | BAREWORD[version] BAREWORD[module] optlistexpr PERLY_SEMICOLON |
eae48c89 Z |
393 | { |
394 | SvREFCNT_inc_simple_void(PL_compcv); | |
68670bd9 | 395 | utilize($KW_USE_or_NO, $startsub, $version, $module, $optlistexpr); |
34b54951 | 396 | parser->parsed_sub = 1; |
a9f5ab8d | 397 | $$ = NULL; |
eae48c89 | 398 | } |
68670bd9 | 399 | | KW_IF PERLY_PAREN_OPEN remember mexpr PERLY_PAREN_CLOSE mblock else |
eae48c89 | 400 | { |
53443c95 BZ |
401 | $$ = block_end($remember, |
402 | newCONDOP(0, $mexpr, op_scope($mblock), $else)); | |
68670bd9 | 403 | parser->copline = (line_t)$KW_IF; |
eae48c89 | 404 | } |
68670bd9 | 405 | | KW_UNLESS PERLY_PAREN_OPEN remember mexpr PERLY_PAREN_CLOSE mblock else |
eae48c89 | 406 | { |
53443c95 BZ |
407 | $$ = block_end($remember, |
408 | newCONDOP(0, $mexpr, $else, op_scope($mblock))); | |
68670bd9 | 409 | parser->copline = (line_t)$KW_UNLESS; |
eae48c89 | 410 | } |
68670bd9 | 411 | | KW_GIVEN PERLY_PAREN_OPEN remember mexpr PERLY_PAREN_CLOSE mblock |
eae48c89 | 412 | { |
53443c95 | 413 | $$ = block_end($remember, newGIVENOP($mexpr, op_scope($mblock), 0)); |
68670bd9 | 414 | parser->copline = (line_t)$KW_GIVEN; |
eae48c89 | 415 | } |
68670bd9 | 416 | | KW_WHEN PERLY_PAREN_OPEN remember mexpr PERLY_PAREN_CLOSE mblock |
53443c95 | 417 | { $$ = block_end($remember, newWHENOP($mexpr, op_scope($mblock))); } |
68670bd9 | 418 | | KW_DEFAULT block |
53443c95 | 419 | { $$ = newWHENOP(0, op_scope($block)); } |
68670bd9 | 420 | | KW_WHILE PERLY_PAREN_OPEN remember texpr PERLY_PAREN_CLOSE mintro mblock cont |
eae48c89 | 421 | { |
53443c95 | 422 | $$ = block_end($remember, |
a9f5ab8d | 423 | newWHILEOP(0, 1, NULL, |
53443c95 | 424 | $texpr, $mblock, $cont, $mintro)); |
68670bd9 | 425 | parser->copline = (line_t)$KW_WHILE; |
eae48c89 | 426 | } |
68670bd9 | 427 | | KW_UNTIL PERLY_PAREN_OPEN remember iexpr PERLY_PAREN_CLOSE mintro mblock cont |
eae48c89 | 428 | { |
53443c95 | 429 | $$ = block_end($remember, |
a9f5ab8d | 430 | newWHILEOP(0, 1, NULL, |
53443c95 | 431 | $iexpr, $mblock, $cont, $mintro)); |
68670bd9 | 432 | parser->copline = (line_t)$KW_UNTIL; |
eae48c89 | 433 | } |
68670bd9 | 434 | | KW_FOR PERLY_PAREN_OPEN remember mnexpr[init_mnexpr] PERLY_SEMICOLON |
2d0e3c96 | 435 | { parser->expect = XTERM; } |
5adeeefb | 436 | texpr PERLY_SEMICOLON |
2d0e3c96 | 437 | { parser->expect = XTERM; } |
04884b68 | 438 | mintro mnexpr[iterate_mnexpr] PERLY_PAREN_CLOSE |
eae48c89 Z |
439 | mblock |
440 | { | |
53443c95 | 441 | OP *initop = $init_mnexpr; |
a9f5ab8d | 442 | OP *forop = newWHILEOP(0, 1, NULL, |
53443c95 | 443 | scalar($texpr), $mblock, $iterate_mnexpr, $mintro); |
eae48c89 Z |
444 | if (initop) { |
445 | forop = op_prepend_elem(OP_LINESEQ, initop, | |
446 | op_append_elem(OP_LINESEQ, | |
447 | newOP(OP_UNSTACK, OPf_SPECIAL), | |
448 | forop)); | |
5f211341 | 449 | } |
0f602692 | 450 | PL_hints |= HINT_BLOCK_SCOPE; |
53443c95 | 451 | $$ = block_end($remember, forop); |
68670bd9 | 452 | parser->copline = (line_t)$KW_FOR; |
eae48c89 | 453 | } |
68670bd9 | 454 | | KW_FOR KW_MY remember my_scalar PERLY_PAREN_OPEN mexpr PERLY_PAREN_CLOSE mblock cont |
eae48c89 | 455 | { |
53443c95 | 456 | $$ = block_end($remember, newFOROP(0, $my_scalar, $mexpr, $mblock, $cont)); |
68670bd9 | 457 | parser->copline = (line_t)$KW_FOR; |
eae48c89 | 458 | } |
68670bd9 | 459 | | KW_FOR KW_MY remember PERLY_PAREN_OPEN my_list_of_scalars PERLY_PAREN_CLOSE PERLY_PAREN_OPEN mexpr PERLY_PAREN_CLOSE mblock cont |
e92ce056 | 460 | { |
f8245cd9 DM |
461 | if ($my_list_of_scalars->op_type == OP_PADSV) |
462 | /* degenerate case of 1 var: for my ($x) .... | |
463 | Flag it so it can be special-cased in newFOROP */ | |
464 | $my_list_of_scalars->op_flags |= OPf_PARENS; | |
e92ce056 | 465 | $$ = block_end($remember, newFOROP(0, $my_list_of_scalars, $mexpr, $mblock, $cont)); |
68670bd9 | 466 | parser->copline = (line_t)$KW_FOR; |
e92ce056 | 467 | } |
68670bd9 | 468 | | KW_FOR scalar PERLY_PAREN_OPEN remember mexpr PERLY_PAREN_CLOSE mblock cont |
eae48c89 | 469 | { |
53443c95 BZ |
470 | $$ = block_end($remember, newFOROP(0, |
471 | op_lvalue($scalar, OP_ENTERLOOP), $mexpr, $mblock, $cont)); | |
68670bd9 | 472 | parser->copline = (line_t)$KW_FOR; |
eae48c89 | 473 | } |
68670bd9 | 474 | | KW_FOR my_refgen remember my_var |
53443c95 | 475 | { parser->in_my = 0; $<opval>$ = my($my_var); }[variable] |
04884b68 | 476 | PERLY_PAREN_OPEN mexpr PERLY_PAREN_CLOSE mblock cont |
d39c26a6 FC |
477 | { |
478 | $$ = block_end( | |
53443c95 | 479 | $remember, |
d39c26a6 FC |
480 | newFOROP(0, |
481 | op_lvalue( | |
482 | newUNOP(OP_REFGEN, 0, | |
53443c95 | 483 | $<opval>variable), |
d39c26a6 | 484 | OP_ENTERLOOP), |
53443c95 | 485 | $mexpr, $mblock, $cont) |
d39c26a6 | 486 | ); |
68670bd9 | 487 | parser->copline = (line_t)$KW_FOR; |
d39c26a6 | 488 | } |
68670bd9 | 489 | | KW_FOR REFGEN refgen_topic PERLY_PAREN_OPEN remember mexpr PERLY_PAREN_CLOSE mblock cont |
d39c26a6 | 490 | { |
53443c95 | 491 | $$ = block_end($remember, newFOROP( |
d39c26a6 | 492 | 0, op_lvalue(newUNOP(OP_REFGEN, 0, |
53443c95 BZ |
493 | $refgen_topic), |
494 | OP_ENTERLOOP), $mexpr, $mblock, $cont)); | |
68670bd9 | 495 | parser->copline = (line_t)$KW_FOR; |
d39c26a6 | 496 | } |
68670bd9 | 497 | | KW_FOR PERLY_PAREN_OPEN remember mexpr PERLY_PAREN_CLOSE mblock cont |
eae48c89 | 498 | { |
53443c95 BZ |
499 | $$ = block_end($remember, |
500 | newFOROP(0, NULL, $mexpr, $mblock, $cont)); | |
68670bd9 | 501 | parser->copline = (line_t)$KW_FOR; |
eae48c89 | 502 | } |
68670bd9 | 503 | | KW_TRY mblock[try] KW_CATCH remember catch_paren[scalar] |
0065df43 PE |
504 | { |
505 | if(!$scalar) { | |
506 | yyerror("catch block requires a (VAR)"); | |
507 | YYERROR; | |
508 | } | |
509 | } | |
510 | mblock[catch] finally | |
a1325b90 | 511 | { |
65648910 PE |
512 | $$ = newTRYCATCHOP(0, |
513 | $try, $scalar, block_end($remember, op_scope($catch))); | |
01f2495a PE |
514 | if($finally) |
515 | $$ = op_wrap_finally($$, $finally); | |
68670bd9 | 516 | parser->copline = (line_t)$KW_TRY; |
a1325b90 | 517 | } |
eae48c89 Z |
518 | | block cont |
519 | { | |
520 | /* a block is a loop that happens once */ | |
a9f5ab8d | 521 | $$ = newWHILEOP(0, 1, NULL, |
53443c95 | 522 | NULL, $block, $cont, 0); |
eae48c89 | 523 | } |
68670bd9 | 524 | | KW_PACKAGE BAREWORD[version] BAREWORD[package] PERLY_BRACE_OPEN remember |
eae48c89 | 525 | { |
53443c95 BZ |
526 | package($package); |
527 | if ($version) { | |
528 | package_version($version); | |
eae48c89 Z |
529 | } |
530 | } | |
d0a6a9c7 | 531 | stmtseq PERLY_BRACE_CLOSE |
eae48c89 Z |
532 | { |
533 | /* a block is a loop that happens once */ | |
a9f5ab8d | 534 | $$ = newWHILEOP(0, 1, NULL, |
53443c95 | 535 | NULL, block_end($remember, $stmtseq), NULL, 0); |
c588171e BZ |
536 | if (parser->copline > (line_t)$PERLY_BRACE_OPEN) |
537 | parser->copline = (line_t)$PERLY_BRACE_OPEN; | |
eae48c89 | 538 | } |
5adeeefb | 539 | | sideff PERLY_SEMICOLON |
eae48c89 | 540 | { |
53443c95 | 541 | $$ = $sideff; |
eae48c89 | 542 | } |
68670bd9 | 543 | | KW_DEFER mblock |
f79e2ff9 PE |
544 | { |
545 | $$ = newDEFEROP(0, op_scope($2)); | |
546 | } | |
5adeeefb | 547 | | YADAYADA PERLY_SEMICOLON |
29d69c3c Z |
548 | { |
549 | $$ = newLISTOP(OP_DIE, 0, newOP(OP_PUSHMARK, 0), | |
550 | newSVOP(OP_CONST, 0, newSVpvs("Unimplemented"))); | |
551 | } | |
5adeeefb | 552 | | PERLY_SEMICOLON |
eae48c89 | 553 | { |
a9f5ab8d | 554 | $$ = NULL; |
624fa8bd | 555 | parser->copline = NOLINE; |
5f211341 | 556 | } |
8d063cd8 LW |
557 | ; |
558 | ||
705fe0e5 FC |
559 | /* Format line */ |
560 | formline: THING formarg | |
561 | { OP *list; | |
53443c95 BZ |
562 | if ($formarg) { |
563 | OP *term = $formarg; | |
564 | list = op_append_elem(OP_LIST, $THING, term); | |
705fe0e5 FC |
565 | } |
566 | else { | |
53443c95 | 567 | list = $THING; |
705fe0e5 | 568 | } |
624fa8bd FC |
569 | if (parser->copline == NOLINE) |
570 | parser->copline = CopLINE(PL_curcop)-1; | |
571 | else parser->copline--; | |
705fe0e5 | 572 | $$ = newSTATEOP(0, NULL, |
03d05f6e | 573 | op_convert_list(OP_FORMLINE, 0, list)); |
705fe0e5 FC |
574 | } |
575 | ; | |
576 | ||
148f5aaf BZ |
577 | formarg |
578 | : empty | |
705fe0e5 | 579 | | FORMLBRACK stmtseq FORMRBRACK |
53443c95 | 580 | { $$ = op_unscope($stmtseq); } |
705fe0e5 FC |
581 | ; |
582 | ||
53443c95 BZ |
583 | condition: expr |
584 | ; | |
585 | ||
891be019 | 586 | /* An expression which may have a side-effect */ |
a687059c | 587 | sideff : error |
a9f5ab8d | 588 | { $$ = NULL; } |
53443c95 BZ |
589 | | expr[body] |
590 | { $$ = $body; } | |
68670bd9 | 591 | | expr[body] KW_IF condition |
53443c95 | 592 | { $$ = newLOGOP(OP_AND, 0, $condition, $body); } |
68670bd9 | 593 | | expr[body] KW_UNLESS condition |
53443c95 | 594 | { $$ = newLOGOP(OP_OR, 0, $condition, $body); } |
68670bd9 | 595 | | expr[body] KW_WHILE condition |
53443c95 | 596 | { $$ = newLOOPOP(OPf_PARENS, 1, scalar($condition), $body); } |
68670bd9 | 597 | | expr[body] KW_UNTIL iexpr |
53443c95 | 598 | { $$ = newLOOPOP(OPf_PARENS, 1, $iexpr, $body); } |
68670bd9 | 599 | | expr[body] KW_FOR condition |
53443c95 | 600 | { $$ = newFOROP(0, NULL, $condition, $body, NULL); |
68670bd9 PE |
601 | parser->copline = (line_t)$KW_FOR; } |
602 | | expr[body] KW_WHEN condition | |
53443c95 | 603 | { $$ = newWHENOP($condition, op_scope($body)); } |
79072805 LW |
604 | ; |
605 | ||
891be019 | 606 | /* else and elsif blocks */ |
148f5aaf BZ |
607 | else |
608 | : empty | |
68670bd9 | 609 | | KW_ELSE mblock |
3ad73efd | 610 | { |
53443c95 BZ |
611 | ($mblock)->op_flags |= OPf_PARENS; |
612 | $$ = op_scope($mblock); | |
f05e27e5 | 613 | } |
68670bd9 PE |
614 | | KW_ELSIF PERLY_PAREN_OPEN mexpr PERLY_PAREN_CLOSE mblock else[else.recurse] |
615 | { parser->copline = (line_t)$KW_ELSIF; | |
3ad73efd | 616 | $$ = newCONDOP(0, |
53443c95 BZ |
617 | newSTATEOP(OPf_SPECIAL,NULL,$mexpr), |
618 | op_scope($mblock), $[else.recurse]); | |
3ad73efd | 619 | PL_hints |= HINT_BLOCK_SCOPE; |
f05e27e5 | 620 | } |
79072805 LW |
621 | ; |
622 | ||
891be019 | 623 | /* Continue blocks */ |
148f5aaf BZ |
624 | cont |
625 | : empty | |
68670bd9 | 626 | | KW_CONTINUE block |
53443c95 | 627 | { $$ = op_scope($block); } |
79072805 LW |
628 | ; |
629 | ||
01f2495a PE |
630 | /* Finally blocks */ |
631 | finally : %empty | |
632 | { $$ = NULL; } | |
68670bd9 | 633 | | KW_FINALLY block |
01f2495a PE |
634 | { $$ = op_scope($block); } |
635 | ; | |
636 | ||
a034e688 | 637 | /* determine whether there are any new my declarations */ |
a410a50e | 638 | mintro : %empty |
a034e688 DM |
639 | { $$ = (PL_min_intro_pending && |
640 | PL_max_intro_pending >= PL_min_intro_pending); | |
641 | intro_my(); } | |
642 | ||
891be019 | 643 | /* Normal expression */ |
148f5aaf BZ |
644 | nexpr |
645 | : empty | |
8d063cd8 LW |
646 | | sideff |
647 | ; | |
648 | ||
891be019 | 649 | /* Boolean expression */ |
a410a50e | 650 | texpr : %empty /* NULL means true */ |
f05e27e5 DM |
651 | { YYSTYPE tmplval; |
652 | (void)scan_num("1", &tmplval); | |
653 | $$ = tmplval.opval; } | |
8d063cd8 LW |
654 | | expr |
655 | ; | |
656 | ||
891be019 | 657 | /* Inverted boolean expression */ |
55497cff | 658 | iexpr : expr |
53443c95 | 659 | { $$ = invert(scalar($expr)); } |
55497cff | 660 | ; |
661 | ||
891be019 | 662 | /* Expression with its own lexical scope */ |
55497cff | 663 | mexpr : expr |
53443c95 | 664 | { $$ = $expr; intro_my(); } |
bbce6d69 | 665 | ; |
666 | ||
667 | mnexpr : nexpr | |
53443c95 | 668 | { $$ = $nexpr; intro_my(); } |
55497cff | 669 | ; |
670 | ||
53443c95 | 671 | formname: BAREWORD { $$ = $BAREWORD; } |
148f5aaf | 672 | | empty |
8d063cd8 LW |
673 | ; |
674 | ||
a410a50e | 675 | startsub: %empty /* start a regular subroutine scope */ |
a8ff2fa6 DM |
676 | { $$ = start_subparse(FALSE, 0); |
677 | SAVEFREESV(PL_compcv); } | |
f05e27e5 | 678 | |
28757baa | 679 | ; |
680 | ||
a410a50e | 681 | startanonsub: %empty /* start an anonymous subroutine scope */ |
a8ff2fa6 DM |
682 | { $$ = start_subparse(FALSE, CVf_ANON); |
683 | SAVEFREESV(PL_compcv); } | |
28757baa | 684 | ; |
685 | ||
a410a50e | 686 | startformsub: %empty /* start a format subroutine scope */ |
a8ff2fa6 DM |
687 | { $$ = start_subparse(TRUE, 0); |
688 | SAVEFREESV(PL_compcv); } | |
44a8e56a | 689 | ; |
690 | ||
891be019 | 691 | /* Name of a subroutine - must be a bareword, could be special */ |
185c2e96 | 692 | subname : BAREWORD |
4210d3f1 | 693 | | PRIVATEREF |
a0d0e21e LW |
694 | ; |
695 | ||
891be019 | 696 | /* Subroutine prototype */ |
148f5aaf BZ |
697 | proto |
698 | : empty | |
4633a7c4 LW |
699 | | THING |
700 | ; | |
28757baa | 701 | |
891be019 | 702 | /* Optional list of subroutine attributes */ |
148f5aaf BZ |
703 | subattrlist |
704 | : empty | |
09bef843 | 705 | | COLONATTR THING |
53443c95 | 706 | { $$ = $THING; } |
09bef843 | 707 | | COLONATTR |
a9f5ab8d | 708 | { $$ = NULL; } |
09bef843 SB |
709 | ; |
710 | ||
891be019 | 711 | /* List of attributes for a "my" variable declaration */ |
09bef843 | 712 | myattrlist: COLONATTR THING |
53443c95 | 713 | { $$ = $THING; } |
09bef843 | 714 | | COLONATTR |
a9f5ab8d | 715 | { $$ = NULL; } |
09bef843 SB |
716 | ; |
717 | ||
abcf453d | 718 | |
d3d9da4a DM |
719 | |
720 | /* -------------------------------------- | |
721 | * subroutine signature parsing | |
722 | */ | |
723 | ||
724 | /* the '' or 'foo' part of a '$' or '@foo' etc signature variable */ | |
a410a50e | 725 | sigvarname: %empty |
a9f5ab8d | 726 | { parser->in_my = 0; $$ = NULL; } |
d3d9da4a | 727 | | PRIVATEREF |
53443c95 | 728 | { parser->in_my = 0; $$ = $PRIVATEREF; } |
d3d9da4a DM |
729 | ; |
730 | ||
731 | sigslurpsigil: | |
9086c946 | 732 | PERLY_SNAIL |
d3d9da4a | 733 | { $$ = '@'; } |
0ba95c59 | 734 | | PERLY_PERCENT_SIGN |
d3d9da4a DM |
735 | { $$ = '%'; } |
736 | ||
737 | /* @, %, @foo, %foo */ | |
738 | sigslurpelem: sigslurpsigil sigvarname sigdefault/* def only to catch errors */ | |
739 | { | |
53443c95 BZ |
740 | I32 sigil = $sigslurpsigil; |
741 | OP *var = $sigvarname; | |
742 | OP *defexpr = $sigdefault; | |
d3d9da4a | 743 | |
036bbc13 | 744 | if (parser->sig_slurpy) |
d3d9da4a | 745 | yyerror("Multiple slurpy parameters not allowed"); |
036bbc13 | 746 | parser->sig_slurpy = (char)sigil; |
d3d9da4a DM |
747 | |
748 | if (defexpr) | |
bb6b75cd | 749 | yyerror("A slurpy parameter may not have " |
d3d9da4a DM |
750 | "a default value"); |
751 | ||
a9f5ab8d | 752 | $$ = var ? newSTATEOP(0, NULL, var) : NULL; |
d3d9da4a DM |
753 | } |
754 | ; | |
755 | ||
756 | /* default part of sub signature scalar element: i.e. '= default_expr' */ | |
148f5aaf BZ |
757 | sigdefault |
758 | : empty | |
d3d9da4a DM |
759 | | ASSIGNOP |
760 | { $$ = newOP(OP_NULL, 0); } | |
761 | | ASSIGNOP term | |
53443c95 | 762 | { $$ = $term; } |
d3d9da4a DM |
763 | |
764 | ||
765 | /* subroutine signature scalar element: e.g. '$x', '$=', '$x = $default' */ | |
766 | sigscalarelem: | |
bfa838cc | 767 | PERLY_DOLLAR sigvarname sigdefault |
d3d9da4a | 768 | { |
53443c95 BZ |
769 | OP *var = $sigvarname; |
770 | OP *defexpr = $sigdefault; | |
d3d9da4a | 771 | |
036bbc13 | 772 | if (parser->sig_slurpy) |
d3d9da4a DM |
773 | yyerror("Slurpy parameter not last"); |
774 | ||
036bbc13 | 775 | parser->sig_elems++; |
d3d9da4a | 776 | |
d3d9da4a | 777 | if (defexpr) { |
036bbc13 | 778 | parser->sig_optelems++; |
4fa06845 DM |
779 | |
780 | if ( defexpr->op_type == OP_NULL | |
d3d9da4a DM |
781 | && !(defexpr->op_flags & OPf_KIDS)) |
782 | { | |
4fa06845 DM |
783 | /* handle '$=' special case */ |
784 | if (var) | |
785 | yyerror("Optional parameter " | |
786 | "lacks default expression"); | |
d3d9da4a DM |
787 | op_free(defexpr); |
788 | } | |
4fa06845 DM |
789 | else { |
790 | /* a normal '=default' expression */ | |
791 | OP *defop = (OP*)alloc_LOGOP(OP_ARGDEFELEM, | |
792 | defexpr, | |
793 | LINKLIST(defexpr)); | |
794 | /* re-purpose op_targ to hold @_ index */ | |
6daeaaa3 | 795 | defop->op_targ = |
036bbc13 | 796 | (PADOFFSET)(parser->sig_elems - 1); |
4fa06845 DM |
797 | |
798 | if (var) { | |
799 | var->op_flags |= OPf_STACKED; | |
800 | (void)op_sibling_splice(var, | |
801 | NULL, 0, defop); | |
802 | scalar(defop); | |
803 | } | |
804 | else | |
805 | var = newUNOP(OP_NULL, 0, defop); | |
806 | ||
807 | LINKLIST(var); | |
808 | /* NB: normally the first child of a | |
809 | * logop is executed before the logop, | |
810 | * and it pushes a boolean result | |
811 | * ready for the logop. For ARGDEFELEM, | |
812 | * the op itself does the boolean | |
813 | * calculation, so set the first op to | |
814 | * it instead. | |
815 | */ | |
816 | var->op_next = defop; | |
817 | defexpr->op_next = var; | |
d3d9da4a DM |
818 | } |
819 | } | |
820 | else { | |
036bbc13 | 821 | if (parser->sig_optelems) |
d3d9da4a DM |
822 | yyerror("Mandatory parameter " |
823 | "follows optional parameter"); | |
d3d9da4a DM |
824 | } |
825 | ||
a9f5ab8d | 826 | $$ = var ? newSTATEOP(0, NULL, var) : NULL; |
d3d9da4a DM |
827 | } |
828 | ; | |
829 | ||
830 | ||
831 | /* subroutine signature element: e.g. '$x = $default' or '%h' */ | |
832 | sigelem: sigscalarelem | |
53443c95 | 833 | { parser->in_my = KEY_sigvar; $$ = $sigscalarelem; } |
d3d9da4a | 834 | | sigslurpelem |
53443c95 | 835 | { parser->in_my = KEY_sigvar; $$ = $sigslurpelem; } |
d3d9da4a DM |
836 | ; |
837 | ||
838 | /* list of subroutine signature elements */ | |
839 | siglist: | |
581f9a7a | 840 | siglist[list] PERLY_COMMA |
53443c95 | 841 | { $$ = $list; } |
581f9a7a | 842 | | siglist[list] PERLY_COMMA sigelem[element] |
30d9c59b | 843 | { |
53443c95 | 844 | $$ = op_append_list(OP_LINESEQ, $list, $element); |
30d9c59b | 845 | } |
53443c95 BZ |
846 | | sigelem[element] %prec PREC_LOW |
847 | { $$ = $element; } | |
30d9c59b Z |
848 | ; |
849 | ||
d3d9da4a | 850 | /* () or (....) */ |
6e9eef66 | 851 | optsiglist |
148f5aaf | 852 | : empty |
d3d9da4a | 853 | | siglist |
6e9eef66 | 854 | ; |
d3d9da4a | 855 | |
75230cc1 | 856 | /* optional subroutine signature */ |
148f5aaf BZ |
857 | optsubsignature |
858 | : empty | |
75230cc1 | 859 | | subsignature |
6e9eef66 | 860 | ; |
75230cc1 | 861 | |
d3d9da4a | 862 | /* Subroutine signature */ |
04884b68 | 863 | subsignature: PERLY_PAREN_OPEN subsigguts PERLY_PAREN_CLOSE |
53443c95 | 864 | { $$ = $subsigguts; } |
996b0cb8 PE |
865 | |
866 | subsigguts: | |
d3d9da4a DM |
867 | { |
868 | ENTER; | |
036bbc13 FC |
869 | SAVEIV(parser->sig_elems); |
870 | SAVEIV(parser->sig_optelems); | |
871 | SAVEI8(parser->sig_slurpy); | |
872 | parser->sig_elems = 0; | |
873 | parser->sig_optelems = 0; | |
874 | parser->sig_slurpy = 0; | |
49fb8620 | 875 | parser->in_my = KEY_sigvar; |
d3d9da4a | 876 | } |
6e9eef66 | 877 | optsiglist |
d3d9da4a | 878 | { |
6e9eef66 | 879 | OP *sigops = $optsiglist; |
f417cfa9 | 880 | struct op_argcheck_aux *aux; |
4fa06845 | 881 | OP *check; |
d3d9da4a | 882 | |
894f226e DM |
883 | if (!FEATURE_SIGNATURES_IS_ENABLED) |
884 | Perl_croak(aTHX_ "Experimental " | |
885 | "subroutine signatures not enabled"); | |
d3d9da4a DM |
886 | |
887 | /* We shouldn't get here otherwise */ | |
f417cfa9 DM |
888 | aux = (struct op_argcheck_aux*) |
889 | PerlMemShared_malloc( | |
890 | sizeof(struct op_argcheck_aux)); | |
891 | aux->params = parser->sig_elems; | |
892 | aux->opt_params = parser->sig_optelems; | |
893 | aux->slurpy = parser->sig_slurpy; | |
894 | check = newUNOP_AUX(OP_ARGCHECK, 0, NULL, | |
895 | (UNOP_AUX_item *)aux); | |
4fa06845 DM |
896 | sigops = op_prepend_elem(OP_LINESEQ, check, sigops); |
897 | sigops = op_prepend_elem(OP_LINESEQ, | |
898 | newSTATEOP(0, NULL, NULL), | |
899 | sigops); | |
900 | /* a nextstate at the end handles context | |
901 | * correctly for an empty sub body */ | |
4df85778 | 902 | sigops = op_append_elem(OP_LINESEQ, |
4fa06845 DM |
903 | sigops, |
904 | newSTATEOP(0, NULL, NULL)); | |
4df85778 DM |
905 | /* wrap the list of arg ops in a NULL aux op. |
906 | This serves two purposes. First, it makes | |
907 | the arg list a separate subtree from the | |
908 | body of the sub, and secondly the null op | |
909 | may in future be upgraded to an OP_SIGNATURE | |
910 | when implemented. For now leave it as | |
911 | ex-argcheck */ | |
912 | $$ = newUNOP_AUX(OP_ARGCHECK, 0, sigops, NULL); | |
913 | op_null($$); | |
d3d9da4a | 914 | |
57a97e26 PE |
915 | CvSIGNATURE_on(PL_compcv); |
916 | ||
49fb8620 | 917 | parser->in_my = 0; |
a8c56356 DM |
918 | /* tell the toker that attrributes can follow |
919 | * this sig, but only so that the toker | |
920 | * can skip through any (illegal) trailing | |
921 | * attribute text then give a useful error | |
922 | * message about "attributes before sig", | |
923 | * rather than falling over ina mess at | |
924 | * unrecognised syntax. | |
925 | */ | |
926 | parser->expect = XATTRBLOCK; | |
927 | parser->sig_seen = TRUE; | |
d3d9da4a DM |
928 | LEAVE; |
929 | } | |
930 | ; | |
931 | ||
75230cc1 | 932 | /* Optional subroutine body (for named subroutine declaration) */ |
6e9eef66 BZ |
933 | optsubbody |
934 | : subbody | |
5adeeefb | 935 | | PERLY_SEMICOLON { $$ = NULL; } |
75230cc1 DM |
936 | ; |
937 | ||
938 | ||
939 | /* Subroutine body (without signature) */ | |
d0a6a9c7 | 940 | subbody: remember PERLY_BRACE_OPEN stmtseq PERLY_BRACE_CLOSE |
75230cc1 | 941 | { |
c588171e BZ |
942 | if (parser->copline > (line_t)$PERLY_BRACE_OPEN) |
943 | parser->copline = (line_t)$PERLY_BRACE_OPEN; | |
53443c95 | 944 | $$ = block_end($remember, $stmtseq); |
75230cc1 DM |
945 | } |
946 | ; | |
947 | ||
948 | ||
949 | /* optional [ Subroutine body with optional signature ] (for named | |
950 | * subroutine declaration) */ | |
6e9eef66 BZ |
951 | optsigsubbody |
952 | : sigsubbody | |
5adeeefb | 953 | | PERLY_SEMICOLON { $$ = NULL; } |
6e9eef66 | 954 | ; |
d3d9da4a | 955 | |
75230cc1 | 956 | /* Subroutine body with optional signature */ |
d0a6a9c7 | 957 | sigsubbody: remember optsubsignature PERLY_BRACE_OPEN stmtseq PERLY_BRACE_CLOSE |
894f226e | 958 | { |
c588171e BZ |
959 | if (parser->copline > (line_t)$PERLY_BRACE_OPEN) |
960 | parser->copline = (line_t)$PERLY_BRACE_OPEN; | |
53443c95 BZ |
961 | $$ = block_end($remember, |
962 | op_append_list(OP_LINESEQ, $optsubsignature, $stmtseq)); | |
894f226e DM |
963 | } |
964 | ; | |
965 | ||
d3d9da4a | 966 | |
891be019 | 967 | /* Ordinary expressions; logical combinations */ |
53443c95 BZ |
968 | expr : expr[lhs] ANDOP expr[rhs] |
969 | { $$ = newLOGOP(OP_AND, 0, $lhs, $rhs); } | |
970 | | expr[lhs] OROP[operator] expr[rhs] | |
971 | { $$ = newLOGOP($operator, 0, $lhs, $rhs); } | |
09b1cffe | 972 | | listexpr %prec PREC_LOW |
a0d0e21e LW |
973 | ; |
974 | ||
891be019 | 975 | /* Expressions are a list of terms joined by commas */ |
581f9a7a | 976 | listexpr: listexpr[list] PERLY_COMMA |
53443c95 | 977 | { $$ = $list; } |
581f9a7a | 978 | | listexpr[list] PERLY_COMMA term |
abcf453d | 979 | { |
53443c95 BZ |
980 | OP* term = $term; |
981 | $$ = op_append_elem(OP_LIST, $list, term); | |
f05e27e5 | 982 | } |
fad39ff1 | 983 | | term %prec PREC_LOW |
8d063cd8 LW |
984 | ; |
985 | ||
891be019 | 986 | /* List operators */ |
09b1cffe | 987 | listop : LSTOP indirob listexpr /* map {...} @args or print $fh @args */ |
53443c95 BZ |
988 | { $$ = op_convert_list($LSTOP, OPf_STACKED, |
989 | op_prepend_elem(OP_LIST, newGVREF($LSTOP,$indirob), $listexpr) ); | |
f05e27e5 | 990 | } |
04884b68 | 991 | | FUNC PERLY_PAREN_OPEN indirob expr PERLY_PAREN_CLOSE /* print ($fh @args */ |
53443c95 BZ |
992 | { $$ = op_convert_list($FUNC, OPf_STACKED, |
993 | op_prepend_elem(OP_LIST, newGVREF($FUNC,$indirob), $expr) ); | |
f05e27e5 | 994 | } |
b179236d | 995 | | term ARROW methodname PERLY_PAREN_OPEN optexpr PERLY_PAREN_CLOSE /* $foo->bar(list) */ |
03d05f6e | 996 | { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED, |
2fcb4757 | 997 | op_append_elem(OP_LIST, |
53443c95 | 998 | op_prepend_elem(OP_LIST, scalar($term), $optexpr), |
b179236d | 999 | newMETHOP(OP_METHOD, 0, $methodname))); |
f05e27e5 | 1000 | } |
b179236d | 1001 | | term ARROW methodname /* $foo->bar */ |
03d05f6e | 1002 | { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED, |
53443c95 | 1003 | op_append_elem(OP_LIST, scalar($term), |
b179236d | 1004 | newMETHOP(OP_METHOD, 0, $methodname))); |
f05e27e5 | 1005 | } |
b179236d | 1006 | | METHCALL0 indirob optlistexpr /* new Class @args */ |
03d05f6e | 1007 | { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED, |
2fcb4757 | 1008 | op_append_elem(OP_LIST, |
53443c95 | 1009 | op_prepend_elem(OP_LIST, $indirob, $optlistexpr), |
b179236d | 1010 | newMETHOP(OP_METHOD, 0, $METHCALL0))); |
f05e27e5 | 1011 | } |
b179236d | 1012 | | METHCALL indirob PERLY_PAREN_OPEN optexpr PERLY_PAREN_CLOSE /* method $object (@args) */ |
03d05f6e | 1013 | { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED, |
2fcb4757 | 1014 | op_append_elem(OP_LIST, |
53443c95 | 1015 | op_prepend_elem(OP_LIST, $indirob, $optexpr), |
b179236d | 1016 | newMETHOP(OP_METHOD, 0, $METHCALL))); |
f05e27e5 | 1017 | } |
09b1cffe | 1018 | | LSTOP optlistexpr /* print @args */ |
53443c95 | 1019 | { $$ = op_convert_list($LSTOP, 0, $optlistexpr); } |
04884b68 | 1020 | | FUNC PERLY_PAREN_OPEN optexpr PERLY_PAREN_CLOSE /* print (@args) */ |
53443c95 | 1021 | { $$ = op_convert_list($FUNC, 0, $optexpr); } |
69afcc21 | 1022 | | FUNC SUBLEXSTART optexpr SUBLEXEND /* uc($arg) from "\U..." */ |
53443c95 | 1023 | { $$ = op_convert_list($FUNC, 0, $optexpr); } |
718a7425 | 1024 | | LSTOPSUB startanonsub block /* sub f(&@); f { foo } ... */ |
5a5094bd | 1025 | { SvREFCNT_inc_simple_void(PL_compcv); |
53443c95 | 1026 | $<opval>$ = newANONATTRSUB($startanonsub, 0, NULL, $block); }[anonattrsub] |
09b1cffe | 1027 | optlistexpr %prec LSTOP /* ... @bar */ |
4633a7c4 | 1028 | { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, |
2fcb4757 | 1029 | op_append_elem(OP_LIST, |
53443c95 | 1030 | op_prepend_elem(OP_LIST, $<opval>anonattrsub, $optlistexpr), $LSTOPSUB)); |
f05e27e5 | 1031 | } |
a687059c LW |
1032 | ; |
1033 | ||
891be019 | 1034 | /* Names of methods. May use $object->$methodname */ |
b179236d | 1035 | methodname: METHCALL0 |
a0d0e21e LW |
1036 | | scalar |
1037 | ; | |
1038 | ||
891be019 | 1039 | /* Some kind of subscripted expression */ |
5adeeefb BZ |
1040 | subscripted: gelem PERLY_BRACE_OPEN expr PERLY_SEMICOLON PERLY_BRACE_CLOSE /* *main::{something} */ |
1041 | /* In this and all the hash accessors, PERLY_SEMICOLON is | |
891be019 | 1042 | * provided by the tokeniser */ |
53443c95 | 1043 | { $$ = newBINOP(OP_GELEM, 0, $gelem, scalar($expr)); } |
fceeeb77 | 1044 | | scalar[array] PERLY_BRACKET_OPEN expr PERLY_BRACKET_CLOSE /* $array[$element] */ |
53443c95 | 1045 | { $$ = newBINOP(OP_AELEM, 0, oopsAV($array), scalar($expr)); |
f05e27e5 | 1046 | } |
fceeeb77 | 1047 | | term[array_reference] ARROW PERLY_BRACKET_OPEN expr PERLY_BRACKET_CLOSE /* somearef->[$element] */ |
fad39ff1 | 1048 | { $$ = newBINOP(OP_AELEM, 0, |
53443c95 BZ |
1049 | ref(newAVREF($array_reference),OP_RV2AV), |
1050 | scalar($expr)); | |
f05e27e5 | 1051 | } |
fceeeb77 | 1052 | | subscripted[array_reference] PERLY_BRACKET_OPEN expr PERLY_BRACKET_CLOSE /* $foo->[$bar]->[$baz] */ |
fad39ff1 | 1053 | { $$ = newBINOP(OP_AELEM, 0, |
53443c95 BZ |
1054 | ref(newAVREF($array_reference),OP_RV2AV), |
1055 | scalar($expr)); | |
f05e27e5 | 1056 | } |
5adeeefb | 1057 | | scalar[hash] PERLY_BRACE_OPEN expr PERLY_SEMICOLON PERLY_BRACE_CLOSE /* $foo{bar();} */ |
53443c95 | 1058 | { $$ = newBINOP(OP_HELEM, 0, oopsHV($hash), jmaybe($expr)); |
f05e27e5 | 1059 | } |
5adeeefb | 1060 | | term[hash_reference] ARROW PERLY_BRACE_OPEN expr PERLY_SEMICOLON PERLY_BRACE_CLOSE /* somehref->{bar();} */ |
fad39ff1 | 1061 | { $$ = newBINOP(OP_HELEM, 0, |
53443c95 BZ |
1062 | ref(newHVREF($hash_reference),OP_RV2HV), |
1063 | jmaybe($expr)); } | |
5adeeefb | 1064 | | subscripted[hash_reference] PERLY_BRACE_OPEN expr PERLY_SEMICOLON PERLY_BRACE_CLOSE /* $foo->[bar]->{baz;} */ |
fad39ff1 | 1065 | { $$ = newBINOP(OP_HELEM, 0, |
53443c95 BZ |
1066 | ref(newHVREF($hash_reference),OP_RV2HV), |
1067 | jmaybe($expr)); } | |
04884b68 | 1068 | | term[code_reference] ARROW PERLY_PAREN_OPEN PERLY_PAREN_CLOSE /* $subref->() */ |
fad39ff1 | 1069 | { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, |
53443c95 | 1070 | newCVREF(0, scalar($code_reference))); |
097ff42c Z |
1071 | if (parser->expect == XBLOCK) |
1072 | parser->expect = XOPERATOR; | |
1073 | } | |
04884b68 | 1074 | | term[code_reference] ARROW PERLY_PAREN_OPEN expr PERLY_PAREN_CLOSE /* $subref->(@args) */ |
fad39ff1 | 1075 | { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, |
53443c95 BZ |
1076 | op_append_elem(OP_LIST, $expr, |
1077 | newCVREF(0, scalar($code_reference)))); | |
097ff42c Z |
1078 | if (parser->expect == XBLOCK) |
1079 | parser->expect = XOPERATOR; | |
1080 | } | |
fad39ff1 | 1081 | |
04884b68 | 1082 | | subscripted[code_reference] PERLY_PAREN_OPEN expr PERLY_PAREN_CLOSE /* $foo->{bar}->(@args) */ |
fad39ff1 | 1083 | { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, |
53443c95 BZ |
1084 | op_append_elem(OP_LIST, $expr, |
1085 | newCVREF(0, scalar($code_reference)))); | |
097ff42c Z |
1086 | if (parser->expect == XBLOCK) |
1087 | parser->expect = XOPERATOR; | |
1088 | } | |
04884b68 | 1089 | | subscripted[code_reference] PERLY_PAREN_OPEN PERLY_PAREN_CLOSE /* $foo->{bar}->() */ |
fad39ff1 | 1090 | { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, |
53443c95 | 1091 | newCVREF(0, scalar($code_reference))); |
097ff42c Z |
1092 | if (parser->expect == XBLOCK) |
1093 | parser->expect = XOPERATOR; | |
1094 | } | |
04884b68 | 1095 | | PERLY_PAREN_OPEN expr[list] PERLY_PAREN_CLOSE PERLY_BRACKET_OPEN expr[slice] PERLY_BRACKET_CLOSE /* list slice */ |
53443c95 | 1096 | { $$ = newSLICEOP(0, $slice, $list); } |
fceeeb77 | 1097 | | QWLIST PERLY_BRACKET_OPEN expr PERLY_BRACKET_CLOSE /* list literal slice */ |
53443c95 | 1098 | { $$ = newSLICEOP(0, $expr, $QWLIST); } |
04884b68 | 1099 | | PERLY_PAREN_OPEN PERLY_PAREN_CLOSE PERLY_BRACKET_OPEN expr PERLY_BRACKET_CLOSE /* empty list slice! */ |
53443c95 | 1100 | { $$ = newSLICEOP(0, $expr, NULL); } |
891be019 | 1101 | ; |
fad39ff1 | 1102 | |
891be019 | 1103 | /* Binary operators between terms */ |
53443c95 BZ |
1104 | termbinop: term[lhs] ASSIGNOP term[rhs] /* $x = $y, $x += $y */ |
1105 | { $$ = newASSIGNOP(OPf_STACKED, $lhs, $ASSIGNOP, $rhs); } | |
1106 | | term[lhs] POWOP term[rhs] /* $x ** $y */ | |
1107 | { $$ = newBINOP($POWOP, 0, scalar($lhs), scalar($rhs)); } | |
1108 | | term[lhs] MULOP term[rhs] /* $x * $y, $x x $y */ | |
1109 | { if ($MULOP != OP_REPEAT) | |
1110 | scalar($lhs); | |
1111 | $$ = newBINOP($MULOP, 0, $lhs, scalar($rhs)); | |
1112 | } | |
1113 | | term[lhs] ADDOP term[rhs] /* $x + $y */ | |
1114 | { $$ = newBINOP($ADDOP, 0, scalar($lhs), scalar($rhs)); } | |
1115 | | term[lhs] SHIFTOP term[rhs] /* $x >> $y, $x << $y */ | |
1116 | { $$ = newBINOP($SHIFTOP, 0, scalar($lhs), scalar($rhs)); } | |
02b85d3d | 1117 | | termrelop %prec PREC_LOW /* $x > $y, etc. */ |
53443c95 | 1118 | { $$ = $termrelop; } |
02b85d3d | 1119 | | termeqop %prec PREC_LOW /* $x == $y, $x cmp $y */ |
53443c95 BZ |
1120 | { $$ = $termeqop; } |
1121 | | term[lhs] BITANDOP term[rhs] /* $x & $y */ | |
1122 | { $$ = newBINOP($BITANDOP, 0, scalar($lhs), scalar($rhs)); } | |
1123 | | term[lhs] BITOROP term[rhs] /* $x | $y */ | |
1124 | { $$ = newBINOP($BITOROP, 0, scalar($lhs), scalar($rhs)); } | |
1125 | | term[lhs] DOTDOT term[rhs] /* $x..$y, $x...$y */ | |
1126 | { $$ = newRANGE($DOTDOT, scalar($lhs), scalar($rhs)); } | |
1127 | | term[lhs] ANDAND term[rhs] /* $x && $y */ | |
1128 | { $$ = newLOGOP(OP_AND, 0, $lhs, $rhs); } | |
1129 | | term[lhs] OROR term[rhs] /* $x || $y */ | |
1130 | { $$ = newLOGOP(OP_OR, 0, $lhs, $rhs); } | |
1131 | | term[lhs] DORDOR term[rhs] /* $x // $y */ | |
1132 | { $$ = newLOGOP(OP_DOR, 0, $lhs, $rhs); } | |
1133 | | term[lhs] MATCHOP term[rhs] /* $x =~ /$y/ */ | |
1134 | { $$ = bind_match($MATCHOP, $lhs, $rhs); } | |
891be019 | 1135 | ; |
8d063cd8 | 1136 | |
02b85d3d | 1137 | termrelop: relopchain %prec PREC_LOW |
53443c95 BZ |
1138 | { $$ = cmpchain_finish($relopchain); } |
1139 | | term[lhs] NCRELOP term[rhs] | |
1140 | { $$ = newBINOP($NCRELOP, 0, scalar($lhs), scalar($rhs)); } | |
02b85d3d Z |
1141 | | termrelop NCRELOP |
1142 | { yyerror("syntax error"); YYERROR; } | |
1143 | | termrelop CHRELOP | |
1144 | { yyerror("syntax error"); YYERROR; } | |
1145 | ; | |
1146 | ||
53443c95 BZ |
1147 | relopchain: term[lhs] CHRELOP term[rhs] |
1148 | { $$ = cmpchain_start($CHRELOP, $lhs, $rhs); } | |
1149 | | relopchain[lhs] CHRELOP term[rhs] | |
1150 | { $$ = cmpchain_extend($CHRELOP, $lhs, $rhs); } | |
02b85d3d Z |
1151 | ; |
1152 | ||
1153 | termeqop: eqopchain %prec PREC_LOW | |
53443c95 BZ |
1154 | { $$ = cmpchain_finish($eqopchain); } |
1155 | | term[lhs] NCEQOP term[rhs] | |
1156 | { $$ = newBINOP($NCEQOP, 0, scalar($lhs), scalar($rhs)); } | |
02b85d3d Z |
1157 | | termeqop NCEQOP |
1158 | { yyerror("syntax error"); YYERROR; } | |
1159 | | termeqop CHEQOP | |
1160 | { yyerror("syntax error"); YYERROR; } | |
1161 | ; | |
1162 | ||
53443c95 BZ |
1163 | eqopchain: term[lhs] CHEQOP term[rhs] |
1164 | { $$ = cmpchain_start($CHEQOP, $lhs, $rhs); } | |
1165 | | eqopchain[lhs] CHEQOP term[rhs] | |
1166 | { $$ = cmpchain_extend($CHEQOP, $lhs, $rhs); } | |
02b85d3d Z |
1167 | ; |
1168 | ||
891be019 | 1169 | /* Unary operators and terms */ |
68a66a8b | 1170 | termunop : PERLY_MINUS term %prec UMINUS /* -$x */ |
53443c95 | 1171 | { $$ = newUNOP(OP_NEGATE, 0, scalar($term)); } |
5776f3e5 | 1172 | | PERLY_PLUS term %prec UMINUS /* +$x */ |
53443c95 | 1173 | { $$ = $term; } |
b5bbe64a | 1174 | |
1c2e9449 | 1175 | | PERLY_EXCLAMATION_MARK term /* !$x */ |
53443c95 | 1176 | { $$ = newUNOP(OP_NOT, 0, scalar($term)); } |
3d92c6b8 BZ |
1177 | | PERLY_TILDE term /* ~$x */ |
1178 | { $$ = newUNOP($PERLY_TILDE, 0, scalar($term)); } | |
891be019 | 1179 | | term POSTINC /* $x++ */ |
79072805 | 1180 | { $$ = newUNOP(OP_POSTINC, 0, |
53443c95 | 1181 | op_lvalue(scalar($term), OP_POSTINC)); } |
891be019 | 1182 | | term POSTDEC /* $x-- */ |
79072805 | 1183 | { $$ = newUNOP(OP_POSTDEC, 0, |
53443c95 | 1184 | op_lvalue(scalar($term), OP_POSTDEC));} |
cc624add | 1185 | | term POSTJOIN /* implicit join after interpolated ->@ */ |
03d05f6e | 1186 | { $$ = op_convert_list(OP_JOIN, 0, |
cc624add FC |
1187 | op_append_elem( |
1188 | OP_LIST, | |
1189 | newSVREF(scalar( | |
1190 | newSVOP(OP_CONST,0, | |
1191 | newSVpvs("\"")) | |
1192 | )), | |
53443c95 | 1193 | $term |
cc624add | 1194 | )); |
cc624add | 1195 | } |
891be019 | 1196 | | PREINC term /* ++$x */ |
79072805 | 1197 | { $$ = newUNOP(OP_PREINC, 0, |
53443c95 | 1198 | op_lvalue(scalar($term), OP_PREINC)); } |
891be019 | 1199 | | PREDEC term /* --$x */ |
79072805 | 1200 | { $$ = newUNOP(OP_PREDEC, 0, |
53443c95 | 1201 | op_lvalue(scalar($term), OP_PREDEC)); } |
891be019 SC |
1202 | |
1203 | ; | |
1204 | ||
1205 | /* Constructors for anonymous data */ | |
18cbf839 BZ |
1206 | anonymous |
1207 | : PERLY_BRACKET_OPEN optexpr PERLY_BRACKET_CLOSE | |
1208 | { $$ = newANONLIST($optexpr); } | |
1209 | | HASHBRACK optexpr PERLY_SEMICOLON PERLY_BRACE_CLOSE %prec PERLY_PAREN_OPEN /* { foo => "Bar" } */ | |
1210 | { $$ = newANONHASH($optexpr); } | |
68670bd9 | 1211 | | KW_SUB_anon startanonsub proto subattrlist subbody %prec PERLY_PAREN_OPEN |
436ddf68 | 1212 | { SvREFCNT_inc_simple_void(PL_compcv); |
53443c95 | 1213 | $$ = newANONATTRSUB($startanonsub, $proto, $subattrlist, $subbody); } |
68670bd9 | 1214 | | KW_SUB_anon_sig startanonsub subattrlist sigsubbody %prec PERLY_PAREN_OPEN |
5a5094bd | 1215 | { SvREFCNT_inc_simple_void(PL_compcv); |
53443c95 | 1216 | $$ = newANONATTRSUB($startanonsub, NULL, $subattrlist, $sigsubbody); } |
891be019 SC |
1217 | ; |
1218 | ||
1219 | /* Things called with "do" */ | |
68670bd9 PE |
1220 | termdo : KW_DO term %prec UNIOP /* do $filename */ |
1221 | { $$ = dofile($term, $KW_DO);} | |
1222 | | KW_DO block %prec PERLY_PAREN_OPEN /* do { code */ | |
53443c95 | 1223 | { $$ = newUNOP(OP_NULL, OPf_SPECIAL, op_scope($block));} |
891be019 SC |
1224 | ; |
1225 | ||
53443c95 | 1226 | term[product] : termbinop |
891be019 SC |
1227 | | termunop |
1228 | | anonymous | |
1229 | | termdo | |
a1ad62bf | 1230 | | term[condition] PERLY_QUESTION_MARK term[then] PERLY_COLON term[else] |
53443c95 BZ |
1231 | { $$ = newCONDOP(0, $condition, $then, $else); } |
1232 | | REFGEN term[operand] /* \$x, \@y, \%z */ | |
1233 | { $$ = newUNOP(OP_REFGEN, 0, $operand); } | |
09bef843 | 1234 | | myattrterm %prec UNIOP |
53443c95 | 1235 | { $$ = $myattrterm; } |
68670bd9 | 1236 | | KW_LOCAL term[operand] %prec UNIOP |
53443c95 | 1237 | { $$ = localize($operand,0); } |
04884b68 | 1238 | | PERLY_PAREN_OPEN expr PERLY_PAREN_CLOSE |
53443c95 | 1239 | { $$ = sawparens($expr); } |
ea25a9b2 | 1240 | | QWLIST |
53443c95 | 1241 | { $$ = $QWLIST; } |
04884b68 | 1242 | | PERLY_PAREN_OPEN PERLY_PAREN_CLOSE |
b5bbe64a | 1243 | { $$ = sawparens(newNULLLIST()); } |
ee67f254 | 1244 | | scalar %prec PERLY_PAREN_OPEN |
53443c95 | 1245 | { $$ = $scalar; } |
ee67f254 | 1246 | | star %prec PERLY_PAREN_OPEN |
53443c95 | 1247 | { $$ = $star; } |
ee67f254 | 1248 | | hsh %prec PERLY_PAREN_OPEN |
53443c95 | 1249 | { $$ = $hsh; } |
ee67f254 | 1250 | | ary %prec PERLY_PAREN_OPEN |
53443c95 | 1251 | { $$ = $ary; } |
ee67f254 | 1252 | | arylen %prec PERLY_PAREN_OPEN /* $#x, $#{ something } */ |
53443c95 | 1253 | { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($arylen, OP_AV2ARYLEN));} |
fad39ff1 | 1254 | | subscripted |
53443c95 | 1255 | { $$ = $subscripted; } |
fceeeb77 | 1256 | | sliceme PERLY_BRACKET_OPEN expr PERLY_BRACKET_CLOSE /* array slice */ |
2fcb4757 | 1257 | { $$ = op_prepend_elem(OP_ASLICE, |
79072805 | 1258 | newOP(OP_PUSHMARK, 0), |
79072805 | 1259 | newLISTOP(OP_ASLICE, 0, |
53443c95 BZ |
1260 | list($expr), |
1261 | ref($sliceme, OP_ASLICE))); | |
1262 | if ($$ && $sliceme) | |
429a2555 | 1263 | $$->op_private |= |
53443c95 | 1264 | $sliceme->op_private & OPpSLICEWARNING; |
f05e27e5 | 1265 | } |
fceeeb77 | 1266 | | kvslice PERLY_BRACKET_OPEN expr PERLY_BRACKET_CLOSE /* array key/value slice */ |
6dd3e0f2 RZ |
1267 | { $$ = op_prepend_elem(OP_KVASLICE, |
1268 | newOP(OP_PUSHMARK, 0), | |
1269 | newLISTOP(OP_KVASLICE, 0, | |
53443c95 BZ |
1270 | list($expr), |
1271 | ref(oopsAV($kvslice), OP_KVASLICE))); | |
1272 | if ($$ && $kvslice) | |
95a31aad | 1273 | $$->op_private |= |
53443c95 | 1274 | $kvslice->op_private & OPpSLICEWARNING; |
6dd3e0f2 | 1275 | } |
5adeeefb | 1276 | | sliceme PERLY_BRACE_OPEN expr PERLY_SEMICOLON PERLY_BRACE_CLOSE /* @hash{@keys} */ |
2fcb4757 | 1277 | { $$ = op_prepend_elem(OP_HSLICE, |
79072805 | 1278 | newOP(OP_PUSHMARK, 0), |
79072805 | 1279 | newLISTOP(OP_HSLICE, 0, |
53443c95 BZ |
1280 | list($expr), |
1281 | ref(oopsHV($sliceme), OP_HSLICE))); | |
1282 | if ($$ && $sliceme) | |
429a2555 | 1283 | $$->op_private |= |
53443c95 | 1284 | $sliceme->op_private & OPpSLICEWARNING; |
f05e27e5 | 1285 | } |
5adeeefb | 1286 | | kvslice PERLY_BRACE_OPEN expr PERLY_SEMICOLON PERLY_BRACE_CLOSE /* %hash{@keys} */ |
5cae3edb RZ |
1287 | { $$ = op_prepend_elem(OP_KVHSLICE, |
1288 | newOP(OP_PUSHMARK, 0), | |
1289 | newLISTOP(OP_KVHSLICE, 0, | |
53443c95 BZ |
1290 | list($expr), |
1291 | ref($kvslice, OP_KVHSLICE))); | |
1292 | if ($$ && $kvslice) | |
95a31aad | 1293 | $$->op_private |= |
53443c95 | 1294 | $kvslice->op_private & OPpSLICEWARNING; |
5cae3edb | 1295 | } |
ee67f254 | 1296 | | THING %prec PERLY_PAREN_OPEN |
53443c95 | 1297 | { $$ = $THING; } |
891be019 | 1298 | | amper /* &foo; */ |
53443c95 | 1299 | { $$ = newUNOP(OP_ENTERSUB, 0, scalar($amper)); } |
04884b68 | 1300 | | amper PERLY_PAREN_OPEN PERLY_PAREN_CLOSE /* &foo() or foo() */ |
53443c95 | 1301 | { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($amper)); |
f05e27e5 | 1302 | } |
04884b68 | 1303 | | amper PERLY_PAREN_OPEN expr PERLY_PAREN_CLOSE /* &foo(@args) or foo(@args) */ |
f05e27e5 DM |
1304 | { |
1305 | $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, | |
53443c95 | 1306 | op_append_elem(OP_LIST, $expr, scalar($amper))); |
f05e27e5 | 1307 | } |
fb602e32 | 1308 | | NOAMP subname optlistexpr /* foo @args (no parens) */ |
a0d0e21e | 1309 | { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, |
53443c95 BZ |
1310 | op_append_elem(OP_LIST, $optlistexpr, scalar($subname))); |
1311 | } | |
bfa838cc | 1312 | | term[operand] ARROW PERLY_DOLLAR PERLY_STAR |
53443c95 | 1313 | { $$ = newSVREF($operand); } |
d02b2fbf | 1314 | | term[operand] ARROW PERLY_SNAIL PERLY_STAR |
53443c95 | 1315 | { $$ = newAVREF($operand); } |
d02b2fbf | 1316 | | term[operand] ARROW PERLY_PERCENT_SIGN PERLY_STAR |
53443c95 | 1317 | { $$ = newHVREF($operand); } |
d02b2fbf | 1318 | | term[operand] ARROW PERLY_AMPERSAND PERLY_STAR |
89f35911 | 1319 | { $$ = newUNOP(OP_ENTERSUB, 0, |
25a50500 | 1320 | scalar(newCVREF($PERLY_AMPERSAND,$operand))); } |
d02b2fbf | 1321 | | term[operand] ARROW PERLY_STAR PERLY_STAR %prec PERLY_PAREN_OPEN |
53443c95 | 1322 | { $$ = newGVREF(0,$operand); } |
891be019 | 1323 | | LOOPEX /* loop exiting command (goto, last, dump, etc) */ |
53443c95 | 1324 | { $$ = newOP($LOOPEX, OPf_SPECIAL); |
b5bbe64a | 1325 | PL_hints |= HINT_BLOCK_SCOPE; } |
53443c95 BZ |
1326 | | LOOPEX term[operand] |
1327 | { $$ = newLOOPEX($LOOPEX,$operand); } | |
09b1cffe | 1328 | | NOTOP listexpr /* not $foo */ |
53443c95 | 1329 | { $$ = newUNOP(OP_NOT, 0, scalar($listexpr)); } |
891be019 | 1330 | | UNIOP /* Unary op, $_ implied */ |
53443c95 | 1331 | { $$ = newOP($UNIOP, 0); } |
f05e27e5 | 1332 | | UNIOP block /* eval { foo }* */ |
53443c95 BZ |
1333 | { $$ = newUNOP($UNIOP, 0, $block); } |
1334 | | UNIOP term[operand] /* Unary op */ | |
1335 | { $$ = newUNOP($UNIOP, 0, $operand); } | |
68670bd9 PE |
1336 | | KW_REQUIRE /* require, $_ implied */ |
1337 | { $$ = newOP(OP_REQUIRE, $KW_REQUIRE ? OPf_SPECIAL : 0); } | |
1338 | | KW_REQUIRE term[operand] /* require Foo */ | |
1339 | { $$ = newUNOP(OP_REQUIRE, $KW_REQUIRE ? OPf_SPECIAL : 0, $operand); } | |
3cd0a11a | 1340 | | UNIOPSUB |
53443c95 BZ |
1341 | { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($UNIOPSUB)); } |
1342 | | UNIOPSUB term[operand] /* Sub treated as unop */ | |
4633a7c4 | 1343 | { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, |
53443c95 | 1344 | op_append_elem(OP_LIST, $operand, scalar($UNIOPSUB))); } |
891be019 | 1345 | | FUNC0 /* Nullary operator */ |
53443c95 | 1346 | { $$ = newOP($FUNC0, 0); } |
04884b68 | 1347 | | FUNC0 PERLY_PAREN_OPEN PERLY_PAREN_CLOSE |
53443c95 | 1348 | { $$ = newOP($FUNC0, 0);} |
7eb971ee | 1349 | | FUNC0OP /* Same as above, but op created in toke.c */ |
53443c95 | 1350 | { $$ = $FUNC0OP; } |
04884b68 | 1351 | | FUNC0OP PERLY_PAREN_OPEN PERLY_PAREN_CLOSE |
53443c95 | 1352 | { $$ = $FUNC0OP; } |
891be019 | 1353 | | FUNC0SUB /* Sub treated as nullop */ |
53443c95 | 1354 | { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($FUNC0SUB)); } |
04884b68 | 1355 | | FUNC1 PERLY_PAREN_OPEN PERLY_PAREN_CLOSE /* not () */ |
53443c95 BZ |
1356 | { $$ = ($FUNC1 == OP_NOT) |
1357 | ? newUNOP($FUNC1, 0, newSVOP(OP_CONST, 0, newSViv(0))) | |
1358 | : newOP($FUNC1, OPf_SPECIAL); } | |
04884b68 | 1359 | | FUNC1 PERLY_PAREN_OPEN expr PERLY_PAREN_CLOSE /* not($foo) */ |
53443c95 | 1360 | { $$ = newUNOP($FUNC1, 0, $expr); } |
d63c20f2 DM |
1361 | | PMFUNC /* m//, s///, qr//, tr/// */ |
1362 | { | |
53443c95 BZ |
1363 | if ( $PMFUNC->op_type != OP_TRANS |
1364 | && $PMFUNC->op_type != OP_TRANSR | |
1365 | && (((PMOP*)$PMFUNC)->op_pmflags & PMf_HAS_CV)) | |
d63c20f2 DM |
1366 | { |
1367 | $<ival>$ = start_subparse(FALSE, CVf_ANON); | |
1368 | SAVEFREESV(PL_compcv); | |
1369 | } else | |
1370 | $<ival>$ = 0; | |
1371 | } | |
69afcc21 | 1372 | SUBLEXSTART listexpr optrepl SUBLEXEND |
53443c95 | 1373 | { $$ = pmruntime($PMFUNC, $listexpr, $optrepl, 1, $<ival>2); } |
185c2e96 | 1374 | | BAREWORD |
378cc40b | 1375 | | listop |
88e1f1a2 | 1376 | | PLUGEXPR |
8d063cd8 LW |
1377 | ; |
1378 | ||
891be019 | 1379 | /* "my" declarations, with optional attributes */ |
7cbc5f3b | 1380 | myattrterm |
68670bd9 | 1381 | : KW_MY myterm myattrlist |
53443c95 | 1382 | { $$ = my_attrs($myterm,$myattrlist); } |
68670bd9 | 1383 | | KW_MY myterm |
53443c95 | 1384 | { $$ = localize($myterm,1); } |
68670bd9 | 1385 | | KW_MY REFGEN myterm myattrlist |
53443c95 | 1386 | { $$ = newUNOP(OP_REFGEN, 0, my_attrs($myterm,$myattrlist)); } |
68670bd9 | 1387 | | KW_MY REFGEN term[operand] |
7cbc5f3b | 1388 | { $$ = newUNOP(OP_REFGEN, 0, localize($operand,1)); } |
09bef843 SB |
1389 | ; |
1390 | ||
891be019 | 1391 | /* Things that can be "my"'d */ |
04884b68 | 1392 | myterm : PERLY_PAREN_OPEN expr PERLY_PAREN_CLOSE |
53443c95 | 1393 | { $$ = sawparens($expr); } |
04884b68 | 1394 | | PERLY_PAREN_OPEN PERLY_PAREN_CLOSE |
b5bbe64a JH |
1395 | { $$ = sawparens(newNULLLIST()); } |
1396 | ||
ee67f254 | 1397 | | scalar %prec PERLY_PAREN_OPEN |
53443c95 | 1398 | { $$ = $scalar; } |
ee67f254 | 1399 | | hsh %prec PERLY_PAREN_OPEN |
53443c95 | 1400 | { $$ = $hsh; } |
ee67f254 | 1401 | | ary %prec PERLY_PAREN_OPEN |
53443c95 | 1402 | { $$ = $ary; } |
09bef843 SB |
1403 | ; |
1404 | ||
891be019 | 1405 | /* Basic list expressions */ |
148f5aaf | 1406 | optlistexpr |
6e9eef66 BZ |
1407 | : empty %prec PREC_LOW |
1408 | | listexpr %prec PREC_LOW | |
a0d0e21e LW |
1409 | ; |
1410 | ||
148f5aaf BZ |
1411 | optexpr |
1412 | : empty | |
79072805 | 1413 | | expr |
79072805 LW |
1414 | ; |
1415 | ||
148f5aaf BZ |
1416 | optrepl |
1417 | : empty | |
6e9eef66 | 1418 | | PERLY_SLASH expr { $$ = $expr; } |
9b6b7be8 FC |
1419 | ; |
1420 | ||
891be019 SC |
1421 | /* A little bit of trickery to make "for my $foo (@bar)" actually be |
1422 | lexical */ | |
55497cff | 1423 | my_scalar: scalar |
53443c95 | 1424 | { parser->in_my = 0; $$ = my($scalar); } |
55497cff | 1425 | ; |
1426 | ||
e92ce056 NC |
1427 | /* A list of scalars for "for my ($foo, $bar) (@baz)" */ |
1428 | list_of_scalars: list_of_scalars[list] PERLY_COMMA | |
ebb7bd1b | 1429 | { $$ = $list; } |
e92ce056 NC |
1430 | | list_of_scalars[list] PERLY_COMMA scalar |
1431 | { | |
1432 | $$ = op_append_elem(OP_LIST, $list, $scalar); | |
1433 | } | |
1434 | | scalar %prec PREC_LOW | |
1435 | ; | |
1436 | ||
1437 | my_list_of_scalars: list_of_scalars | |
1438 | { parser->in_my = 0; $$ = $list_of_scalars; } | |
1439 | ; | |
1440 | ||
d39c26a6 FC |
1441 | my_var : scalar |
1442 | | ary | |
1443 | | hsh | |
1444 | ; | |
1445 | ||
1446 | refgen_topic: my_var | |
1447 | | amper | |
1448 | ; | |
1449 | ||
68670bd9 PE |
1450 | my_refgen: KW_MY REFGEN |
1451 | | REFGEN KW_MY | |
e118fea3 FC |
1452 | ; |
1453 | ||
25a50500 BZ |
1454 | amper : PERLY_AMPERSAND indirob |
1455 | { $$ = newCVREF($PERLY_AMPERSAND,$indirob); } | |
a687059c LW |
1456 | ; |
1457 | ||
bfa838cc | 1458 | scalar : PERLY_DOLLAR indirob |
53443c95 | 1459 | { $$ = newSVREF($indirob); } |
a687059c LW |
1460 | ; |
1461 | ||
9086c946 | 1462 | ary : PERLY_SNAIL indirob |
53443c95 | 1463 | { $$ = newAVREF($indirob); |
9086c946 | 1464 | if ($$) $$->op_private |= $PERLY_SNAIL; |
f05e27e5 | 1465 | } |
79072805 LW |
1466 | ; |
1467 | ||
0ba95c59 | 1468 | hsh : PERLY_PERCENT_SIGN indirob |
53443c95 | 1469 | { $$ = newHVREF($indirob); |
0ba95c59 | 1470 | if ($$) $$->op_private |= $PERLY_PERCENT_SIGN; |
f05e27e5 | 1471 | } |
79072805 LW |
1472 | ; |
1473 | ||
1474 | arylen : DOLSHARP indirob | |
53443c95 | 1475 | { $$ = newAVREF($indirob); } |
d02b2fbf | 1476 | | term ARROW DOLSHARP PERLY_STAR |
53443c95 | 1477 | { $$ = newAVREF($term); } |
79072805 LW |
1478 | ; |
1479 | ||
d02b2fbf | 1480 | star : PERLY_STAR indirob |
53443c95 | 1481 | { $$ = newGVREF(0,$indirob); } |
79072805 LW |
1482 | ; |
1483 | ||
89f35911 | 1484 | sliceme : ary |
9086c946 | 1485 | | term ARROW PERLY_SNAIL |
53443c95 | 1486 | { $$ = newAVREF($term); } |
89f35911 FC |
1487 | ; |
1488 | ||
76eba8ab | 1489 | kvslice : hsh |
0ba95c59 | 1490 | | term ARROW PERLY_PERCENT_SIGN |
53443c95 | 1491 | { $$ = newHVREF($term); } |
76eba8ab FC |
1492 | ; |
1493 | ||
89f35911 | 1494 | gelem : star |
d02b2fbf | 1495 | | term ARROW PERLY_STAR |
53443c95 | 1496 | { $$ = newGVREF(0,$term); } |
89f35911 FC |
1497 | ; |
1498 | ||
891be019 | 1499 | /* Indirect objects */ |
185c2e96 | 1500 | indirob : BAREWORD |
53443c95 | 1501 | { $$ = scalar($BAREWORD); } |
fad39ff1 | 1502 | | scalar %prec PREC_LOW |
53443c95 | 1503 | { $$ = scalar($scalar); } |
79072805 | 1504 | | block |
53443c95 | 1505 | { $$ = op_scope($block); } |
79072805 | 1506 | |
93a17b20 | 1507 | | PRIVATEREF |
53443c95 | 1508 | { $$ = $PRIVATEREF; } |
8d063cd8 | 1509 | ; |