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