This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
a "replacement" for awk and sed
[perl5.git] / perl.y
CommitLineData
8d063cd8
LW
1/* $Header: perl.y,v 1.0 87/12/18 15:48:59 root Exp $
2 *
3 * $Log: perl.y,v $
4 * Revision 1.0 87/12/18 15:48:59 root
5 * Initial revision
6 *
7 */
8
9%{
10#include "handy.h"
11#include "EXTERN.h"
12#include "search.h"
13#include "util.h"
14#include "INTERN.h"
15#include "perl.h"
16char *tokename[] = {
17"256",
18"word",
19"append","open","write","select","close","loopctl",
20"using","format","do","shift","push","pop","chop",
21"while","until","if","unless","else","elsif","continue","split","sprintf",
22"for", "eof", "tell", "seek", "stat",
23"function(no args)","function(1 arg)","function(2 args)","function(3 args)","array function",
24"join", "sub",
25"format lines",
26"register","array_length", "array",
27"s","pattern",
28"string","y",
29"print", "unary operation",
30"..",
31"||",
32"&&",
33"==","!=", "EQ", "NE",
34"<=",">=", "LT", "GT", "LE", "GE",
35"<<",">>",
36"=~","!~",
37"unary -",
38"++", "--",
39"???"
40};
41
42%}
43
44%start prog
45
46%union {
47 int ival;
48 char *cval;
49 ARG *arg;
50 CMD *cmdval;
51 struct compcmd compval;
52 STAB *stabval;
53 FCMD *formval;
54}
55
56%token <cval> WORD
57%token <ival> APPEND OPEN WRITE SELECT CLOSE LOOPEX
58%token <ival> USING FORMAT DO SHIFT PUSH POP CHOP
59%token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE SPLIT SPRINTF
60%token <ival> FOR FEOF TELL SEEK STAT
61%token <ival> FUNC0 FUNC1 FUNC2 FUNC3 STABFUN
62%token <ival> JOIN SUB
63%token <formval> FORMLIST
64%token <stabval> REG ARYLEN ARY
65%token <arg> SUBST PATTERN
66%token <arg> RSTRING TRANS
67
68%type <ival> prog decl format
69%type <stabval>
70%type <cmdval> block lineseq line loop cond sideff nexpr else
71%type <arg> expr sexpr term
72%type <arg> condmod loopmod cexpr
73%type <arg> texpr print
74%type <cval> label
75%type <compval> compblock
76
77%nonassoc <ival> PRINT
78%left ','
79%nonassoc <ival> UNIOP
80%right '='
81%right '?' ':'
82%nonassoc DOTDOT
83%left OROR
84%left ANDAND
85%left '|' '^'
86%left '&'
87%nonassoc EQ NE SEQ SNE
88%nonassoc '<' '>' LE GE SLT SGT SLE SGE
89%left LS RS
90%left '+' '-' '.'
91%left '*' '/' '%' 'x'
92%left MATCH NMATCH
93%right '!' '~' UMINUS
94%nonassoc INC DEC
95%left '('
96
97%% /* RULES */
98
99prog : lineseq
100 { main_root = block_head($1); }
101 ;
102
103compblock: block CONTINUE block
104 { $$.comp_true = $1; $$.comp_alt = $3; }
105 | block else
106 { $$.comp_true = $1; $$.comp_alt = $2; }
107 ;
108
109else : /* NULL */
110 { $$ = Nullcmd; }
111 | ELSE block
112 { $$ = $2; }
113 | ELSIF '(' expr ')' compblock
114 { $$ = make_ccmd(C_IF,$3,$5); }
115 ;
116
117block : '{' lineseq '}'
118 { $$ = block_head($2); }
119 ;
120
121lineseq : /* NULL */
122 { $$ = Nullcmd; }
123 | lineseq line
124 { $$ = append_line($1,$2); }
125 ;
126
127line : decl
128 { $$ = Nullcmd; }
129 | label cond
130 { $$ = add_label($1,$2); }
131 | loop /* loops add their own labels */
132 | label ';'
133 { if ($1 != Nullch) {
134 $$ = add_label(make_acmd(C_EXPR, Nullstab,
135 Nullarg, Nullarg) );
136 } else
137 $$ = Nullcmd; }
138 | label sideff ';'
139 { $$ = add_label($1,$2); }
140 ;
141
142sideff : expr
143 { $$ = make_acmd(C_EXPR, Nullstab, $1, Nullarg); }
144 | expr condmod
145 { $$ = addcond(
146 make_acmd(C_EXPR, Nullstab, Nullarg, $1), $2); }
147 | expr loopmod
148 { $$ = addloop(
149 make_acmd(C_EXPR, Nullstab, Nullarg, $1), $2); }
150 ;
151
152cond : IF '(' expr ')' compblock
153 { $$ = make_ccmd(C_IF,$3,$5); }
154 | UNLESS '(' expr ')' compblock
155 { $$ = invert(make_ccmd(C_IF,$3,$5)); }
156 | IF block compblock
157 { $$ = make_ccmd(C_IF,cmd_to_arg($2),$3); }
158 | UNLESS block compblock
159 { $$ = invert(make_ccmd(C_IF,cmd_to_arg($2),$3)); }
160 ;
161
162loop : label WHILE '(' texpr ')' compblock
163 { $$ = wopt(add_label($1,
164 make_ccmd(C_WHILE,$4,$6) )); }
165 | label UNTIL '(' expr ')' compblock
166 { $$ = wopt(add_label($1,
167 invert(make_ccmd(C_WHILE,$4,$6)) )); }
168 | label WHILE block compblock
169 { $$ = wopt(add_label($1,
170 make_ccmd(C_WHILE, cmd_to_arg($3),$4) )); }
171 | label UNTIL block compblock
172 { $$ = wopt(add_label($1,
173 invert(make_ccmd(C_WHILE, cmd_to_arg($3),$4)) )); }
174 | label FOR '(' nexpr ';' texpr ';' nexpr ')' block
175 /* basically fake up an initialize-while lineseq */
176 { yyval.compval.comp_true = $10;
177 yyval.compval.comp_alt = $8;
178 $$ = append_line($4,wopt(add_label($1,
179 make_ccmd(C_WHILE,$6,yyval.compval) ))); }
180 | label compblock /* a block is a loop that happens once */
181 { $$ = add_label($1,make_ccmd(C_BLOCK,Nullarg,$2)); }
182 ;
183
184nexpr : /* NULL */
185 { $$ = Nullcmd; }
186 | sideff
187 ;
188
189texpr : /* NULL means true */
190 { scanstr("1"); $$ = yylval.arg; }
191 | expr
192 ;
193
194label : /* empty */
195 { $$ = Nullch; }
196 | WORD ':'
197 ;
198
199loopmod : WHILE expr
200 { $$ = $2; }
201 | UNTIL expr
202 { $$ = make_op(O_NOT,1,$2,Nullarg,Nullarg,0); }
203 ;
204
205condmod : IF expr
206 { $$ = $2; }
207 | UNLESS expr
208 { $$ = make_op(O_NOT,1,$2,Nullarg,Nullarg,0); }
209 ;
210
211decl : format
212 { $$ = 0; }
213 | subrout
214 { $$ = 0; }
215 ;
216
217format : FORMAT WORD '=' FORMLIST '.'
218 { stabent($2,TRUE)->stab_form = $4; safefree($2); }
219 | FORMAT '=' FORMLIST '.'
220 { stabent("stdout",TRUE)->stab_form = $3; }
221 ;
222
223subrout : SUB WORD block
224 { stabent($2,TRUE)->stab_sub = $3; }
225 ;
226
227expr : print
228 | cexpr
229 ;
230
231cexpr : sexpr ',' cexpr
232 { $$ = make_op(O_COMMA, 2, $1, $3, Nullarg,0); }
233 | sexpr
234 ;
235
236sexpr : sexpr '=' sexpr
237 { $1 = listish($1);
238 if ($1->arg_type == O_LIST)
239 $3 = listish($3);
240 $$ = l(make_op(O_ASSIGN, 2, $1, $3, Nullarg,1)); }
241 | sexpr '*' '=' sexpr
242 { $$ = l(make_op(O_MULTIPLY, 2, $1, $4, Nullarg,0)); }
243 | sexpr '/' '=' sexpr
244 { $$ = l(make_op(O_DIVIDE, 2, $1, $4, Nullarg,0)); }
245 | sexpr '%' '=' sexpr
246 { $$ = l(make_op(O_MODULO, 2, $1, $4, Nullarg,0)); }
247 | sexpr 'x' '=' sexpr
248 { $$ = l(make_op(O_REPEAT, 2, $1, $4, Nullarg,0)); }
249 | sexpr '+' '=' sexpr
250 { $$ = l(make_op(O_ADD, 2, $1, $4, Nullarg,0)); }
251 | sexpr '-' '=' sexpr
252 { $$ = l(make_op(O_SUBTRACT, 2, $1, $4, Nullarg,0)); }
253 | sexpr LS '=' sexpr
254 { $$ = l(make_op(O_LEFT_SHIFT, 2, $1, $4, Nullarg,0)); }
255 | sexpr RS '=' sexpr
256 { $$ = l(make_op(O_RIGHT_SHIFT, 2, $1, $4, Nullarg,0)); }
257 | sexpr '&' '=' sexpr
258 { $$ = l(make_op(O_BIT_AND, 2, $1, $4, Nullarg,0)); }
259 | sexpr '^' '=' sexpr
260 { $$ = l(make_op(O_XOR, 2, $1, $4, Nullarg,0)); }
261 | sexpr '|' '=' sexpr
262 { $$ = l(make_op(O_BIT_OR, 2, $1, $4, Nullarg,0)); }
263 | sexpr '.' '=' sexpr
264 { $$ = l(make_op(O_CONCAT, 2, $1, $4, Nullarg,0)); }
265
266
267 | sexpr '*' sexpr
268 { $$ = make_op(O_MULTIPLY, 2, $1, $3, Nullarg,0); }
269 | sexpr '/' sexpr
270 { $$ = make_op(O_DIVIDE, 2, $1, $3, Nullarg,0); }
271 | sexpr '%' sexpr
272 { $$ = make_op(O_MODULO, 2, $1, $3, Nullarg,0); }
273 | sexpr 'x' sexpr
274 { $$ = make_op(O_REPEAT, 2, $1, $3, Nullarg,0); }
275 | sexpr '+' sexpr
276 { $$ = make_op(O_ADD, 2, $1, $3, Nullarg,0); }
277 | sexpr '-' sexpr
278 { $$ = make_op(O_SUBTRACT, 2, $1, $3, Nullarg,0); }
279 | sexpr LS sexpr
280 { $$ = make_op(O_LEFT_SHIFT, 2, $1, $3, Nullarg,0); }
281 | sexpr RS sexpr
282 { $$ = make_op(O_RIGHT_SHIFT, 2, $1, $3, Nullarg,0); }
283 | sexpr '<' sexpr
284 { $$ = make_op(O_LT, 2, $1, $3, Nullarg,0); }
285 | sexpr '>' sexpr
286 { $$ = make_op(O_GT, 2, $1, $3, Nullarg,0); }
287 | sexpr LE sexpr
288 { $$ = make_op(O_LE, 2, $1, $3, Nullarg,0); }
289 | sexpr GE sexpr
290 { $$ = make_op(O_GE, 2, $1, $3, Nullarg,0); }
291 | sexpr EQ sexpr
292 { $$ = make_op(O_EQ, 2, $1, $3, Nullarg,0); }
293 | sexpr NE sexpr
294 { $$ = make_op(O_NE, 2, $1, $3, Nullarg,0); }
295 | sexpr SLT sexpr
296 { $$ = make_op(O_SLT, 2, $1, $3, Nullarg,0); }
297 | sexpr SGT sexpr
298 { $$ = make_op(O_SGT, 2, $1, $3, Nullarg,0); }
299 | sexpr SLE sexpr
300 { $$ = make_op(O_SLE, 2, $1, $3, Nullarg,0); }
301 | sexpr SGE sexpr
302 { $$ = make_op(O_SGE, 2, $1, $3, Nullarg,0); }
303 | sexpr SEQ sexpr
304 { $$ = make_op(O_SEQ, 2, $1, $3, Nullarg,0); }
305 | sexpr SNE sexpr
306 { $$ = make_op(O_SNE, 2, $1, $3, Nullarg,0); }
307 | sexpr '&' sexpr
308 { $$ = make_op(O_BIT_AND, 2, $1, $3, Nullarg,0); }
309 | sexpr '^' sexpr
310 { $$ = make_op(O_XOR, 2, $1, $3, Nullarg,0); }
311 | sexpr '|' sexpr
312 { $$ = make_op(O_BIT_OR, 2, $1, $3, Nullarg,0); }
313 | sexpr DOTDOT sexpr
314 { $$ = make_op(O_FLIP, 4,
315 flipflip($1),
316 flipflip($3),
317 Nullarg,0);}
318 | sexpr ANDAND sexpr
319 { $$ = make_op(O_AND, 2, $1, $3, Nullarg,0); }
320 | sexpr OROR sexpr
321 { $$ = make_op(O_OR, 2, $1, $3, Nullarg,0); }
322 | sexpr '?' sexpr ':' sexpr
323 { $$ = make_op(O_COND_EXPR, 3, $1, $3, $5,0); }
324 | sexpr '.' sexpr
325 { $$ = make_op(O_CONCAT, 2, $1, $3, Nullarg,0); }
326 | sexpr MATCH sexpr
327 { $$ = mod_match(O_MATCH, $1, $3); }
328 | sexpr NMATCH sexpr
329 { $$ = mod_match(O_NMATCH, $1, $3); }
330 | term INC
331 { $$ = addflags(1, AF_POST|AF_UP,
332 l(make_op(O_ITEM,1,$1,Nullarg,Nullarg,0))); }
333 | term DEC
334 { $$ = addflags(1, AF_POST,
335 l(make_op(O_ITEM,1,$1,Nullarg,Nullarg,0))); }
336 | INC term
337 { $$ = addflags(1, AF_PRE|AF_UP,
338 l(make_op(O_ITEM,1,$2,Nullarg,Nullarg,0))); }
339 | DEC term
340 { $$ = addflags(1, AF_PRE,
341 l(make_op(O_ITEM,1,$2,Nullarg,Nullarg,0))); }
342 | term
343 { $$ = $1; }
344 ;
345
346term : '-' term %prec UMINUS
347 { $$ = make_op(O_NEGATE, 1, $2, Nullarg, Nullarg,0); }
348 | '!' term
349 { $$ = make_op(O_NOT, 1, $2, Nullarg, Nullarg,0); }
350 | '~' term
351 { $$ = make_op(O_COMPLEMENT, 1, $2, Nullarg, Nullarg,0);}
352 | '(' expr ')'
353 { $$ = make_list(hide_ary($2)); }
354 | '(' ')'
355 { $$ = make_list(Nullarg); }
356 | DO block %prec '('
357 { $$ = cmd_to_arg($2); }
358 | REG %prec '('
359 { $$ = stab_to_arg(A_STAB,$1); }
360 | REG '[' expr ']' %prec '('
361 { $$ = make_op(O_ARRAY, 2,
362 $3, stab_to_arg(A_STAB,aadd($1)), Nullarg,0); }
363 | ARY %prec '('
364 { $$ = make_op(O_ARRAY, 1,
365 stab_to_arg(A_STAB,$1),
366 Nullarg, Nullarg, 1); }
367 | REG '{' expr '}' %prec '('
368 { $$ = make_op(O_HASH, 2,
369 $3, stab_to_arg(A_STAB,hadd($1)), Nullarg,0); }
370 | ARYLEN %prec '('
371 { $$ = stab_to_arg(A_ARYLEN,$1); }
372 | RSTRING %prec '('
373 { $$ = $1; }
374 | PATTERN %prec '('
375 { $$ = $1; }
376 | SUBST %prec '('
377 { $$ = $1; }
378 | TRANS %prec '('
379 { $$ = $1; }
380 | DO WORD '(' expr ')'
381 { $$ = make_op(O_SUBR, 2,
382 make_list($4),
383 stab_to_arg(A_STAB,stabent($2,TRUE)),
384 Nullarg,1); }
385 | DO WORD '(' ')'
386 { $$ = make_op(O_SUBR, 2,
387 make_list(Nullarg),
388 stab_to_arg(A_STAB,stabent($2,TRUE)),
389 Nullarg,1); }
390 | LOOPEX
391 { $$ = make_op($1,0,Nullarg,Nullarg,Nullarg,0); }
392 | LOOPEX WORD
393 { $$ = make_op($1,1,cval_to_arg($2),
394 Nullarg,Nullarg,0); }
395 | UNIOP
396 { $$ = make_op($1,1,Nullarg,Nullarg,Nullarg,0); }
397 | UNIOP sexpr
398 { $$ = make_op($1,1,$2,Nullarg,Nullarg,0); }
399 | WRITE
400 { $$ = make_op(O_WRITE, 0,
401 Nullarg, Nullarg, Nullarg,0); }
402 | WRITE '(' ')'
403 { $$ = make_op(O_WRITE, 0,
404 Nullarg, Nullarg, Nullarg,0); }
405 | WRITE '(' WORD ')'
406 { $$ = l(make_op(O_WRITE, 1,
407 stab_to_arg(A_STAB,stabent($3,TRUE)),
408 Nullarg, Nullarg,0)); safefree($3); }
409 | WRITE '(' expr ')'
410 { $$ = make_op(O_WRITE, 1, $3, Nullarg, Nullarg,0); }
411 | SELECT '(' WORD ')'
412 { $$ = l(make_op(O_SELECT, 1,
413 stab_to_arg(A_STAB,stabent($3,TRUE)),
414 Nullarg, Nullarg,0)); safefree($3); }
415 | SELECT '(' expr ')'
416 { $$ = make_op(O_SELECT, 1, $3, Nullarg, Nullarg,0); }
417 | OPEN WORD %prec '('
418 { $$ = make_op(O_OPEN, 2,
419 stab_to_arg(A_STAB,stabent($2,TRUE)),
420 stab_to_arg(A_STAB,stabent($2,TRUE)),
421 Nullarg,0); }
422 | OPEN '(' WORD ')'
423 { $$ = make_op(O_OPEN, 2,
424 stab_to_arg(A_STAB,stabent($3,TRUE)),
425 stab_to_arg(A_STAB,stabent($3,TRUE)),
426 Nullarg,0); }
427 | OPEN '(' WORD ',' expr ')'
428 { $$ = make_op(O_OPEN, 2,
429 stab_to_arg(A_STAB,stabent($3,TRUE)),
430 $5, Nullarg,0); }
431 | CLOSE '(' WORD ')'
432 { $$ = make_op(O_CLOSE, 1,
433 stab_to_arg(A_STAB,stabent($3,TRUE)),
434 Nullarg, Nullarg,0); }
435 | CLOSE WORD %prec '('
436 { $$ = make_op(O_CLOSE, 1,
437 stab_to_arg(A_STAB,stabent($2,TRUE)),
438 Nullarg, Nullarg,0); }
439 | FEOF '(' WORD ')'
440 { $$ = make_op(O_EOF, 1,
441 stab_to_arg(A_STAB,stabent($3,TRUE)),
442 Nullarg, Nullarg,0); }
443 | FEOF '(' ')'
444 { $$ = make_op(O_EOF, 0,
445 stab_to_arg(A_STAB,stabent("ARGV",TRUE)),
446 Nullarg, Nullarg,0); }
447 | FEOF
448 { $$ = make_op(O_EOF, 0,
449 Nullarg, Nullarg, Nullarg,0); }
450 | TELL '(' WORD ')'
451 { $$ = make_op(O_TELL, 1,
452 stab_to_arg(A_STAB,stabent($3,TRUE)),
453 Nullarg, Nullarg,0); }
454 | TELL
455 { $$ = make_op(O_TELL, 0,
456 Nullarg, Nullarg, Nullarg,0); }
457 | SEEK '(' WORD ',' sexpr ',' expr ')'
458 { $$ = make_op(O_SEEK, 3,
459 stab_to_arg(A_STAB,stabent($3,TRUE)),
460 $5, $7,1); }
461 | PUSH '(' WORD ',' expr ')'
462 { $$ = make_op($1, 2,
463 make_list($5),
464 stab_to_arg(A_STAB,aadd(stabent($3,TRUE))),
465 Nullarg,1); }
466 | PUSH '(' ARY ',' expr ')'
467 { $$ = make_op($1, 2,
468 make_list($5),
469 stab_to_arg(A_STAB,$3),
470 Nullarg,1); }
471 | POP WORD %prec '('
472 { $$ = make_op(O_POP, 1,
473 stab_to_arg(A_STAB,aadd(stabent($2,TRUE))),
474 Nullarg, Nullarg,0); }
475 | POP '(' WORD ')'
476 { $$ = make_op(O_POP, 1,
477 stab_to_arg(A_STAB,aadd(stabent($3,TRUE))),
478 Nullarg, Nullarg,0); }
479 | POP ARY %prec '('
480 { $$ = make_op(O_POP, 1,
481 stab_to_arg(A_STAB,$2),
482 Nullarg,
483 Nullarg,
484 0); }
485 | POP '(' ARY ')'
486 { $$ = make_op(O_POP, 1,
487 stab_to_arg(A_STAB,$3),
488 Nullarg,
489 Nullarg,
490 0); }
491 | SHIFT WORD %prec '('
492 { $$ = make_op(O_SHIFT, 1,
493 stab_to_arg(A_STAB,aadd(stabent($2,TRUE))),
494 Nullarg, Nullarg,0); }
495 | SHIFT '(' WORD ')'
496 { $$ = make_op(O_SHIFT, 1,
497 stab_to_arg(A_STAB,aadd(stabent($3,TRUE))),
498 Nullarg, Nullarg,0); }
499 | SHIFT ARY %prec '('
500 { $$ = make_op(O_SHIFT, 1,
501 stab_to_arg(A_STAB,$2), Nullarg, Nullarg,0); }
502 | SHIFT '(' ARY ')'
503 { $$ = make_op(O_SHIFT, 1,
504 stab_to_arg(A_STAB,$3), Nullarg, Nullarg,0); }
505 | SHIFT %prec '('
506 { $$ = make_op(O_SHIFT, 1,
507 stab_to_arg(A_STAB,aadd(stabent("ARGV",TRUE))),
508 Nullarg, Nullarg,0); }
509 | SPLIT %prec '('
510 { scanpat("/[ \t\n]+/");
511 $$ = make_split(defstab,yylval.arg); }
512 | SPLIT '(' WORD ')'
513 { scanpat("/[ \t\n]+/");
514 $$ = make_split(stabent($3,TRUE),yylval.arg); }
515 | SPLIT '(' WORD ',' PATTERN ')'
516 { $$ = make_split(stabent($3,TRUE),$5); }
517 | SPLIT '(' WORD ',' PATTERN ',' sexpr ')'
518 { $$ = mod_match(O_MATCH,
519 $7,
520 make_split(stabent($3,TRUE),$5) ); }
521 | SPLIT '(' sexpr ',' sexpr ')'
522 { $$ = mod_match(O_MATCH, $5, make_split(defstab,$3) ); }
523 | SPLIT '(' sexpr ')'
524 { $$ = mod_match(O_MATCH,
525 stab_to_arg(A_STAB,defstab),
526 make_split(defstab,$3) ); }
527 | JOIN '(' WORD ',' expr ')'
528 { $$ = make_op(O_JOIN, 2,
529 $5,
530 stab_to_arg(A_STAB,aadd(stabent($3,TRUE))),
531 Nullarg,0); }
532 | JOIN '(' sexpr ',' expr ')'
533 { $$ = make_op(O_JOIN, 2,
534 $3,
535 make_list($5),
536 Nullarg,2); }
537 | SPRINTF '(' expr ')'
538 { $$ = make_op(O_SPRINTF, 1,
539 make_list($3),
540 Nullarg,
541 Nullarg,1); }
542 | STAT '(' WORD ')'
543 { $$ = l(make_op(O_STAT, 1,
544 stab_to_arg(A_STAB,stabent($3,TRUE)),
545 Nullarg, Nullarg,0)); }
546 | STAT '(' expr ')'
547 { $$ = make_op(O_STAT, 1, $3, Nullarg, Nullarg,0); }
548 | CHOP
549 { $$ = l(make_op(O_CHOP, 1,
550 stab_to_arg(A_STAB,defstab),
551 Nullarg, Nullarg,0)); }
552 | CHOP '(' expr ')'
553 { $$ = l(make_op(O_CHOP, 1, $3, Nullarg, Nullarg,0)); }
554 | FUNC0
555 { $$ = make_op($1, 0, Nullarg, Nullarg, Nullarg,0); }
556 | FUNC1 '(' expr ')'
557 { $$ = make_op($1, 1, $3, Nullarg, Nullarg,0); }
558 | FUNC2 '(' sexpr ',' expr ')'
559 { $$ = make_op($1, 2, $3, $5, Nullarg, 0); }
560 | FUNC3 '(' sexpr ',' sexpr ',' expr ')'
561 { $$ = make_op($1, 3, $3, $5, $7, 0); }
562 | STABFUN '(' WORD ')'
563 { $$ = make_op($1, 1,
564 stab_to_arg(A_STAB,hadd(stabent($3,TRUE))),
565 Nullarg,
566 Nullarg, 0); }
567 ;
568
569print : PRINT
570 { $$ = make_op($1,2,
571 stab_to_arg(A_STAB,defstab),
572 stab_to_arg(A_STAB,Nullstab),
573 Nullarg,0); }
574 | PRINT expr
575 { $$ = make_op($1,2,make_list($2),
576 stab_to_arg(A_STAB,Nullstab),
577 Nullarg,1); }
578 | PRINT WORD
579 { $$ = make_op($1,2,
580 stab_to_arg(A_STAB,defstab),
581 stab_to_arg(A_STAB,stabent($2,TRUE)),
582 Nullarg,1); }
583 | PRINT WORD expr
584 { $$ = make_op($1,2,make_list($3),
585 stab_to_arg(A_STAB,stabent($2,TRUE)),
586 Nullarg,1); }
587 ;
588
589%% /* PROGRAM */
590#include "perly.c"