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