* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
* @(#)gram.exec 5.2 (Berkeley) 1/7/86
* Grammar for executable statements, f77 compiler pass 1, 4.2 BSD.
* University of Utah CS Dept modification history:
* Revision 5.2 85/12/18 20:17:38 donn
* Modified end_spec to insist on parser state INEXEC after seeing an
* executable statement. This allows us to limit statement functions to
* Revision 5.1 85/08/10 03:47:22 donn
* Revision 3.1 84/10/13 00:36:41 donn
* Installed Jerry Berkman's version; preserved comment header.
* Revision 1.3 84/08/06 18:38:43 donn
* Fixed a bug in Jerry Berkman's label fixes which caused the same label to
* be generated twice for some types of logical IF statements.
* Revision 1.2 84/08/04 21:09:57 donn
* Added fixes from Jerry Berkman to allow proper ASSIGNS from format
| SDO end_spec intonlyon label intonlyoff opt_comma dospec
execerr("no backward DO loops", CNULL);
$4->blklevel = blklevel+1;
{ exendif(); thiswasbranch = NO; }
| SELSEIF end_spec SLPAR expr SRPAR STHEN
{ exelif($4); lastwasbranch = NO; }
{ exelse(); lastwasbranch = NO; }
{ exendif(); lastwasbranch = NO; }
logif: SLOGIF end_spec SLPAR expr SRPAR
dospec: name SEQUALS exprlist
{ if( $1->vclass != CLPARAM ) {
err("symbolic constant not allowed as DO variable");
iffable: let lhs SEQUALS expr
| SASSIGN end_spec assignlabel STO name
{ if( $5->vclass != CLPARAM ) {
err("can only assign to a variable");
| SARITHIF end_spec SLPAR expr SRPAR label SCOMMA label SCOMMA label
{ exarif($4, $6, $8, $10); thiswasbranch = YES; }
{ excall($1, PNULL, 0, labarray); }
{ excall($1, PNULL, 0, labarray); }
| call SLPAR callarglist SRPAR
{ if(nstars < MAXLABLIST)
excall($1, mklist($3), nstars, labarray);
err("too many alternate returns");
| SRETURN end_spec opt_expr
{ exreturn($3); thiswasbranch = YES; }
{ exstop($1, $3); thiswasbranch = $1; }
{ $$ = mklabel( convci(toklen, token) ); }
{ if(parstate == OUTSIDE)
startproc(PNULL, CLMAIN);
if( yystno != 0 && thislabel->labtype != LABFORMAT)
optbuff (SKLABEL, 0, thislabel->labelno, 1);
putlabel(thislabel->labelno);
goto: SGOTO end_spec label
{ exgoto($3); thiswasbranch = YES; }
{ if( $3->vclass != CLPARAM ) {
exasgoto($3); thiswasbranch = YES;
err("must go to label or assigned variable");
| SASGOTO end_spec name opt_comma SLPAR labellist SRPAR
{ if( $3->vclass != CLPARAM ) {
exasgoto($3); thiswasbranch = YES;
err("must go to label or assigned variable");
| SCOMPGOTO end_spec SLPAR labellist SRPAR opt_comma expr
{ if(nstars < MAXLABLIST)
optbuff (SKCMGOTO, fixtype($7), nstars, labarray);
putcmgo (fixtype($7), nstars, labarray);
err("computed GOTO list too long");
call: SCALL end_spec name
{ $$ = ($1 ? mkchain($1,CHNULL) : CHNULL); }
| callarglist SCOMMA callarg
if($1) $$ = hookup($1, mkchain($3,CHNULL));
else $$ = mkchain($3,CHNULL);
{ if(nstars<MAXLABLIST) labarray[nstars++] = $2; $$ = 0; }
{ $$ = mkchain($1, CHNULL); }
{ $$ = hookup($1, mkchain($3,CHNULL) ); }
{ if(parstate == OUTSIDE)
startproc(PNULL, CLMAIN);
if(parstate < INDATA) enddcl();
if( yystno != 0 && thislabel->labtype != LABFORMAT)
optbuff (SKLABEL, 0, thislabel->labelno, 1);
putlabel(thislabel->labelno);