perl 3.0: (no announcement message available)
[p5sagit/p5-mst-13.2.git] / perl.y
1 /* $Header: perl.y,v 3.0 89/10/18 15:22:04 lwall Locked $
2  *
3  *    Copyright (c) 1989, Larry Wall
4  *
5  *    You may distribute under the terms of the GNU General Public License
6  *    as specified in the README file that comes with the perl 3.0 kit.
7  *
8  * $Log:        perl.y,v $
9  * Revision 3.0  89/10/18  15:22:04  lwall
10  * 3.0 baseline
11  * 
12  */
13
14 %{
15 #include "INTERN.h"
16 #include "perl.h"
17
18 STAB *scrstab;
19 ARG *arg4;      /* rarely used arguments to make_op() */
20 ARG *arg5;
21
22 %}
23
24 %start prog
25
26 %union {
27     int ival;
28     char *cval;
29     ARG *arg;
30     CMD *cmdval;
31     struct compcmd compval;
32     STAB *stabval;
33     FCMD *formval;
34 }
35
36 %token <cval> WORD
37 %token <ival> APPEND OPEN SELECT LOOPEX
38 %token <ival> USING FORMAT DO SHIFT PUSH POP LVALFUN
39 %token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE SPLIT FLIST
40 %token <ival> FOR FILOP FILOP2 FILOP3 FILOP4 FILOP22 FILOP25
41 %token <ival> FUNC0 FUNC1 FUNC2 FUNC3 HSHFUN HSHFUN3
42 %token <ival> FLIST2 SUB FILETEST LOCAL DELETE
43 %token <ival> RELOP EQOP MULOP ADDOP PACKAGE AMPER LFUNC4
44 %token <formval> FORMLIST
45 %token <stabval> REG ARYLEN ARY HSH STAR
46 %token <arg> SUBST PATTERN
47 %token <arg> RSTRING TRANS
48
49 %type <ival> prog decl format remember
50 %type <stabval>
51 %type <cmdval> block lineseq line loop cond sideff nexpr else
52 %type <arg> expr sexpr cexpr csexpr term handle aryword hshword
53 %type <arg> texpr listop
54 %type <cval> label
55 %type <compval> compblock
56
57 %nonassoc <ival> LISTOP
58 %left ','
59 %right '='
60 %right '?' ':'
61 %nonassoc DOTDOT
62 %left OROR
63 %left ANDAND
64 %left '|' '^'
65 %left '&'
66 %nonassoc EQOP
67 %nonassoc RELOP
68 %nonassoc <ival> UNIOP
69 %nonassoc FILETEST
70 %left LS RS
71 %left ADDOP
72 %left MULOP
73 %left MATCH NMATCH 
74 %right '!' '~' UMINUS
75 %right POW
76 %nonassoc INC DEC
77 %left '('
78
79 %% /* RULES */
80
81 prog    :       lineseq
82                         { if (in_eval)
83                                 eval_root = block_head($1);
84                             else
85                                 main_root = block_head($1); }
86         ;
87
88 compblock:      block CONTINUE block
89                         { $$.comp_true = $1; $$.comp_alt = $3; }
90         |       block else
91                         { $$.comp_true = $1; $$.comp_alt = $2; }
92         ;
93
94 else    :       /* NULL */
95                         { $$ = Nullcmd; }
96         |       ELSE block
97                         { $$ = $2; }
98         |       ELSIF '(' expr ')' compblock
99                         { cmdline = $1;
100                             $$ = make_ccmd(C_ELSIF,$3,$5); }
101         ;
102
103 block   :       '{' remember lineseq '}'
104                         { $$ = block_head($3);
105                           if (savestack->ary_fill > $2)
106                             restorelist($2); }
107         ;
108
109 remember:       /* NULL */      /* in case they push a package name */
110                         { $$ = savestack->ary_fill; }
111         ;
112
113 lineseq :       /* NULL */
114                         { $$ = Nullcmd; }
115         |       lineseq line
116                         { $$ = append_line($1,$2); }
117         ;
118
119 line    :       decl
120                         { $$ = Nullcmd; }
121         |       label cond
122                         { $$ = add_label($1,$2); }
123         |       loop    /* loops add their own labels */
124         |       label ';'
125                         { if ($1 != Nullch) {
126                               $$ = add_label($1, make_acmd(C_EXPR, Nullstab,
127                                   Nullarg, Nullarg) );
128                             } else
129                               $$ = Nullcmd; }
130         |       label sideff ';'
131                         { $$ = add_label($1,$2); }
132         ;
133
134 sideff  :       error
135                         { $$ = Nullcmd; }
136         |       expr
137                         { $$ = make_acmd(C_EXPR, Nullstab, $1, Nullarg); }
138         |       expr IF expr
139                         { $$ = addcond(
140                                make_acmd(C_EXPR, Nullstab, Nullarg, $1), $3); }
141         |       expr UNLESS expr
142                         { $$ = addcond(invert(
143                                make_acmd(C_EXPR, Nullstab, Nullarg, $1)), $3); }
144         |       expr WHILE expr
145                         { $$ = addloop(
146                                make_acmd(C_EXPR, Nullstab, Nullarg, $1), $3); }
147         |       expr UNTIL expr
148                         { $$ = addloop(invert(
149                                make_acmd(C_EXPR, Nullstab, Nullarg, $1)), $3); }
150         ;
151
152 cond    :       IF '(' expr ')' compblock
153                         { cmdline = $1;
154                             $$ = make_icmd(C_IF,$3,$5); }
155         |       UNLESS '(' expr ')' compblock
156                         { cmdline = $1;
157                             $$ = invert(make_icmd(C_IF,$3,$5)); }
158         |       IF block compblock
159                         { cmdline = $1;
160                             $$ = make_ccmd(C_IF,cmd_to_arg($2),$3); }
161         |       UNLESS block compblock
162                         { cmdline = $1;
163                             $$ = invert(make_ccmd(C_IF,cmd_to_arg($2),$3)); }
164         ;
165
166 loop    :       label WHILE '(' texpr ')' compblock
167                         { cmdline = $2;
168                             $$ = wopt(add_label($1,
169                             make_ccmd(C_WHILE,$4,$6) )); }
170         |       label UNTIL '(' expr ')' compblock
171                         { cmdline = $2;
172                             $$ = wopt(add_label($1,
173                             invert(make_ccmd(C_WHILE,$4,$6)) )); }
174         |       label WHILE block compblock
175                         { cmdline = $2;
176                             $$ = wopt(add_label($1,
177                             make_ccmd(C_WHILE, cmd_to_arg($3),$4) )); }
178         |       label UNTIL block compblock
179                         { cmdline = $2;
180                             $$ = wopt(add_label($1,
181                             invert(make_ccmd(C_WHILE, cmd_to_arg($3),$4)) )); }
182         |       label FOR REG '(' expr ')' compblock
183                         { cmdline = $2;
184                             /*
185                              * The following gobbledygook catches EXPRs that
186                              * aren't explicit array refs and translates
187                              *          foreach VAR (EXPR) {
188                              * into
189                              *          @ary = EXPR;
190                              *          foreach VAR (@ary) {
191                              * where @ary is a hidden array made by genstab().
192                              * (Note that @ary may become a local array if
193                              * it is determined that it might be called
194                              * recursively.  See cmd_tosave().)
195                              */
196                             if ($5->arg_type != O_ARRAY) {
197                                 scrstab = aadd(genstab());
198                                 $$ = append_line(
199                                     make_acmd(C_EXPR, Nullstab,
200                                       l(make_op(O_ASSIGN,2,
201                                         listish(make_op(O_ARRAY, 1,
202                                           stab2arg(A_STAB,scrstab),
203                                           Nullarg,Nullarg, 1)),
204                                         listish(make_list($5)),
205                                         Nullarg)),
206                                       Nullarg),
207                                     wopt(over($3,add_label($1,
208                                       make_ccmd(C_WHILE,
209                                         make_op(O_ARRAY, 1,
210                                           stab2arg(A_STAB,scrstab),
211                                           Nullarg,Nullarg ),
212                                         $7)))));
213                             }
214                             else {
215                                 $$ = wopt(over($3,add_label($1,
216                                 make_ccmd(C_WHILE,$5,$7) )));
217                             }
218                         }
219         |       label FOR '(' expr ')' compblock
220                         { cmdline = $2;
221                             if ($4->arg_type != O_ARRAY) {
222                                 scrstab = aadd(genstab());
223                                 $$ = append_line(
224                                     make_acmd(C_EXPR, Nullstab,
225                                       l(make_op(O_ASSIGN,2,
226                                         listish(make_op(O_ARRAY, 1,
227                                           stab2arg(A_STAB,scrstab),
228                                           Nullarg,Nullarg, 1 )),
229                                         listish(make_list($4)),
230                                         Nullarg)),
231                                       Nullarg),
232                                     wopt(over(defstab,add_label($1,
233                                       make_ccmd(C_WHILE,
234                                         make_op(O_ARRAY, 1,
235                                           stab2arg(A_STAB,scrstab),
236                                           Nullarg,Nullarg ),
237                                         $6)))));
238                             }
239                             else {      /* lisp, anyone? */
240                                 $$ = wopt(over(defstab,add_label($1,
241                                 make_ccmd(C_WHILE,$4,$6) )));
242                             }
243                         }
244         |       label FOR '(' nexpr ';' texpr ';' nexpr ')' block
245                         /* basically fake up an initialize-while lineseq */
246                         {   yyval.compval.comp_true = $10;
247                             yyval.compval.comp_alt = $8;
248                             cmdline = $2;
249                             $$ = append_line($4,wopt(add_label($1,
250                                 make_ccmd(C_WHILE,$6,yyval.compval) ))); }
251         |       label compblock /* a block is a loop that happens once */
252                         { $$ = add_label($1,make_ccmd(C_BLOCK,Nullarg,$2)); }
253         ;
254
255 nexpr   :       /* NULL */
256                         { $$ = Nullcmd; }
257         |       sideff
258         ;
259
260 texpr   :       /* NULL means true */
261                         { (void)scanstr("1"); $$ = yylval.arg; }
262         |       expr
263         ;
264
265 label   :       /* empty */
266                         { $$ = Nullch; }
267         |       WORD ':'
268         ;
269
270 decl    :       format
271                         { $$ = 0; }
272         |       subrout
273                         { $$ = 0; }
274         |       package
275                         { $$ = 0; }
276         ;
277
278 format  :       FORMAT WORD '=' FORMLIST
279                         { stab_form(stabent($2,TRUE)) = $4; Safefree($2);}
280         |       FORMAT '=' FORMLIST
281                         { stab_form(stabent("STDOUT",TRUE)) = $3; }
282         ;
283
284 subrout :       SUB WORD block
285                         { make_sub($2,$3); }
286         ;
287
288 package :       PACKAGE WORD ';'
289                         { char tmpbuf[256];
290
291                           savehptr(&curstash);
292                           saveitem(curstname);
293                           str_set(curstname,$2);
294                           sprintf(tmpbuf,"'_%s",$2);
295                           curstash = stab_xhash(hadd(stabent(tmpbuf,TRUE)));
296                           curstash->tbl_coeffsize = 0;
297                           Safefree($2);
298                         }
299         ;
300
301 cexpr   :       ',' expr
302                         { $$ = $2; }
303         ;
304
305 expr    :       expr ',' sexpr
306                         { $$ = make_op(O_COMMA, 2, $1, $3, Nullarg); }
307         |       sexpr
308         ;
309
310 csexpr  :       ',' sexpr
311                         { $$ = $2; }
312         ;
313
314 sexpr   :       sexpr '=' sexpr
315                         {   $1 = listish($1);
316                             if ($1->arg_type == O_ASSIGN && $1->arg_len == 1)
317                                 $1->arg_type = O_ITEM;  /* a local() */
318                             if ($1->arg_type == O_LIST)
319                                 $3 = listish($3);
320                             $$ = l(make_op(O_ASSIGN, 2, $1, $3, Nullarg)); }
321         |       sexpr POW '=' sexpr
322                         { $$ = l(make_op(O_POW, 2, $1, $4, Nullarg)); }
323         |       sexpr MULOP '=' sexpr
324                         { $$ = l(make_op($2, 2, $1, $4, Nullarg)); }
325         |       sexpr ADDOP '=' sexpr
326                         { $$ = rcatmaybe(l(make_op($2, 2, $1, $4, Nullarg)));}
327         |       sexpr LS '=' sexpr
328                         { $$ = l(make_op(O_LEFT_SHIFT, 2, $1, $4, Nullarg)); }
329         |       sexpr RS '=' sexpr
330                         { $$ = l(make_op(O_RIGHT_SHIFT, 2, $1, $4, Nullarg)); }
331         |       sexpr '&' '=' sexpr
332                         { $$ = l(make_op(O_BIT_AND, 2, $1, $4, Nullarg)); }
333         |       sexpr '^' '=' sexpr
334                         { $$ = l(make_op(O_XOR, 2, $1, $4, Nullarg)); }
335         |       sexpr '|' '=' sexpr
336                         { $$ = l(make_op(O_BIT_OR, 2, $1, $4, Nullarg)); }
337
338
339         |       sexpr POW sexpr
340                         { $$ = make_op(O_POW, 2, $1, $3, Nullarg); }
341         |       sexpr MULOP sexpr
342                         { $$ = make_op($2, 2, $1, $3, Nullarg); }
343         |       sexpr ADDOP sexpr
344                         { $$ = make_op($2, 2, $1, $3, Nullarg); }
345         |       sexpr LS sexpr
346                         { $$ = make_op(O_LEFT_SHIFT, 2, $1, $3, Nullarg); }
347         |       sexpr RS sexpr
348                         { $$ = make_op(O_RIGHT_SHIFT, 2, $1, $3, Nullarg); }
349         |       sexpr RELOP sexpr
350                         { $$ = make_op($2, 2, $1, $3, Nullarg); }
351         |       sexpr EQOP sexpr
352                         { $$ = make_op($2, 2, $1, $3, Nullarg); }
353         |       sexpr '&' sexpr
354                         { $$ = make_op(O_BIT_AND, 2, $1, $3, Nullarg); }
355         |       sexpr '^' sexpr
356                         { $$ = make_op(O_XOR, 2, $1, $3, Nullarg); }
357         |       sexpr '|' sexpr
358                         { $$ = make_op(O_BIT_OR, 2, $1, $3, Nullarg); }
359         |       sexpr DOTDOT sexpr
360                         { arg4 = Nullarg;
361                           $$ = make_op(O_F_OR_R, 4, $1, $3, Nullarg); }
362         |       sexpr ANDAND sexpr
363                         { $$ = make_op(O_AND, 2, $1, $3, Nullarg); }
364         |       sexpr OROR sexpr
365                         { $$ = make_op(O_OR, 2, $1, $3, Nullarg); }
366         |       sexpr '?' sexpr ':' sexpr
367                         { $$ = make_op(O_COND_EXPR, 3, $1, $3, $5); }
368         |       sexpr MATCH sexpr
369                         { $$ = mod_match(O_MATCH, $1, $3); }
370         |       sexpr NMATCH sexpr
371                         { $$ = mod_match(O_NMATCH, $1, $3); }
372         |       term INC
373                         { $$ = addflags(1, AF_POST|AF_UP,
374                             l(make_op(O_ITEM,1,$1,Nullarg,Nullarg))); }
375         |       term DEC
376                         { $$ = addflags(1, AF_POST,
377                             l(make_op(O_ITEM,1,$1,Nullarg,Nullarg))); }
378         |       INC term
379                         { $$ = addflags(1, AF_PRE|AF_UP,
380                             l(make_op(O_ITEM,1,$2,Nullarg,Nullarg))); }
381         |       DEC term
382                         { $$ = addflags(1, AF_PRE,
383                             l(make_op(O_ITEM,1,$2,Nullarg,Nullarg))); }
384         |       term
385                         { $$ = $1; }
386         ;
387
388 term    :       '-' term %prec UMINUS
389                         { $$ = make_op(O_NEGATE, 1, $2, Nullarg, Nullarg); }
390         |       '+' term %prec UMINUS
391                         { $$ = $2; }
392         |       '!' term
393                         { $$ = make_op(O_NOT, 1, $2, Nullarg, Nullarg); }
394         |       '~' term
395                         { $$ = make_op(O_COMPLEMENT, 1, $2, Nullarg, Nullarg);}
396         |       FILETEST WORD
397                         { opargs[$1] = 0;       /* force it special */
398                             $$ = make_op($1, 1,
399                                 stab2arg(A_STAB,stabent($2,TRUE)),
400                                 Nullarg, Nullarg);
401                         }
402         |       FILETEST sexpr
403                         { opargs[$1] = 1;
404                             $$ = make_op($1, 1, $2, Nullarg, Nullarg); }
405         |       FILETEST
406                         { opargs[$1] = ($1 != O_FTTTY);
407                             $$ = make_op($1, 1,
408                                 stab2arg(A_STAB,
409                                   $1 == O_FTTTY?stabent("STDIN",TRUE):defstab),
410                                 Nullarg, Nullarg); }
411         |       LOCAL '(' expr ')'
412                         { $$ = l(make_op(O_ITEM, 1,
413                                 localize(listish(make_list($3))),
414                                 Nullarg,Nullarg)); }
415         |       '(' expr ')'
416                         { $$ = make_list(hide_ary($2)); }
417         |       '(' ')'
418                         { $$ = make_list(Nullarg); }
419         |       DO sexpr        %prec FILETEST
420                         { $$ = fixeval(
421                             make_op(O_DOFILE,2,$2,Nullarg,Nullarg) );
422                           allstabs = TRUE;}
423         |       DO block        %prec '('
424                         { $$ = cmd_to_arg($2); }
425         |       REG     %prec '('
426                         { $$ = stab2arg(A_STAB,$1); }
427         |       STAR    %prec '('
428                         { $$ = stab2arg(A_STAR,$1); }
429         |       REG '[' expr ']'        %prec '('
430                         { $$ = make_op(O_AELEM, 2,
431                                 stab2arg(A_STAB,aadd($1)), $3, Nullarg); }
432         |       HSH     %prec '('
433                         { $$ = make_op(O_HASH, 1,
434                                 stab2arg(A_STAB,$1),
435                                 Nullarg, Nullarg); }
436         |       ARY     %prec '('
437                         { $$ = make_op(O_ARRAY, 1,
438                                 stab2arg(A_STAB,$1),
439                                 Nullarg, Nullarg); }
440         |       REG '{' expr '}'        %prec '('
441                         { $$ = make_op(O_HELEM, 2,
442                                 stab2arg(A_STAB,hadd($1)),
443                                 jmaybe($3),
444                                 Nullarg); }
445         |       ARY '[' expr ']'        %prec '('
446                         { $$ = make_op(O_ASLICE, 2,
447                                 stab2arg(A_STAB,aadd($1)),
448                                 listish(make_list($3)),
449                                 Nullarg); }
450         |       ARY '{' expr '}'        %prec '('
451                         { $$ = make_op(O_HSLICE, 2,
452                                 stab2arg(A_STAB,hadd($1)),
453                                 listish(make_list($3)),
454                                 Nullarg); }
455         |       DELETE REG '{' expr '}' %prec '('
456                         { $$ = make_op(O_DELETE, 2,
457                                 stab2arg(A_STAB,hadd($2)),
458                                 jmaybe($4),
459                                 Nullarg); }
460         |       ARYLEN  %prec '('
461                         { $$ = stab2arg(A_ARYLEN,$1); }
462         |       RSTRING %prec '('
463                         { $$ = $1; }
464         |       PATTERN %prec '('
465                         { $$ = $1; }
466         |       SUBST   %prec '('
467                         { $$ = $1; }
468         |       TRANS   %prec '('
469                         { $$ = $1; }
470         |       DO WORD '(' expr ')'
471                         { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
472                                 stab2arg(A_WORD,stabent($2,TRUE)),
473                                 make_list($4),
474                                 Nullarg); Safefree($2); }
475         |       AMPER WORD '(' expr ')'
476                         { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
477                                 stab2arg(A_WORD,stabent($2,TRUE)),
478                                 make_list($4),
479                                 Nullarg); Safefree($2); }
480         |       DO WORD '(' ')'
481                         { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
482                                 stab2arg(A_WORD,stabent($2,TRUE)),
483                                 make_list(Nullarg),
484                                 Nullarg); }
485         |       AMPER WORD '(' ')'
486                         { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
487                                 stab2arg(A_WORD,stabent($2,TRUE)),
488                                 make_list(Nullarg),
489                                 Nullarg); }
490         |       AMPER WORD
491                         { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
492                                 stab2arg(A_WORD,stabent($2,TRUE)),
493                                 Nullarg,
494                                 Nullarg); }
495         |       DO REG '(' expr ')'
496                         { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
497                                 stab2arg(A_STAB,$2),
498                                 make_list($4),
499                                 Nullarg); }
500         |       AMPER REG '(' expr ')'
501                         { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
502                                 stab2arg(A_STAB,$2),
503                                 make_list($4),
504                                 Nullarg); }
505         |       DO REG '(' ')'
506                         { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
507                                 stab2arg(A_STAB,$2),
508                                 make_list(Nullarg),
509                                 Nullarg); }
510         |       AMPER REG '(' ')'
511                         { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
512                                 stab2arg(A_STAB,$2),
513                                 make_list(Nullarg),
514                                 Nullarg); }
515         |       AMPER REG
516                         { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
517                                 stab2arg(A_STAB,$2),
518                                 Nullarg,
519                                 Nullarg); }
520         |       LOOPEX
521                         { $$ = make_op($1,0,Nullarg,Nullarg,Nullarg); }
522         |       LOOPEX WORD
523                         { $$ = make_op($1,1,cval_to_arg($2),
524                             Nullarg,Nullarg); }
525         |       UNIOP
526                         { $$ = make_op($1,1,Nullarg,Nullarg,Nullarg);
527                           if ($1 == O_EVAL || $1 == O_RESET)
528                             $$ = fixeval($$); }
529         |       UNIOP sexpr
530                         { $$ = make_op($1,1,$2,Nullarg,Nullarg);
531                           if ($1 == O_EVAL || $1 == O_RESET)
532                             $$ = fixeval($$); }
533         |       SELECT
534                         { $$ = make_op(O_SELECT, 0, Nullarg, Nullarg, Nullarg);}
535         |       SELECT '(' handle ')'
536                         { $$ = make_op(O_SELECT, 1, $3, Nullarg, Nullarg); }
537         |       SELECT '(' sexpr csexpr csexpr csexpr ')'
538                         { arg4 = $6;
539                           $$ = make_op(O_SSELECT, 4, $3, $4, $5); }
540         |       OPEN WORD       %prec '('
541                         { $$ = make_op(O_OPEN, 2,
542                             stab2arg(A_WORD,stabent($2,TRUE)),
543                             stab2arg(A_STAB,stabent($2,TRUE)),
544                             Nullarg); }
545         |       OPEN '(' WORD ')'
546                         { $$ = make_op(O_OPEN, 2,
547                             stab2arg(A_WORD,stabent($3,TRUE)),
548                             stab2arg(A_STAB,stabent($3,TRUE)),
549                             Nullarg); }
550         |       OPEN '(' handle cexpr ')'
551                         { $$ = make_op(O_OPEN, 2,
552                             $3,
553                             $4, Nullarg); }
554         |       FILOP '(' handle ')'
555                         { $$ = make_op($1, 1,
556                             $3,
557                             Nullarg, Nullarg); }
558         |       FILOP WORD
559                         { $$ = make_op($1, 1,
560                             stab2arg(A_WORD,stabent($2,TRUE)),
561                             Nullarg, Nullarg);
562                           Safefree($2); }
563         |       FILOP REG
564                         { $$ = make_op($1, 1,
565                             stab2arg(A_STAB,$2),
566                             Nullarg, Nullarg); }
567         |       FILOP '(' ')'
568                         { $$ = make_op($1, 1,
569                             stab2arg(A_WORD,Nullstab),
570                             Nullarg, Nullarg); }
571         |       FILOP   %prec '('
572                         { $$ = make_op($1, 0,
573                             Nullarg, Nullarg, Nullarg); }
574         |       FILOP2 '(' handle cexpr ')'
575                         { $$ = make_op($1, 2, $3, $4, Nullarg); }
576         |       FILOP3 '(' handle csexpr cexpr ')'
577                         { $$ = make_op($1, 3, $3, $4, $5); }
578         |       FILOP22 '(' handle ',' handle ')'
579                         { $$ = make_op($1, 2, $3, $5, Nullarg); }
580         |       FILOP4 '(' handle csexpr csexpr cexpr ')'
581                         { arg4 = $6; $$ = make_op($1, 4, $3, $4, $5); }
582         |       FILOP25 '(' handle ',' handle csexpr csexpr cexpr ')'
583                         { arg4 = $7; arg5 = $8;
584                           $$ = make_op($1, 5, $3, $5, $6); }
585         |       PUSH '(' aryword cexpr ')'
586                         { $$ = make_op($1, 2,
587                             $3,
588                             make_list($4),
589                             Nullarg); }
590         |       POP aryword     %prec '('
591                         { $$ = make_op(O_POP, 1, $2, Nullarg, Nullarg); }
592         |       POP '(' aryword ')'
593                         { $$ = make_op(O_POP, 1, $3, Nullarg, Nullarg); }
594         |       SHIFT aryword   %prec '('
595                         { $$ = make_op(O_SHIFT, 1, $2, Nullarg, Nullarg); }
596         |       SHIFT '(' aryword ')'
597                         { $$ = make_op(O_SHIFT, 1, $3, Nullarg, Nullarg); }
598         |       SHIFT   %prec '('
599                         { $$ = make_op(O_SHIFT, 1,
600                             stab2arg(A_STAB,
601                               aadd(stabent(subline ? "_" : "ARGV", TRUE))),
602                             Nullarg, Nullarg); }
603         |       SPLIT   %prec '('
604                         { (void)scanpat("/\\s+/");
605                             $$ = make_split(defstab,yylval.arg,Nullarg); }
606         |       SPLIT '(' sexpr csexpr csexpr ')'
607                         { $$ = mod_match(O_MATCH, $4,
608                           make_split(defstab,$3,$5));}
609         |       SPLIT '(' sexpr csexpr ')'
610                         { $$ = mod_match(O_MATCH, $4,
611                           make_split(defstab,$3,Nullarg) ); }
612         |       SPLIT '(' sexpr ')'
613                         { $$ = mod_match(O_MATCH,
614                             stab2arg(A_STAB,defstab),
615                             make_split(defstab,$3,Nullarg) ); }
616         |       FLIST2 '(' sexpr cexpr ')'
617                         { $$ = make_op($1, 2,
618                             $3,
619                             listish(make_list($4)),
620                             Nullarg); }
621         |       FLIST '(' expr ')'
622                         { $$ = make_op($1, 1,
623                             make_list($3),
624                             Nullarg,
625                             Nullarg); }
626         |       LVALFUN sexpr   %prec '('
627                         { $$ = l(make_op($1, 1, fixl($1,$2),
628                             Nullarg, Nullarg)); }
629         |       LVALFUN
630                         { $$ = l(make_op($1, 1,
631                             stab2arg(A_STAB,defstab),
632                             Nullarg, Nullarg)); }
633         |       FUNC0
634                         { $$ = make_op($1, 0, Nullarg, Nullarg, Nullarg); }
635         |       FUNC1 '(' expr ')'
636                         { $$ = make_op($1, 1, $3, Nullarg, Nullarg);
637                           if ($1 == O_EVAL || $1 == O_RESET)
638                             $$ = fixeval($$); }
639         |       FUNC2 '(' sexpr cexpr ')'
640                         { $$ = make_op($1, 2, $3, $4, Nullarg);
641                             if ($1 == O_INDEX && $$[2].arg_type == A_SINGLE)
642                                 fbmcompile($$[2].arg_ptr.arg_str,0); }
643         |       FUNC3 '(' sexpr csexpr cexpr ')'
644                         { $$ = make_op($1, 3, $3, $4, $5); }
645         |       LFUNC4 '(' sexpr csexpr csexpr cexpr ')'
646                         { arg4 = $6; $$ = make_op($1, 4, l($3), $4, $5); }
647         |       HSHFUN '(' hshword ')'
648                         { $$ = make_op($1, 1,
649                                 $3,
650                                 Nullarg,
651                                 Nullarg); }
652         |       HSHFUN hshword
653                         { $$ = make_op($1, 1,
654                                 $2,
655                                 Nullarg,
656                                 Nullarg); }
657         |       HSHFUN3 '(' hshword csexpr cexpr ')'
658                         { $$ = make_op($1, 3, $3, $4, $5); }
659         |       listop
660         ;
661
662 listop  :       LISTOP
663                         { $$ = make_op($1,2,
664                                 stab2arg(A_WORD,Nullstab),
665                                 stab2arg(A_STAB,defstab),
666                                 Nullarg); }
667         |       LISTOP expr
668                         { $$ = make_op($1,2,
669                                 stab2arg(A_WORD,Nullstab),
670                                 maybelistish($1,make_list($2)),
671                                 Nullarg); }
672         |       LISTOP WORD
673                         { $$ = make_op($1,2,
674                                 stab2arg(A_WORD,stabent($2,TRUE)),
675                                 stab2arg(A_STAB,defstab),
676                                 Nullarg); }
677         |       LISTOP WORD expr
678                         { $$ = make_op($1,2,
679                                 stab2arg(A_WORD,stabent($2,TRUE)),
680                                 maybelistish($1,make_list($3)),
681                                 Nullarg); Safefree($2); }
682         |       LISTOP REG expr
683                         { $$ = make_op($1,2,
684                                 stab2arg(A_STAB,$2),
685                                 maybelistish($1,make_list($3)),
686                                 Nullarg); }
687         ;
688
689 handle  :       WORD
690                         { $$ = stab2arg(A_WORD,stabent($1,TRUE)); Safefree($1);}
691         |       sexpr
692         ;
693
694 aryword :       WORD
695                         { $$ = stab2arg(A_WORD,aadd(stabent($1,TRUE)));
696                             Safefree($1); }
697         |       ARY
698                         { $$ = stab2arg(A_STAB,$1); }
699         ;
700
701 hshword :       WORD
702                         { $$ = stab2arg(A_WORD,hadd(stabent($1,TRUE)));
703                             Safefree($1); }
704         |       HSH
705                         { $$ = stab2arg(A_STAB,$1); }
706         ;
707
708 %% /* PROGRAM */