1 /* $Header: perl.y,v 3.0.1.1 89/10/26 23:20:41 lwall Locked $
3 * Copyright (c) 1989, Larry Wall
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.
9 * Revision 3.0.1.1 89/10/26 23:20:41 lwall
10 * patch1: grandfathered "format stdout"
11 * patch1: operator(); is now normally equivalent to operator;
13 * Revision 3.0 89/10/18 15:22:04 lwall
23 ARG *arg4; /* rarely used arguments to make_op() */
35 struct compcmd compval;
41 %token <ival> APPEND OPEN SELECT LOOPEX
42 %token <ival> USING FORMAT DO SHIFT PUSH POP LVALFUN
43 %token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE SPLIT FLIST
44 %token <ival> FOR FILOP FILOP2 FILOP3 FILOP4 FILOP22 FILOP25
45 %token <ival> FUNC0 FUNC1 FUNC2 FUNC3 HSHFUN HSHFUN3
46 %token <ival> FLIST2 SUB FILETEST LOCAL DELETE
47 %token <ival> RELOP EQOP MULOP ADDOP PACKAGE AMPER LFUNC4
48 %token <formval> FORMLIST
49 %token <stabval> REG ARYLEN ARY HSH STAR
50 %token <arg> SUBST PATTERN
51 %token <arg> RSTRING TRANS
53 %type <ival> prog decl format remember
55 %type <cmdval> block lineseq line loop cond sideff nexpr else
56 %type <arg> expr sexpr cexpr csexpr term handle aryword hshword
57 %type <arg> texpr listop
59 %type <compval> compblock
61 %nonassoc <ival> LISTOP
72 %nonassoc <ival> UNIOP
87 eval_root = block_head($1);
89 main_root = block_head($1); }
92 compblock: block CONTINUE block
93 { $$.comp_true = $1; $$.comp_alt = $3; }
95 { $$.comp_true = $1; $$.comp_alt = $2; }
102 | ELSIF '(' expr ')' compblock
104 $$ = make_ccmd(C_ELSIF,$3,$5); }
107 block : '{' remember lineseq '}'
108 { $$ = block_head($3);
109 if (savestack->ary_fill > $2)
113 remember: /* NULL */ /* in case they push a package name */
114 { $$ = savestack->ary_fill; }
120 { $$ = append_line($1,$2); }
126 { $$ = add_label($1,$2); }
127 | loop /* loops add their own labels */
129 { if ($1 != Nullch) {
130 $$ = add_label($1, make_acmd(C_EXPR, Nullstab,
135 { $$ = add_label($1,$2); }
141 { $$ = make_acmd(C_EXPR, Nullstab, $1, Nullarg); }
144 make_acmd(C_EXPR, Nullstab, Nullarg, $1), $3); }
146 { $$ = addcond(invert(
147 make_acmd(C_EXPR, Nullstab, Nullarg, $1)), $3); }
150 make_acmd(C_EXPR, Nullstab, Nullarg, $1), $3); }
152 { $$ = addloop(invert(
153 make_acmd(C_EXPR, Nullstab, Nullarg, $1)), $3); }
156 cond : IF '(' expr ')' compblock
158 $$ = make_icmd(C_IF,$3,$5); }
159 | UNLESS '(' expr ')' compblock
161 $$ = invert(make_icmd(C_IF,$3,$5)); }
164 $$ = make_ccmd(C_IF,cmd_to_arg($2),$3); }
165 | UNLESS block compblock
167 $$ = invert(make_ccmd(C_IF,cmd_to_arg($2),$3)); }
170 loop : label WHILE '(' texpr ')' compblock
172 $$ = wopt(add_label($1,
173 make_ccmd(C_WHILE,$4,$6) )); }
174 | label UNTIL '(' expr ')' compblock
176 $$ = wopt(add_label($1,
177 invert(make_ccmd(C_WHILE,$4,$6)) )); }
178 | label WHILE block compblock
180 $$ = wopt(add_label($1,
181 make_ccmd(C_WHILE, cmd_to_arg($3),$4) )); }
182 | label UNTIL block compblock
184 $$ = wopt(add_label($1,
185 invert(make_ccmd(C_WHILE, cmd_to_arg($3),$4)) )); }
186 | label FOR REG '(' expr ')' compblock
189 * The following gobbledygook catches EXPRs that
190 * aren't explicit array refs and translates
191 * foreach VAR (EXPR) {
194 * foreach VAR (@ary) {
195 * where @ary is a hidden array made by genstab().
196 * (Note that @ary may become a local array if
197 * it is determined that it might be called
198 * recursively. See cmd_tosave().)
200 if ($5->arg_type != O_ARRAY) {
201 scrstab = aadd(genstab());
203 make_acmd(C_EXPR, Nullstab,
204 l(make_op(O_ASSIGN,2,
205 listish(make_op(O_ARRAY, 1,
206 stab2arg(A_STAB,scrstab),
207 Nullarg,Nullarg, 1)),
208 listish(make_list($5)),
211 wopt(over($3,add_label($1,
214 stab2arg(A_STAB,scrstab),
219 $$ = wopt(over($3,add_label($1,
220 make_ccmd(C_WHILE,$5,$7) )));
223 | label FOR '(' expr ')' compblock
225 if ($4->arg_type != O_ARRAY) {
226 scrstab = aadd(genstab());
228 make_acmd(C_EXPR, Nullstab,
229 l(make_op(O_ASSIGN,2,
230 listish(make_op(O_ARRAY, 1,
231 stab2arg(A_STAB,scrstab),
232 Nullarg,Nullarg, 1 )),
233 listish(make_list($4)),
236 wopt(over(defstab,add_label($1,
239 stab2arg(A_STAB,scrstab),
243 else { /* lisp, anyone? */
244 $$ = wopt(over(defstab,add_label($1,
245 make_ccmd(C_WHILE,$4,$6) )));
248 | label FOR '(' nexpr ';' texpr ';' nexpr ')' block
249 /* basically fake up an initialize-while lineseq */
250 { yyval.compval.comp_true = $10;
251 yyval.compval.comp_alt = $8;
253 $$ = append_line($4,wopt(add_label($1,
254 make_ccmd(C_WHILE,$6,yyval.compval) ))); }
255 | label compblock /* a block is a loop that happens once */
256 { $$ = add_label($1,make_ccmd(C_BLOCK,Nullarg,$2)); }
264 texpr : /* NULL means true */
265 { (void)scanstr("1"); $$ = yylval.arg; }
282 format : FORMAT WORD '=' FORMLIST
283 { if (strEQ($2,"stdout"))
284 stab_form(stabent("STDOUT",TRUE)) = $4;
285 else if (strEQ($2,"stderr"))
286 stab_form(stabent("STDERR",TRUE)) = $4;
288 stab_form(stabent($2,TRUE)) = $4;
290 | FORMAT '=' FORMLIST
291 { stab_form(stabent("STDOUT",TRUE)) = $3; }
294 subrout : SUB WORD block
298 package : PACKAGE WORD ';'
303 str_set(curstname,$2);
304 sprintf(tmpbuf,"'_%s",$2);
305 curstash = stab_xhash(hadd(stabent(tmpbuf,TRUE)));
306 curstash->tbl_coeffsize = 0;
315 expr : expr ',' sexpr
316 { $$ = make_op(O_COMMA, 2, $1, $3, Nullarg); }
324 sexpr : sexpr '=' sexpr
326 if ($1->arg_type == O_ASSIGN && $1->arg_len == 1)
327 $1->arg_type = O_ITEM; /* a local() */
328 if ($1->arg_type == O_LIST)
330 $$ = l(make_op(O_ASSIGN, 2, $1, $3, Nullarg)); }
331 | sexpr POW '=' sexpr
332 { $$ = l(make_op(O_POW, 2, $1, $4, Nullarg)); }
333 | sexpr MULOP '=' sexpr
334 { $$ = l(make_op($2, 2, $1, $4, Nullarg)); }
335 | sexpr ADDOP '=' sexpr
336 { $$ = rcatmaybe(l(make_op($2, 2, $1, $4, Nullarg)));}
338 { $$ = l(make_op(O_LEFT_SHIFT, 2, $1, $4, Nullarg)); }
340 { $$ = l(make_op(O_RIGHT_SHIFT, 2, $1, $4, Nullarg)); }
341 | sexpr '&' '=' sexpr
342 { $$ = l(make_op(O_BIT_AND, 2, $1, $4, Nullarg)); }
343 | sexpr '^' '=' sexpr
344 { $$ = l(make_op(O_XOR, 2, $1, $4, Nullarg)); }
345 | sexpr '|' '=' sexpr
346 { $$ = l(make_op(O_BIT_OR, 2, $1, $4, Nullarg)); }
350 { $$ = make_op(O_POW, 2, $1, $3, Nullarg); }
352 { $$ = make_op($2, 2, $1, $3, Nullarg); }
354 { $$ = make_op($2, 2, $1, $3, Nullarg); }
356 { $$ = make_op(O_LEFT_SHIFT, 2, $1, $3, Nullarg); }
358 { $$ = make_op(O_RIGHT_SHIFT, 2, $1, $3, Nullarg); }
360 { $$ = make_op($2, 2, $1, $3, Nullarg); }
362 { $$ = make_op($2, 2, $1, $3, Nullarg); }
364 { $$ = make_op(O_BIT_AND, 2, $1, $3, Nullarg); }
366 { $$ = make_op(O_XOR, 2, $1, $3, Nullarg); }
368 { $$ = make_op(O_BIT_OR, 2, $1, $3, Nullarg); }
371 $$ = make_op(O_F_OR_R, 4, $1, $3, Nullarg); }
373 { $$ = make_op(O_AND, 2, $1, $3, Nullarg); }
375 { $$ = make_op(O_OR, 2, $1, $3, Nullarg); }
376 | sexpr '?' sexpr ':' sexpr
377 { $$ = make_op(O_COND_EXPR, 3, $1, $3, $5); }
379 { $$ = mod_match(O_MATCH, $1, $3); }
381 { $$ = mod_match(O_NMATCH, $1, $3); }
383 { $$ = addflags(1, AF_POST|AF_UP,
384 l(make_op(O_ITEM,1,$1,Nullarg,Nullarg))); }
386 { $$ = addflags(1, AF_POST,
387 l(make_op(O_ITEM,1,$1,Nullarg,Nullarg))); }
389 { $$ = addflags(1, AF_PRE|AF_UP,
390 l(make_op(O_ITEM,1,$2,Nullarg,Nullarg))); }
392 { $$ = addflags(1, AF_PRE,
393 l(make_op(O_ITEM,1,$2,Nullarg,Nullarg))); }
398 term : '-' term %prec UMINUS
399 { $$ = make_op(O_NEGATE, 1, $2, Nullarg, Nullarg); }
400 | '+' term %prec UMINUS
403 { $$ = make_op(O_NOT, 1, $2, Nullarg, Nullarg); }
405 { $$ = make_op(O_COMPLEMENT, 1, $2, Nullarg, Nullarg);}
407 { opargs[$1] = 0; /* force it special */
409 stab2arg(A_STAB,stabent($2,TRUE)),
414 $$ = make_op($1, 1, $2, Nullarg, Nullarg); }
416 { opargs[$1] = ($1 != O_FTTTY);
419 $1 == O_FTTTY?stabent("STDIN",TRUE):defstab),
422 { $$ = l(make_op(O_ITEM, 1,
423 localize(listish(make_list($3))),
426 { $$ = make_list(hide_ary($2)); }
428 { $$ = make_list(Nullarg); }
429 | DO sexpr %prec FILETEST
431 make_op(O_DOFILE,2,$2,Nullarg,Nullarg) );
434 { $$ = cmd_to_arg($2); }
436 { $$ = stab2arg(A_STAB,$1); }
438 { $$ = stab2arg(A_STAR,$1); }
439 | REG '[' expr ']' %prec '('
440 { $$ = make_op(O_AELEM, 2,
441 stab2arg(A_STAB,aadd($1)), $3, Nullarg); }
443 { $$ = make_op(O_HASH, 1,
447 { $$ = make_op(O_ARRAY, 1,
450 | REG '{' expr '}' %prec '('
451 { $$ = make_op(O_HELEM, 2,
452 stab2arg(A_STAB,hadd($1)),
455 | ARY '[' expr ']' %prec '('
456 { $$ = make_op(O_ASLICE, 2,
457 stab2arg(A_STAB,aadd($1)),
458 listish(make_list($3)),
460 | ARY '{' expr '}' %prec '('
461 { $$ = make_op(O_HSLICE, 2,
462 stab2arg(A_STAB,hadd($1)),
463 listish(make_list($3)),
465 | DELETE REG '{' expr '}' %prec '('
466 { $$ = make_op(O_DELETE, 2,
467 stab2arg(A_STAB,hadd($2)),
471 { $$ = stab2arg(A_ARYLEN,$1); }
480 | DO WORD '(' expr ')'
481 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
482 stab2arg(A_WORD,stabent($2,TRUE)),
484 Nullarg); Safefree($2); }
485 | AMPER WORD '(' expr ')'
486 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
487 stab2arg(A_WORD,stabent($2,TRUE)),
489 Nullarg); Safefree($2); }
491 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
492 stab2arg(A_WORD,stabent($2,TRUE)),
496 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
497 stab2arg(A_WORD,stabent($2,TRUE)),
501 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
502 stab2arg(A_WORD,stabent($2,TRUE)),
505 | DO REG '(' expr ')'
506 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
510 | AMPER REG '(' expr ')'
511 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
516 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
521 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
526 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
531 { $$ = make_op($1,0,Nullarg,Nullarg,Nullarg); }
533 { $$ = make_op($1,1,cval_to_arg($2),
536 { $$ = make_op($1,1,Nullarg,Nullarg,Nullarg);
537 if ($1 == O_EVAL || $1 == O_RESET)
540 { $$ = make_op($1,1,$2,Nullarg,Nullarg);
541 if ($1 == O_EVAL || $1 == O_RESET)
544 { $$ = make_op(O_SELECT, 0, Nullarg, Nullarg, Nullarg);}
545 | SELECT '(' handle ')'
546 { $$ = make_op(O_SELECT, 1, $3, Nullarg, Nullarg); }
547 | SELECT '(' sexpr csexpr csexpr csexpr ')'
549 $$ = make_op(O_SSELECT, 4, $3, $4, $5); }
550 | OPEN WORD %prec '('
551 { $$ = make_op(O_OPEN, 2,
552 stab2arg(A_WORD,stabent($2,TRUE)),
553 stab2arg(A_STAB,stabent($2,TRUE)),
556 { $$ = make_op(O_OPEN, 2,
557 stab2arg(A_WORD,stabent($3,TRUE)),
558 stab2arg(A_STAB,stabent($3,TRUE)),
560 | OPEN '(' handle cexpr ')'
561 { $$ = make_op(O_OPEN, 2,
564 | FILOP '(' handle ')'
565 { $$ = make_op($1, 1,
569 { $$ = make_op($1, 1,
570 stab2arg(A_WORD,stabent($2,TRUE)),
574 { $$ = make_op($1, 1,
578 { $$ = make_op($1, 1,
579 stab2arg(A_WORD,Nullstab),
582 { $$ = make_op($1, 0,
583 Nullarg, Nullarg, Nullarg); }
584 | FILOP2 '(' handle cexpr ')'
585 { $$ = make_op($1, 2, $3, $4, Nullarg); }
586 | FILOP3 '(' handle csexpr cexpr ')'
587 { $$ = make_op($1, 3, $3, $4, $5); }
588 | FILOP22 '(' handle ',' handle ')'
589 { $$ = make_op($1, 2, $3, $5, Nullarg); }
590 | FILOP4 '(' handle csexpr csexpr cexpr ')'
591 { arg4 = $6; $$ = make_op($1, 4, $3, $4, $5); }
592 | FILOP25 '(' handle ',' handle csexpr csexpr cexpr ')'
593 { arg4 = $7; arg5 = $8;
594 $$ = make_op($1, 5, $3, $5, $6); }
595 | PUSH '(' aryword cexpr ')'
596 { $$ = make_op($1, 2,
600 | POP aryword %prec '('
601 { $$ = make_op(O_POP, 1, $2, Nullarg, Nullarg); }
602 | POP '(' aryword ')'
603 { $$ = make_op(O_POP, 1, $3, Nullarg, Nullarg); }
604 | SHIFT aryword %prec '('
605 { $$ = make_op(O_SHIFT, 1, $2, Nullarg, Nullarg); }
606 | SHIFT '(' aryword ')'
607 { $$ = make_op(O_SHIFT, 1, $3, Nullarg, Nullarg); }
609 { $$ = make_op(O_SHIFT, 1,
611 aadd(stabent(subline ? "_" : "ARGV", TRUE))),
614 { (void)scanpat("/\\s+/");
615 $$ = make_split(defstab,yylval.arg,Nullarg); }
616 | SPLIT '(' sexpr csexpr csexpr ')'
617 { $$ = mod_match(O_MATCH, $4,
618 make_split(defstab,$3,$5));}
619 | SPLIT '(' sexpr csexpr ')'
620 { $$ = mod_match(O_MATCH, $4,
621 make_split(defstab,$3,Nullarg) ); }
622 | SPLIT '(' sexpr ')'
623 { $$ = mod_match(O_MATCH,
624 stab2arg(A_STAB,defstab),
625 make_split(defstab,$3,Nullarg) ); }
626 | FLIST2 '(' sexpr cexpr ')'
627 { $$ = make_op($1, 2,
629 listish(make_list($4)),
632 { $$ = make_op($1, 1,
636 | LVALFUN sexpr %prec '('
637 { $$ = l(make_op($1, 1, fixl($1,$2),
638 Nullarg, Nullarg)); }
640 { $$ = l(make_op($1, 1,
641 stab2arg(A_STAB,defstab),
642 Nullarg, Nullarg)); }
644 { $$ = make_op($1, 0, Nullarg, Nullarg, Nullarg); }
646 { $$ = make_op($1, 1, Nullarg, Nullarg, Nullarg);
647 if ($1 == O_EVAL || $1 == O_RESET)
650 { $$ = make_op($1, 1, $3, Nullarg, Nullarg);
651 if ($1 == O_EVAL || $1 == O_RESET)
653 | FUNC2 '(' sexpr cexpr ')'
654 { $$ = make_op($1, 2, $3, $4, Nullarg);
655 if ($1 == O_INDEX && $$[2].arg_type == A_SINGLE)
656 fbmcompile($$[2].arg_ptr.arg_str,0); }
657 | FUNC3 '(' sexpr csexpr cexpr ')'
658 { $$ = make_op($1, 3, $3, $4, $5); }
659 | LFUNC4 '(' sexpr csexpr csexpr cexpr ')'
660 { arg4 = $6; $$ = make_op($1, 4, l($3), $4, $5); }
661 | HSHFUN '(' hshword ')'
662 { $$ = make_op($1, 1,
667 { $$ = make_op($1, 1,
671 | HSHFUN3 '(' hshword csexpr cexpr ')'
672 { $$ = make_op($1, 3, $3, $4, $5); }
678 stab2arg(A_WORD,Nullstab),
679 stab2arg(A_STAB,defstab),
683 stab2arg(A_WORD,Nullstab),
684 maybelistish($1,make_list($2)),
688 stab2arg(A_WORD,stabent($2,TRUE)),
689 stab2arg(A_STAB,defstab),
693 stab2arg(A_WORD,stabent($2,TRUE)),
694 maybelistish($1,make_list($3)),
695 Nullarg); Safefree($2); }
699 maybelistish($1,make_list($3)),
704 { $$ = stab2arg(A_WORD,stabent($1,TRUE)); Safefree($1);}
709 { $$ = stab2arg(A_WORD,aadd(stabent($1,TRUE)));
712 { $$ = stab2arg(A_STAB,$1); }
716 { $$ = stab2arg(A_WORD,hadd(stabent($1,TRUE)));
719 { $$ = stab2arg(A_STAB,$1); }