exec: iffable | SDO end_spec intonlyon label intonlyoff dospec { if($4->labdefined) error("no backward DO loops",0,0,EXECERR); $4->blklevel = blklevel+1; exdo($4->labelno, $6); } | logif iffable { exendif(); thiswasbranch = NO; } | logif STHEN | SELSEIF end_spec SLPAR expr SRPAR STHEN { exelif($4); } | SELSE end_spec { exelse(); } | SENDIF end_spec { exendif(); } ; logif: SLOGIF end_spec SLPAR expr SRPAR { exif($4); } ; dospec: name SEQUALS exprlist { $$ = mkchain($1, $3); } ; iffable: let lhs SEQUALS expr { exequals($2, $4); } | SASSIGN end_spec labelval STO name { exassign($5, $3); } | SCONTINUE end_spec | goto | io { inioctl = NO; } | SARITHIF end_spec SLPAR expr SRPAR label SCOMMA label SCOMMA label { exarif($4, $6, $8, $10); thiswasbranch = YES; } | call { excall($1, 0, 0, labarray); } | call SLPAR SRPAR { excall($1, 0, 0, labarray); } | call SLPAR callarglist SRPAR { if(nstars < MAXLABLIST) excall($1, mklist($3), nstars, labarray); else error("too many alternate returns",0,0,ERR); } | SRETURN end_spec opt_expr { exreturn($3); thiswasbranch = YES; } | stop end_spec opt_expr { exstop($1, $3); thiswasbranch = $1; } ; let: SLET { if(parstate == OUTSIDE) { newproc(); startproc(0, CLMAIN); } } ; goto: SGOTO end_spec label { exgoto($3); thiswasbranch = YES; } | SASGOTO end_spec name { exasgoto($3); thiswasbranch = YES; } | SASGOTO end_spec name opt_comma SLPAR labellist SRPAR { exasgoto($3); thiswasbranch = YES; } | SCOMPGOTO end_spec SLPAR labellist SRPAR opt_comma expr { if(nstars < MAXLABLIST) putcmgo(fixtype($7), nstars, labarray); else error("computed GOTO list too long",0,0,ERR); } ; opt_comma: | SCOMMA ; call: SCALL end_spec name { nstars = 0; $$ = $3; } ; callarglist: callarg { $$ = ($1 ? mkchain($1,0) : 0); } | callarglist SCOMMA callarg { if($3) if($1) $$ = hookup($1, mkchain($3,0)); else $$ = mkchain($3,0); } ; callarg: expr | SSTAR label { if(nstars