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