1 /* $Header: perl.y,v 1.0 87/12/18 15:48:59 root Exp $
4 * Revision 1.0 87/12/18 15:48:59 root
19 "append","open","write","select","close","loopctl",
20 "using","format","do","shift","push","pop","chop",
21 "while","until","if","unless","else","elsif","continue","split","sprintf",
22 "for", "eof", "tell", "seek", "stat",
23 "function(no args)","function(1 arg)","function(2 args)","function(3 args)","array function",
26 "register","array_length", "array",
29 "print", "unary operation",
33 "==","!=", "EQ", "NE",
34 "<=",">=", "LT", "GT", "LE", "GE",
51 struct compcmd compval;
57 %token <ival> APPEND OPEN WRITE SELECT CLOSE LOOPEX
58 %token <ival> USING FORMAT DO SHIFT PUSH POP CHOP
59 %token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE SPLIT SPRINTF
60 %token <ival> FOR FEOF TELL SEEK STAT
61 %token <ival> FUNC0 FUNC1 FUNC2 FUNC3 STABFUN
62 %token <ival> JOIN SUB
63 %token <formval> FORMLIST
64 %token <stabval> REG ARYLEN ARY
65 %token <arg> SUBST PATTERN
66 %token <arg> RSTRING TRANS
68 %type <ival> prog decl format
70 %type <cmdval> block lineseq line loop cond sideff nexpr else
71 %type <arg> expr sexpr term
72 %type <arg> condmod loopmod cexpr
73 %type <arg> texpr print
75 %type <compval> compblock
77 %nonassoc <ival> PRINT
79 %nonassoc <ival> UNIOP
87 %nonassoc EQ NE SEQ SNE
88 %nonassoc '<' '>' LE GE SLT SGT SLE SGE
100 { main_root = block_head($1); }
103 compblock: block CONTINUE block
104 { $$.comp_true = $1; $$.comp_alt = $3; }
106 { $$.comp_true = $1; $$.comp_alt = $2; }
113 | ELSIF '(' expr ')' compblock
114 { $$ = make_ccmd(C_IF,$3,$5); }
117 block : '{' lineseq '}'
118 { $$ = block_head($2); }
124 { $$ = append_line($1,$2); }
130 { $$ = add_label($1,$2); }
131 | loop /* loops add their own labels */
133 { if ($1 != Nullch) {
134 $$ = add_label(make_acmd(C_EXPR, Nullstab,
139 { $$ = add_label($1,$2); }
143 { $$ = make_acmd(C_EXPR, Nullstab, $1, Nullarg); }
146 make_acmd(C_EXPR, Nullstab, Nullarg, $1), $2); }
149 make_acmd(C_EXPR, Nullstab, Nullarg, $1), $2); }
152 cond : IF '(' expr ')' compblock
153 { $$ = make_ccmd(C_IF,$3,$5); }
154 | UNLESS '(' expr ')' compblock
155 { $$ = invert(make_ccmd(C_IF,$3,$5)); }
157 { $$ = make_ccmd(C_IF,cmd_to_arg($2),$3); }
158 | UNLESS block compblock
159 { $$ = invert(make_ccmd(C_IF,cmd_to_arg($2),$3)); }
162 loop : label WHILE '(' texpr ')' compblock
163 { $$ = wopt(add_label($1,
164 make_ccmd(C_WHILE,$4,$6) )); }
165 | label UNTIL '(' expr ')' compblock
166 { $$ = wopt(add_label($1,
167 invert(make_ccmd(C_WHILE,$4,$6)) )); }
168 | label WHILE block compblock
169 { $$ = wopt(add_label($1,
170 make_ccmd(C_WHILE, cmd_to_arg($3),$4) )); }
171 | label UNTIL block compblock
172 { $$ = wopt(add_label($1,
173 invert(make_ccmd(C_WHILE, cmd_to_arg($3),$4)) )); }
174 | label FOR '(' nexpr ';' texpr ';' nexpr ')' block
175 /* basically fake up an initialize-while lineseq */
176 { yyval.compval.comp_true = $10;
177 yyval.compval.comp_alt = $8;
178 $$ = append_line($4,wopt(add_label($1,
179 make_ccmd(C_WHILE,$6,yyval.compval) ))); }
180 | label compblock /* a block is a loop that happens once */
181 { $$ = add_label($1,make_ccmd(C_BLOCK,Nullarg,$2)); }
189 texpr : /* NULL means true */
190 { scanstr("1"); $$ = yylval.arg; }
202 { $$ = make_op(O_NOT,1,$2,Nullarg,Nullarg,0); }
208 { $$ = make_op(O_NOT,1,$2,Nullarg,Nullarg,0); }
217 format : FORMAT WORD '=' FORMLIST '.'
218 { stabent($2,TRUE)->stab_form = $4; safefree($2); }
219 | FORMAT '=' FORMLIST '.'
220 { stabent("stdout",TRUE)->stab_form = $3; }
223 subrout : SUB WORD block
224 { stabent($2,TRUE)->stab_sub = $3; }
231 cexpr : sexpr ',' cexpr
232 { $$ = make_op(O_COMMA, 2, $1, $3, Nullarg,0); }
236 sexpr : sexpr '=' sexpr
238 if ($1->arg_type == O_LIST)
240 $$ = l(make_op(O_ASSIGN, 2, $1, $3, Nullarg,1)); }
241 | sexpr '*' '=' sexpr
242 { $$ = l(make_op(O_MULTIPLY, 2, $1, $4, Nullarg,0)); }
243 | sexpr '/' '=' sexpr
244 { $$ = l(make_op(O_DIVIDE, 2, $1, $4, Nullarg,0)); }
245 | sexpr '%' '=' sexpr
246 { $$ = l(make_op(O_MODULO, 2, $1, $4, Nullarg,0)); }
247 | sexpr 'x' '=' sexpr
248 { $$ = l(make_op(O_REPEAT, 2, $1, $4, Nullarg,0)); }
249 | sexpr '+' '=' sexpr
250 { $$ = l(make_op(O_ADD, 2, $1, $4, Nullarg,0)); }
251 | sexpr '-' '=' sexpr
252 { $$ = l(make_op(O_SUBTRACT, 2, $1, $4, Nullarg,0)); }
254 { $$ = l(make_op(O_LEFT_SHIFT, 2, $1, $4, Nullarg,0)); }
256 { $$ = l(make_op(O_RIGHT_SHIFT, 2, $1, $4, Nullarg,0)); }
257 | sexpr '&' '=' sexpr
258 { $$ = l(make_op(O_BIT_AND, 2, $1, $4, Nullarg,0)); }
259 | sexpr '^' '=' sexpr
260 { $$ = l(make_op(O_XOR, 2, $1, $4, Nullarg,0)); }
261 | sexpr '|' '=' sexpr
262 { $$ = l(make_op(O_BIT_OR, 2, $1, $4, Nullarg,0)); }
263 | sexpr '.' '=' sexpr
264 { $$ = l(make_op(O_CONCAT, 2, $1, $4, Nullarg,0)); }
268 { $$ = make_op(O_MULTIPLY, 2, $1, $3, Nullarg,0); }
270 { $$ = make_op(O_DIVIDE, 2, $1, $3, Nullarg,0); }
272 { $$ = make_op(O_MODULO, 2, $1, $3, Nullarg,0); }
274 { $$ = make_op(O_REPEAT, 2, $1, $3, Nullarg,0); }
276 { $$ = make_op(O_ADD, 2, $1, $3, Nullarg,0); }
278 { $$ = make_op(O_SUBTRACT, 2, $1, $3, Nullarg,0); }
280 { $$ = make_op(O_LEFT_SHIFT, 2, $1, $3, Nullarg,0); }
282 { $$ = make_op(O_RIGHT_SHIFT, 2, $1, $3, Nullarg,0); }
284 { $$ = make_op(O_LT, 2, $1, $3, Nullarg,0); }
286 { $$ = make_op(O_GT, 2, $1, $3, Nullarg,0); }
288 { $$ = make_op(O_LE, 2, $1, $3, Nullarg,0); }
290 { $$ = make_op(O_GE, 2, $1, $3, Nullarg,0); }
292 { $$ = make_op(O_EQ, 2, $1, $3, Nullarg,0); }
294 { $$ = make_op(O_NE, 2, $1, $3, Nullarg,0); }
296 { $$ = make_op(O_SLT, 2, $1, $3, Nullarg,0); }
298 { $$ = make_op(O_SGT, 2, $1, $3, Nullarg,0); }
300 { $$ = make_op(O_SLE, 2, $1, $3, Nullarg,0); }
302 { $$ = make_op(O_SGE, 2, $1, $3, Nullarg,0); }
304 { $$ = make_op(O_SEQ, 2, $1, $3, Nullarg,0); }
306 { $$ = make_op(O_SNE, 2, $1, $3, Nullarg,0); }
308 { $$ = make_op(O_BIT_AND, 2, $1, $3, Nullarg,0); }
310 { $$ = make_op(O_XOR, 2, $1, $3, Nullarg,0); }
312 { $$ = make_op(O_BIT_OR, 2, $1, $3, Nullarg,0); }
314 { $$ = make_op(O_FLIP, 4,
319 { $$ = make_op(O_AND, 2, $1, $3, Nullarg,0); }
321 { $$ = make_op(O_OR, 2, $1, $3, Nullarg,0); }
322 | sexpr '?' sexpr ':' sexpr
323 { $$ = make_op(O_COND_EXPR, 3, $1, $3, $5,0); }
325 { $$ = make_op(O_CONCAT, 2, $1, $3, Nullarg,0); }
327 { $$ = mod_match(O_MATCH, $1, $3); }
329 { $$ = mod_match(O_NMATCH, $1, $3); }
331 { $$ = addflags(1, AF_POST|AF_UP,
332 l(make_op(O_ITEM,1,$1,Nullarg,Nullarg,0))); }
334 { $$ = addflags(1, AF_POST,
335 l(make_op(O_ITEM,1,$1,Nullarg,Nullarg,0))); }
337 { $$ = addflags(1, AF_PRE|AF_UP,
338 l(make_op(O_ITEM,1,$2,Nullarg,Nullarg,0))); }
340 { $$ = addflags(1, AF_PRE,
341 l(make_op(O_ITEM,1,$2,Nullarg,Nullarg,0))); }
346 term : '-' term %prec UMINUS
347 { $$ = make_op(O_NEGATE, 1, $2, Nullarg, Nullarg,0); }
349 { $$ = make_op(O_NOT, 1, $2, Nullarg, Nullarg,0); }
351 { $$ = make_op(O_COMPLEMENT, 1, $2, Nullarg, Nullarg,0);}
353 { $$ = make_list(hide_ary($2)); }
355 { $$ = make_list(Nullarg); }
357 { $$ = cmd_to_arg($2); }
359 { $$ = stab_to_arg(A_STAB,$1); }
360 | REG '[' expr ']' %prec '('
361 { $$ = make_op(O_ARRAY, 2,
362 $3, stab_to_arg(A_STAB,aadd($1)), Nullarg,0); }
364 { $$ = make_op(O_ARRAY, 1,
365 stab_to_arg(A_STAB,$1),
366 Nullarg, Nullarg, 1); }
367 | REG '{' expr '}' %prec '('
368 { $$ = make_op(O_HASH, 2,
369 $3, stab_to_arg(A_STAB,hadd($1)), Nullarg,0); }
371 { $$ = stab_to_arg(A_ARYLEN,$1); }
380 | DO WORD '(' expr ')'
381 { $$ = make_op(O_SUBR, 2,
383 stab_to_arg(A_STAB,stabent($2,TRUE)),
386 { $$ = make_op(O_SUBR, 2,
388 stab_to_arg(A_STAB,stabent($2,TRUE)),
391 { $$ = make_op($1,0,Nullarg,Nullarg,Nullarg,0); }
393 { $$ = make_op($1,1,cval_to_arg($2),
394 Nullarg,Nullarg,0); }
396 { $$ = make_op($1,1,Nullarg,Nullarg,Nullarg,0); }
398 { $$ = make_op($1,1,$2,Nullarg,Nullarg,0); }
400 { $$ = make_op(O_WRITE, 0,
401 Nullarg, Nullarg, Nullarg,0); }
403 { $$ = make_op(O_WRITE, 0,
404 Nullarg, Nullarg, Nullarg,0); }
406 { $$ = l(make_op(O_WRITE, 1,
407 stab_to_arg(A_STAB,stabent($3,TRUE)),
408 Nullarg, Nullarg,0)); safefree($3); }
410 { $$ = make_op(O_WRITE, 1, $3, Nullarg, Nullarg,0); }
411 | SELECT '(' WORD ')'
412 { $$ = l(make_op(O_SELECT, 1,
413 stab_to_arg(A_STAB,stabent($3,TRUE)),
414 Nullarg, Nullarg,0)); safefree($3); }
415 | SELECT '(' expr ')'
416 { $$ = make_op(O_SELECT, 1, $3, Nullarg, Nullarg,0); }
417 | OPEN WORD %prec '('
418 { $$ = make_op(O_OPEN, 2,
419 stab_to_arg(A_STAB,stabent($2,TRUE)),
420 stab_to_arg(A_STAB,stabent($2,TRUE)),
423 { $$ = make_op(O_OPEN, 2,
424 stab_to_arg(A_STAB,stabent($3,TRUE)),
425 stab_to_arg(A_STAB,stabent($3,TRUE)),
427 | OPEN '(' WORD ',' expr ')'
428 { $$ = make_op(O_OPEN, 2,
429 stab_to_arg(A_STAB,stabent($3,TRUE)),
432 { $$ = make_op(O_CLOSE, 1,
433 stab_to_arg(A_STAB,stabent($3,TRUE)),
434 Nullarg, Nullarg,0); }
435 | CLOSE WORD %prec '('
436 { $$ = make_op(O_CLOSE, 1,
437 stab_to_arg(A_STAB,stabent($2,TRUE)),
438 Nullarg, Nullarg,0); }
440 { $$ = make_op(O_EOF, 1,
441 stab_to_arg(A_STAB,stabent($3,TRUE)),
442 Nullarg, Nullarg,0); }
444 { $$ = make_op(O_EOF, 0,
445 stab_to_arg(A_STAB,stabent("ARGV",TRUE)),
446 Nullarg, Nullarg,0); }
448 { $$ = make_op(O_EOF, 0,
449 Nullarg, Nullarg, Nullarg,0); }
451 { $$ = make_op(O_TELL, 1,
452 stab_to_arg(A_STAB,stabent($3,TRUE)),
453 Nullarg, Nullarg,0); }
455 { $$ = make_op(O_TELL, 0,
456 Nullarg, Nullarg, Nullarg,0); }
457 | SEEK '(' WORD ',' sexpr ',' expr ')'
458 { $$ = make_op(O_SEEK, 3,
459 stab_to_arg(A_STAB,stabent($3,TRUE)),
461 | PUSH '(' WORD ',' expr ')'
462 { $$ = make_op($1, 2,
464 stab_to_arg(A_STAB,aadd(stabent($3,TRUE))),
466 | PUSH '(' ARY ',' expr ')'
467 { $$ = make_op($1, 2,
469 stab_to_arg(A_STAB,$3),
472 { $$ = make_op(O_POP, 1,
473 stab_to_arg(A_STAB,aadd(stabent($2,TRUE))),
474 Nullarg, Nullarg,0); }
476 { $$ = make_op(O_POP, 1,
477 stab_to_arg(A_STAB,aadd(stabent($3,TRUE))),
478 Nullarg, Nullarg,0); }
480 { $$ = make_op(O_POP, 1,
481 stab_to_arg(A_STAB,$2),
486 { $$ = make_op(O_POP, 1,
487 stab_to_arg(A_STAB,$3),
491 | SHIFT WORD %prec '('
492 { $$ = make_op(O_SHIFT, 1,
493 stab_to_arg(A_STAB,aadd(stabent($2,TRUE))),
494 Nullarg, Nullarg,0); }
496 { $$ = make_op(O_SHIFT, 1,
497 stab_to_arg(A_STAB,aadd(stabent($3,TRUE))),
498 Nullarg, Nullarg,0); }
499 | SHIFT ARY %prec '('
500 { $$ = make_op(O_SHIFT, 1,
501 stab_to_arg(A_STAB,$2), Nullarg, Nullarg,0); }
503 { $$ = make_op(O_SHIFT, 1,
504 stab_to_arg(A_STAB,$3), Nullarg, Nullarg,0); }
506 { $$ = make_op(O_SHIFT, 1,
507 stab_to_arg(A_STAB,aadd(stabent("ARGV",TRUE))),
508 Nullarg, Nullarg,0); }
510 { scanpat("/[ \t\n]+/");
511 $$ = make_split(defstab,yylval.arg); }
513 { scanpat("/[ \t\n]+/");
514 $$ = make_split(stabent($3,TRUE),yylval.arg); }
515 | SPLIT '(' WORD ',' PATTERN ')'
516 { $$ = make_split(stabent($3,TRUE),$5); }
517 | SPLIT '(' WORD ',' PATTERN ',' sexpr ')'
518 { $$ = mod_match(O_MATCH,
520 make_split(stabent($3,TRUE),$5) ); }
521 | SPLIT '(' sexpr ',' sexpr ')'
522 { $$ = mod_match(O_MATCH, $5, make_split(defstab,$3) ); }
523 | SPLIT '(' sexpr ')'
524 { $$ = mod_match(O_MATCH,
525 stab_to_arg(A_STAB,defstab),
526 make_split(defstab,$3) ); }
527 | JOIN '(' WORD ',' expr ')'
528 { $$ = make_op(O_JOIN, 2,
530 stab_to_arg(A_STAB,aadd(stabent($3,TRUE))),
532 | JOIN '(' sexpr ',' expr ')'
533 { $$ = make_op(O_JOIN, 2,
537 | SPRINTF '(' expr ')'
538 { $$ = make_op(O_SPRINTF, 1,
543 { $$ = l(make_op(O_STAT, 1,
544 stab_to_arg(A_STAB,stabent($3,TRUE)),
545 Nullarg, Nullarg,0)); }
547 { $$ = make_op(O_STAT, 1, $3, Nullarg, Nullarg,0); }
549 { $$ = l(make_op(O_CHOP, 1,
550 stab_to_arg(A_STAB,defstab),
551 Nullarg, Nullarg,0)); }
553 { $$ = l(make_op(O_CHOP, 1, $3, Nullarg, Nullarg,0)); }
555 { $$ = make_op($1, 0, Nullarg, Nullarg, Nullarg,0); }
557 { $$ = make_op($1, 1, $3, Nullarg, Nullarg,0); }
558 | FUNC2 '(' sexpr ',' expr ')'
559 { $$ = make_op($1, 2, $3, $5, Nullarg, 0); }
560 | FUNC3 '(' sexpr ',' sexpr ',' expr ')'
561 { $$ = make_op($1, 3, $3, $5, $7, 0); }
562 | STABFUN '(' WORD ')'
563 { $$ = make_op($1, 1,
564 stab_to_arg(A_STAB,hadd(stabent($3,TRUE))),
571 stab_to_arg(A_STAB,defstab),
572 stab_to_arg(A_STAB,Nullstab),
575 { $$ = make_op($1,2,make_list($2),
576 stab_to_arg(A_STAB,Nullstab),
580 stab_to_arg(A_STAB,defstab),
581 stab_to_arg(A_STAB,stabent($2,TRUE)),
584 { $$ = make_op($1,2,make_list($3),
585 stab_to_arg(A_STAB,stabent($2,TRUE)),