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