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