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