1 /* $Header: perl.y,v 1.0.1.1 88/01/28 10:25:31 root Exp $
4 * Revision 1.0.1.1 88/01/28 10:25:31 root
5 * patch8: added eval operator.
7 * Revision 1.0 87/12/18 15:48:59 root
22 "append","open","write","select","close","loopctl",
23 "using","format","do","shift","push","pop","chop",
24 "while","until","if","unless","else","elsif","continue","split","sprintf",
25 "for", "eof", "tell", "seek", "stat",
26 "function(no args)","function(1 arg)","function(2 args)","function(3 args)","array function",
29 "register","array_length", "array",
32 "print", "unary operation",
36 "==","!=", "EQ", "NE",
37 "<=",">=", "LT", "GT", "LE", "GE",
54 struct compcmd compval;
60 %token <ival> APPEND OPEN WRITE SELECT CLOSE LOOPEX
61 %token <ival> USING FORMAT DO SHIFT PUSH POP CHOP
62 %token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE SPLIT SPRINTF
63 %token <ival> FOR FEOF TELL SEEK STAT
64 %token <ival> FUNC0 FUNC1 FUNC2 FUNC3 STABFUN
65 %token <ival> JOIN SUB
66 %token <formval> FORMLIST
67 %token <stabval> REG ARYLEN ARY
68 %token <arg> SUBST PATTERN
69 %token <arg> RSTRING TRANS
71 %type <ival> prog decl format
73 %type <cmdval> block lineseq line loop cond sideff nexpr else
74 %type <arg> expr sexpr term
75 %type <arg> condmod loopmod cexpr
76 %type <arg> texpr print
78 %type <compval> compblock
80 %nonassoc <ival> PRINT
82 %nonassoc <ival> UNIOP
90 %nonassoc EQ NE SEQ SNE
91 %nonassoc '<' '>' LE GE SLT SGT SLE SGE
104 eval_root = block_head($1);
106 main_root = block_head($1); }
109 compblock: block CONTINUE block
110 { $$.comp_true = $1; $$.comp_alt = $3; }
112 { $$.comp_true = $1; $$.comp_alt = $2; }
119 | ELSIF '(' expr ')' compblock
120 { $$ = make_ccmd(C_IF,$3,$5); }
123 block : '{' lineseq '}'
124 { $$ = block_head($2); }
130 { $$ = append_line($1,$2); }
136 { $$ = add_label($1,$2); }
137 | loop /* loops add their own labels */
139 { if ($1 != Nullch) {
140 $$ = add_label(make_acmd(C_EXPR, Nullstab,
145 { $$ = add_label($1,$2); }
149 { $$ = make_acmd(C_EXPR, Nullstab, $1, Nullarg); }
152 make_acmd(C_EXPR, Nullstab, Nullarg, $1), $2); }
155 make_acmd(C_EXPR, Nullstab, Nullarg, $1), $2); }
158 cond : IF '(' expr ')' compblock
159 { $$ = make_ccmd(C_IF,$3,$5); }
160 | UNLESS '(' expr ')' compblock
161 { $$ = invert(make_ccmd(C_IF,$3,$5)); }
163 { $$ = make_ccmd(C_IF,cmd_to_arg($2),$3); }
164 | UNLESS block compblock
165 { $$ = invert(make_ccmd(C_IF,cmd_to_arg($2),$3)); }
168 loop : label WHILE '(' texpr ')' compblock
169 { $$ = wopt(add_label($1,
170 make_ccmd(C_WHILE,$4,$6) )); }
171 | label UNTIL '(' expr ')' compblock
172 { $$ = wopt(add_label($1,
173 invert(make_ccmd(C_WHILE,$4,$6)) )); }
174 | label WHILE block compblock
175 { $$ = wopt(add_label($1,
176 make_ccmd(C_WHILE, cmd_to_arg($3),$4) )); }
177 | label UNTIL block compblock
178 { $$ = wopt(add_label($1,
179 invert(make_ccmd(C_WHILE, cmd_to_arg($3),$4)) )); }
180 | label FOR '(' nexpr ';' texpr ';' nexpr ')' block
181 /* basically fake up an initialize-while lineseq */
182 { yyval.compval.comp_true = $10;
183 yyval.compval.comp_alt = $8;
184 $$ = append_line($4,wopt(add_label($1,
185 make_ccmd(C_WHILE,$6,yyval.compval) ))); }
186 | label compblock /* a block is a loop that happens once */
187 { $$ = add_label($1,make_ccmd(C_BLOCK,Nullarg,$2)); }
195 texpr : /* NULL means true */
196 { scanstr("1"); $$ = yylval.arg; }
208 { $$ = make_op(O_NOT,1,$2,Nullarg,Nullarg,0); }
214 { $$ = make_op(O_NOT,1,$2,Nullarg,Nullarg,0); }
223 format : FORMAT WORD '=' FORMLIST '.'
224 { stabent($2,TRUE)->stab_form = $4; safefree($2); }
225 | FORMAT '=' FORMLIST '.'
226 { stabent("stdout",TRUE)->stab_form = $3; }
229 subrout : SUB WORD block
230 { stabent($2,TRUE)->stab_sub = $3; }
237 cexpr : sexpr ',' cexpr
238 { $$ = make_op(O_COMMA, 2, $1, $3, Nullarg,0); }
242 sexpr : sexpr '=' sexpr
244 if ($1->arg_type == O_LIST)
246 $$ = l(make_op(O_ASSIGN, 2, $1, $3, Nullarg,1)); }
247 | sexpr '*' '=' sexpr
248 { $$ = l(make_op(O_MULTIPLY, 2, $1, $4, Nullarg,0)); }
249 | sexpr '/' '=' sexpr
250 { $$ = l(make_op(O_DIVIDE, 2, $1, $4, Nullarg,0)); }
251 | sexpr '%' '=' sexpr
252 { $$ = l(make_op(O_MODULO, 2, $1, $4, Nullarg,0)); }
253 | sexpr 'x' '=' sexpr
254 { $$ = l(make_op(O_REPEAT, 2, $1, $4, Nullarg,0)); }
255 | sexpr '+' '=' sexpr
256 { $$ = l(make_op(O_ADD, 2, $1, $4, Nullarg,0)); }
257 | sexpr '-' '=' sexpr
258 { $$ = l(make_op(O_SUBTRACT, 2, $1, $4, Nullarg,0)); }
260 { $$ = l(make_op(O_LEFT_SHIFT, 2, $1, $4, Nullarg,0)); }
262 { $$ = l(make_op(O_RIGHT_SHIFT, 2, $1, $4, Nullarg,0)); }
263 | sexpr '&' '=' sexpr
264 { $$ = l(make_op(O_BIT_AND, 2, $1, $4, Nullarg,0)); }
265 | sexpr '^' '=' sexpr
266 { $$ = l(make_op(O_XOR, 2, $1, $4, Nullarg,0)); }
267 | sexpr '|' '=' sexpr
268 { $$ = l(make_op(O_BIT_OR, 2, $1, $4, Nullarg,0)); }
269 | sexpr '.' '=' sexpr
270 { $$ = l(make_op(O_CONCAT, 2, $1, $4, Nullarg,0)); }
274 { $$ = make_op(O_MULTIPLY, 2, $1, $3, Nullarg,0); }
276 { $$ = make_op(O_DIVIDE, 2, $1, $3, Nullarg,0); }
278 { $$ = make_op(O_MODULO, 2, $1, $3, Nullarg,0); }
280 { $$ = make_op(O_REPEAT, 2, $1, $3, Nullarg,0); }
282 { $$ = make_op(O_ADD, 2, $1, $3, Nullarg,0); }
284 { $$ = make_op(O_SUBTRACT, 2, $1, $3, Nullarg,0); }
286 { $$ = make_op(O_LEFT_SHIFT, 2, $1, $3, Nullarg,0); }
288 { $$ = make_op(O_RIGHT_SHIFT, 2, $1, $3, Nullarg,0); }
290 { $$ = make_op(O_LT, 2, $1, $3, Nullarg,0); }
292 { $$ = make_op(O_GT, 2, $1, $3, Nullarg,0); }
294 { $$ = make_op(O_LE, 2, $1, $3, Nullarg,0); }
296 { $$ = make_op(O_GE, 2, $1, $3, Nullarg,0); }
298 { $$ = make_op(O_EQ, 2, $1, $3, Nullarg,0); }
300 { $$ = make_op(O_NE, 2, $1, $3, Nullarg,0); }
302 { $$ = make_op(O_SLT, 2, $1, $3, Nullarg,0); }
304 { $$ = make_op(O_SGT, 2, $1, $3, Nullarg,0); }
306 { $$ = make_op(O_SLE, 2, $1, $3, Nullarg,0); }
308 { $$ = make_op(O_SGE, 2, $1, $3, Nullarg,0); }
310 { $$ = make_op(O_SEQ, 2, $1, $3, Nullarg,0); }
312 { $$ = make_op(O_SNE, 2, $1, $3, Nullarg,0); }
314 { $$ = make_op(O_BIT_AND, 2, $1, $3, Nullarg,0); }
316 { $$ = make_op(O_XOR, 2, $1, $3, Nullarg,0); }
318 { $$ = make_op(O_BIT_OR, 2, $1, $3, Nullarg,0); }
320 { $$ = make_op(O_FLIP, 4,
325 { $$ = make_op(O_AND, 2, $1, $3, Nullarg,0); }
327 { $$ = make_op(O_OR, 2, $1, $3, Nullarg,0); }
328 | sexpr '?' sexpr ':' sexpr
329 { $$ = make_op(O_COND_EXPR, 3, $1, $3, $5,0); }
331 { $$ = make_op(O_CONCAT, 2, $1, $3, Nullarg,0); }
333 { $$ = mod_match(O_MATCH, $1, $3); }
335 { $$ = mod_match(O_NMATCH, $1, $3); }
337 { $$ = addflags(1, AF_POST|AF_UP,
338 l(make_op(O_ITEM,1,$1,Nullarg,Nullarg,0))); }
340 { $$ = addflags(1, AF_POST,
341 l(make_op(O_ITEM,1,$1,Nullarg,Nullarg,0))); }
343 { $$ = addflags(1, AF_PRE|AF_UP,
344 l(make_op(O_ITEM,1,$2,Nullarg,Nullarg,0))); }
346 { $$ = addflags(1, AF_PRE,
347 l(make_op(O_ITEM,1,$2,Nullarg,Nullarg,0))); }
352 term : '-' term %prec UMINUS
353 { $$ = make_op(O_NEGATE, 1, $2, Nullarg, Nullarg,0); }
355 { $$ = make_op(O_NOT, 1, $2, Nullarg, Nullarg,0); }
357 { $$ = make_op(O_COMPLEMENT, 1, $2, Nullarg, Nullarg,0);}
359 { $$ = make_list(hide_ary($2)); }
361 { $$ = make_list(Nullarg); }
363 { $$ = cmd_to_arg($2); }
365 { $$ = stab_to_arg(A_STAB,$1); }
366 | REG '[' expr ']' %prec '('
367 { $$ = make_op(O_ARRAY, 2,
368 $3, stab_to_arg(A_STAB,aadd($1)), Nullarg,0); }
370 { $$ = make_op(O_ARRAY, 1,
371 stab_to_arg(A_STAB,$1),
372 Nullarg, Nullarg, 1); }
373 | REG '{' expr '}' %prec '('
374 { $$ = make_op(O_HASH, 2,
375 $3, stab_to_arg(A_STAB,hadd($1)), Nullarg,0); }
377 { $$ = stab_to_arg(A_ARYLEN,$1); }
386 | DO WORD '(' expr ')'
387 { $$ = make_op(O_SUBR, 2,
389 stab_to_arg(A_STAB,stabent($2,TRUE)),
392 { $$ = make_op(O_SUBR, 2,
394 stab_to_arg(A_STAB,stabent($2,TRUE)),
397 { $$ = make_op($1,0,Nullarg,Nullarg,Nullarg,0); }
399 { $$ = make_op($1,1,cval_to_arg($2),
400 Nullarg,Nullarg,0); }
402 { $$ = make_op($1,1,Nullarg,Nullarg,Nullarg,0); }
404 { $$ = make_op($1,1,$2,Nullarg,Nullarg,0); }
406 { $$ = make_op(O_WRITE, 0,
407 Nullarg, Nullarg, Nullarg,0); }
409 { $$ = make_op(O_WRITE, 0,
410 Nullarg, Nullarg, Nullarg,0); }
412 { $$ = l(make_op(O_WRITE, 1,
413 stab_to_arg(A_STAB,stabent($3,TRUE)),
414 Nullarg, Nullarg,0)); safefree($3); }
416 { $$ = make_op(O_WRITE, 1, $3, Nullarg, Nullarg,0); }
417 | SELECT '(' WORD ')'
418 { $$ = l(make_op(O_SELECT, 1,
419 stab_to_arg(A_STAB,stabent($3,TRUE)),
420 Nullarg, Nullarg,0)); safefree($3); }
421 | SELECT '(' expr ')'
422 { $$ = make_op(O_SELECT, 1, $3, Nullarg, Nullarg,0); }
423 | OPEN WORD %prec '('
424 { $$ = make_op(O_OPEN, 2,
425 stab_to_arg(A_STAB,stabent($2,TRUE)),
426 stab_to_arg(A_STAB,stabent($2,TRUE)),
429 { $$ = make_op(O_OPEN, 2,
430 stab_to_arg(A_STAB,stabent($3,TRUE)),
431 stab_to_arg(A_STAB,stabent($3,TRUE)),
433 | OPEN '(' WORD ',' expr ')'
434 { $$ = make_op(O_OPEN, 2,
435 stab_to_arg(A_STAB,stabent($3,TRUE)),
438 { $$ = make_op(O_CLOSE, 1,
439 stab_to_arg(A_STAB,stabent($3,TRUE)),
440 Nullarg, Nullarg,0); }
441 | CLOSE WORD %prec '('
442 { $$ = make_op(O_CLOSE, 1,
443 stab_to_arg(A_STAB,stabent($2,TRUE)),
444 Nullarg, Nullarg,0); }
446 { $$ = make_op(O_EOF, 1,
447 stab_to_arg(A_STAB,stabent($3,TRUE)),
448 Nullarg, Nullarg,0); }
450 { $$ = make_op(O_EOF, 0,
451 stab_to_arg(A_STAB,stabent("ARGV",TRUE)),
452 Nullarg, Nullarg,0); }
454 { $$ = make_op(O_EOF, 0,
455 Nullarg, Nullarg, Nullarg,0); }
457 { $$ = make_op(O_TELL, 1,
458 stab_to_arg(A_STAB,stabent($3,TRUE)),
459 Nullarg, Nullarg,0); }
461 { $$ = make_op(O_TELL, 0,
462 Nullarg, Nullarg, Nullarg,0); }
463 | SEEK '(' WORD ',' sexpr ',' expr ')'
464 { $$ = make_op(O_SEEK, 3,
465 stab_to_arg(A_STAB,stabent($3,TRUE)),
467 | PUSH '(' WORD ',' expr ')'
468 { $$ = make_op($1, 2,
470 stab_to_arg(A_STAB,aadd(stabent($3,TRUE))),
472 | PUSH '(' ARY ',' expr ')'
473 { $$ = make_op($1, 2,
475 stab_to_arg(A_STAB,$3),
478 { $$ = make_op(O_POP, 1,
479 stab_to_arg(A_STAB,aadd(stabent($2,TRUE))),
480 Nullarg, Nullarg,0); }
482 { $$ = make_op(O_POP, 1,
483 stab_to_arg(A_STAB,aadd(stabent($3,TRUE))),
484 Nullarg, Nullarg,0); }
486 { $$ = make_op(O_POP, 1,
487 stab_to_arg(A_STAB,$2),
492 { $$ = make_op(O_POP, 1,
493 stab_to_arg(A_STAB,$3),
497 | SHIFT WORD %prec '('
498 { $$ = make_op(O_SHIFT, 1,
499 stab_to_arg(A_STAB,aadd(stabent($2,TRUE))),
500 Nullarg, Nullarg,0); }
502 { $$ = make_op(O_SHIFT, 1,
503 stab_to_arg(A_STAB,aadd(stabent($3,TRUE))),
504 Nullarg, Nullarg,0); }
505 | SHIFT ARY %prec '('
506 { $$ = make_op(O_SHIFT, 1,
507 stab_to_arg(A_STAB,$2), Nullarg, Nullarg,0); }
509 { $$ = make_op(O_SHIFT, 1,
510 stab_to_arg(A_STAB,$3), Nullarg, Nullarg,0); }
512 { $$ = make_op(O_SHIFT, 1,
513 stab_to_arg(A_STAB,aadd(stabent("ARGV",TRUE))),
514 Nullarg, Nullarg,0); }
516 { scanpat("/[ \t\n]+/");
517 $$ = make_split(defstab,yylval.arg); }
519 { scanpat("/[ \t\n]+/");
520 $$ = make_split(stabent($3,TRUE),yylval.arg); }
521 | SPLIT '(' WORD ',' PATTERN ')'
522 { $$ = make_split(stabent($3,TRUE),$5); }
523 | SPLIT '(' WORD ',' PATTERN ',' sexpr ')'
524 { $$ = mod_match(O_MATCH,
526 make_split(stabent($3,TRUE),$5) ); }
527 | SPLIT '(' sexpr ',' sexpr ')'
528 { $$ = mod_match(O_MATCH, $5, make_split(defstab,$3) ); }
529 | SPLIT '(' sexpr ')'
530 { $$ = mod_match(O_MATCH,
531 stab_to_arg(A_STAB,defstab),
532 make_split(defstab,$3) ); }
533 | JOIN '(' WORD ',' expr ')'
534 { $$ = make_op(O_JOIN, 2,
536 stab_to_arg(A_STAB,aadd(stabent($3,TRUE))),
538 | JOIN '(' sexpr ',' expr ')'
539 { $$ = make_op(O_JOIN, 2,
543 | SPRINTF '(' expr ')'
544 { $$ = make_op(O_SPRINTF, 1,
549 { $$ = l(make_op(O_STAT, 1,
550 stab_to_arg(A_STAB,stabent($3,TRUE)),
551 Nullarg, Nullarg,0)); }
553 { $$ = make_op(O_STAT, 1, $3, Nullarg, Nullarg,0); }
555 { $$ = l(make_op(O_CHOP, 1,
556 stab_to_arg(A_STAB,defstab),
557 Nullarg, Nullarg,0)); }
559 { $$ = l(make_op(O_CHOP, 1, $3, Nullarg, Nullarg,0)); }
561 { $$ = make_op($1, 0, Nullarg, Nullarg, Nullarg,0); }
563 { $$ = make_op($1, 1, $3, Nullarg, Nullarg,0); }
564 | FUNC2 '(' sexpr ',' expr ')'
565 { $$ = make_op($1, 2, $3, $5, Nullarg, 0); }
566 | FUNC3 '(' sexpr ',' sexpr ',' expr ')'
567 { $$ = make_op($1, 3, $3, $5, $7, 0); }
568 | STABFUN '(' WORD ')'
569 { $$ = make_op($1, 1,
570 stab_to_arg(A_STAB,hadd(stabent($3,TRUE))),
577 stab_to_arg(A_STAB,defstab),
578 stab_to_arg(A_STAB,Nullstab),
581 { $$ = make_op($1,2,make_list($2),
582 stab_to_arg(A_STAB,Nullstab),
586 stab_to_arg(A_STAB,defstab),
587 stab_to_arg(A_STAB,stabent($2,TRUE)),
590 { $$ = make_op($1,2,make_list($3),
591 stab_to_arg(A_STAB,stabent($2,TRUE)),