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