# 2.11BSD#431 - /usr/src/lib/mip/cgram.y

##### Functions

    _addcase          X
    _adddef           X
    _bdty             X
    _dstash           X
    _mkty             X
    _resetbc          X
    _savebc           X
    _swend            X
    _swstart          X

       1: /*	cgram.y	4.4.1	95/01/17	*/
       2:
       3: /*
       4:  * Grammar for the C compiler.
       5:  *
       6:  * This grammar requires the definitions of terminals in the file 'pcctokens'.
       7:  * (YACC doesn't have an 'include' mechanism, unfortunately.)
       8:  */
       9:
      10:
      11: /* at last count, there were 7 shift/reduce, 1 reduce/reduce conflicts
      12: /* these involved:
      13: 	if/else
      14: 	recognizing functions in various contexts, including declarations
      15: 	error recovery
      16: 	*/
      17:
      18: %left CM
      19: %right ASOP ASSIGN
      20: %right QUEST COLON
      21: %left OROR
      22: %left ANDAND
      23: %left OR
      24: %left ER
      25: %left AND
      26: %left EQUOP
      27: %left RELOP
      28: %left SHIFTOP
      29: %left PLUS MINUS
      30: %left MUL DIVOP
      31: %right UNOP
      32: %right INCOP SIZEOF
      33: %left LB LP STROP
      34: %{
      35: # include "pass1.h"
      36: %}
      37:
      38:     /* define types */
      39: %start ext_def_list
      40:
      41: %type <intval> con_e ifelprefix ifprefix whprefix forprefix doprefix switchpart
      42:         enum_head str_head name_lp
      43: %type <nodep> e .e term attributes oattributes type enum_dcl struct_dcl
      44:         cast_type null_decl funct_idn declarator fdeclarator nfdeclarator
      45:         elist
      46:
      47: %token <intval> CLASS NAME STRUCT RELOP CM DIVOP PLUS MINUS SHIFTOP MUL AND OR ER ANDAND OROR
      48:         ASSIGN STROP INCOP UNOP ICON
      49: %token <nodep> TYPE
      50:
      51: %%
      52:
      53: %{
      54:     static int fake = 0;
      55: #ifndef FLEXNAMES
      56:     static char fakename[NCHNAM+1];
      57: #else
      58:     static char fakename[24];
      59: #endif
      60: %}
      61:
      62: ext_def_list:      ext_def_list external_def
      63:         |
      64:             =ftnend();
      65:         ;
      66: external_def:      data_def
      67:             ={ curclass = SNULL;  blevel = 0; }
      68:         |  error
      69:             ={ curclass = SNULL;  blevel = 0; }
      70:         ;
      71: data_def:
      72:            oattributes  SM
      73:             ={  $1->in.op = FREE; }
      74:         |  oattributes init_dcl_list  SM
      75:             ={  $1->in.op = FREE; }
      76:         |  oattributes fdeclarator {
      77:                 defid( tymerge($1,$2), curclass==STATIC?STATIC:EXTDEF );
      78: #ifndef LINT
      79:                 pfstab(stab[$2->tn.rval].sname);
      80: #endif
      81:                 }  function_body
      82:             ={
      83:                 if( blevel ) cerror("function level error" );
      84:                 if( reached ) retstat |= NRETVAL;
      85:                 $1->in.op = FREE;
      86:                 ftnend();
      87:                 }
      88:         ;
      89:
      90: function_body:     arg_dcl_list compoundstmt
      91:         ;
      92: arg_dcl_list:      arg_dcl_list declaration
      93:         |   ={  blevel = 1; }
      94:         ;
      95:
      96: stmt_list:     stmt_list statement
      97:         |  /* empty */
      98:             ={  bccode();
      99:                 locctr(PROG);
     100:                 }
     101:         ;
     102:
     103: r_dcl_stat_list :  dcl_stat_list attributes SM
     104:             ={  $2->in.op = FREE;
     105: #ifndef LINT
     106:                 plcstab(blevel);
     107: #endif
     108:                 }
     109:         |  dcl_stat_list attributes init_dcl_list SM
     110:             ={  $2->in.op = FREE;
     111: #ifndef LINT
     112:                 plcstab(blevel);
     113: #endif
     114:                 }
     115:         ;
     116:
     117: dcl_stat_list   :  dcl_stat_list attributes SM
     118:             ={  $2->in.op = FREE; }
     119:         |  dcl_stat_list attributes init_dcl_list SM
     120:             ={  $2->in.op = FREE; }
     121:         |  /* empty */
     122:         ;
     123: declaration:       attributes declarator_list  SM
     124:             ={ curclass = SNULL;  $1->in.op = FREE; }
     125:         |  attributes SM
     126:             ={ curclass = SNULL;  $1->in.op = FREE; }
     127:         |  error  SM
     128:             ={  curclass = SNULL; }
     129:         ;
     130: oattributes:      attributes
     131:         |  /* VOID */
     132:             ={  $$ = mkty(INT,0,INT);  curclass = SNULL; }
     133:         ;
     134: attributes:    class type
     135:             ={  $$ = $2; }
     136:         |  type class
     137:         |  class
     138:             ={  $$ = mkty(INT,0,INT); }
     139:         |  type
     140:             ={ curclass = SNULL ; }
     141:         |  type class type
     142:             ={  $1->in.type = types( $1->in.type, $3->in.type, UNDEF );
     143:                 $3->in.op = FREE;
     144:                 }
     145:         ;
     146:
     147:
     148: class:        CLASS
     149:             ={  curclass = $1; }
     150:         ;
     151:
     152: type:          TYPE
     153:         |  TYPE TYPE
     154:             ={  $1->in.type = types( $1->in.type, $2->in.type, UNDEF );
     155:                 $2->in.op = FREE;
     156:                 }
     157:         |  TYPE TYPE TYPE
     158:             ={  $1->in.type = types( $1->in.type, $2->in.type, $3->in.type );
     159:                 $2->in.op = $3->in.op = FREE;
     160:                 }
     161:         |  struct_dcl
     162:         |  enum_dcl
     163:         ;
     164:
     165: enum_dcl:      enum_head LC moe_list optcomma RC
     166:             ={ $$ = dclstruct($1); }
     167:         |  ENUM NAME
     168:             ={  $$ = rstruct($2,0);  stwart = instruct; }
     169:         ;
     170:
     171: enum_head:     ENUM
     172:             ={  $$ = bstruct(-1,0); stwart = SEENAME; }
     173:         |  ENUM NAME
     174:             ={  $$ = bstruct($2,0); stwart = SEENAME; }
     175:         ;
     176:
     177: moe_list:      moe
     178:         |  moe_list CM moe
     179:         ;
     180:
     181: moe:           NAME
     182:             ={  moedef( $1 ); }
     183:         |  NAME ASSIGN con_e
     184:             ={  strucoff = $3;  moedef( $1 ); }
     185:         ;
     186:
     187: struct_dcl:    str_head LC type_dcl_list optsemi RC
     188:             ={ $$ = dclstruct($1);  }
     189:         |  STRUCT NAME
     190:             ={  $$ = rstruct($2,$1); }
     191:         ;
     192:
     193: str_head:      STRUCT
     194:             ={  $$ = bstruct(-1,$1);  stwart=0; }
     195:         |  STRUCT NAME
     196:             ={  $$ = bstruct($2,$1);  stwart=0;  }
     197:         ;
     198:
     199: type_dcl_list:     type_declaration
     200:         |  type_dcl_list SM type_declaration
     201:         ;
     202:
     203: type_declaration:  type declarator_list
     204:             ={ curclass = SNULL;  stwart=0; $1->in.op = FREE; }
     205:         |  type
     206:             ={  if( curclass != MOU ){
     207:                 curclass = SNULL;
     208:                 }
     209:                 else {
     210:                 sprintf( fakename, "$%dFAKE", fake++ );
     211: #ifdef FLEXNAMES
     212:                 /* No need to hash this, we won't look it up */
     213:                 defid( tymerge($1, bdty(NAME,NIL,lookup( savestr(fakename), SMOS ))), curclass );
     214: #else
     215:                 defid( tymerge($1, bdty(NAME,NIL,lookup( fakename, SMOS ))), curclass );
     216: #endif
     217:                 werror("structure typed union member must be named");
     218:                 }
     219:                 stwart = 0;
     220:                 $1->in.op = FREE;
     221:                 }
     222:         ;
     223:
     224:
     225: declarator_list:   declarator
     226:             ={ defid( tymerge($<nodep>0,$1), curclass);  stwart = instruct; }
     227:         |  declarator_list  CM {$<nodep>$=$<nodep>0;}  declarator
     228:             ={ defid( tymerge($<nodep>0,$4), curclass);  stwart = instruct; }
     229:         ;
     230: declarator:    fdeclarator
     231:         |  nfdeclarator
     232:         |  nfdeclarator COLON con_e
     233:             %prec CM
     234:             ={  if( !(instruct&INSTRUCT) ) uerror("field outside of structure" );
     235:                 if( $3<0 || $3 >= FIELD ){
     236:                 uerror("illegal field size" );
     237:                 $3 = 1;
     238:                 }
     239:                 defid( tymerge($<nodep>0,$1), FIELD|$3 );
     240:                 $$ = NIL;
     241:                 }
     242:         |  COLON con_e
     243:             %prec CM
     244:             ={  if( !(instruct&INSTRUCT) ) uerror("field outside of structure" );
     245:                 falloc( stab, $2, -1, $<nodep>0 );  /* alignment or hole */
     246:                 $$ = NIL;
     247:                 }
     248:         |  error
     249:             ={  $$ = NIL; }
     250:         ;
     251:
     252:         /* int (a)();   is not a function --- sorry! */
     253: nfdeclarator:      MUL nfdeclarator
     254:             ={  umul:
     255:                 $$ = bdty( UNARY MUL, $2, 0 ); }
     256:         |  nfdeclarator  LP   RP
     257:             ={  uftn:
     258:                 $$ = bdty( UNARY CALL, $1, 0 );  }
     259:         |  nfdeclarator LB RB
     260:             ={  uary:
     261:                 $$ = bdty( LB, $1, 0 );  }
     262:         |  nfdeclarator LB con_e RB
     263:             ={  bary:
     264:                 if( (int)$3 <= 0 ) werror("zero or negative subscript" );
     265:                 $$ = bdty( LB, $1, $3 );  }
     266:         |  NAME
     267:             ={  $$ = bdty( NAME, NIL, $1 );  }
     268:         |   LP  nfdeclarator  RP
     269:             ={ $$=$2; }
     270:         ;
     271: fdeclarator:       MUL fdeclarator
     272:             ={  goto umul; }
     273:         |  fdeclarator  LP   RP
     274:             ={  goto uftn; }
     275:         |  fdeclarator LB RB
     276:             ={  goto uary; }
     277:         |  fdeclarator LB con_e RB
     278:             ={  goto bary; }
     279:         |   LP  fdeclarator  RP
     280:             ={ $$ = $2; }
     281:         |  name_lp  name_list  RP
     282:             ={
     283:                 if( blevel!=0 ) uerror("function declaration in bad context");
     284:                 $$ = bdty( UNARY CALL, bdty(NAME,NIL,$1), 0 );
     285:                 stwart = 0;
     286:                 }
     287:         |  name_lp RP
     288:             ={
     289:                 $$ = bdty( UNARY CALL, bdty(NAME,NIL,$1), 0 );
     290:                 stwart = 0;
     291:                 }
     292:         ;
     293:
     294: name_lp:      NAME LP
     295:             ={
     296:                 /* turn off typedefs for argument names */
     297:                 stwart = SEENAME;
     298:                 if( stab[$1].sclass == SNULL )
     299:                     stab[$1].stype = FTN;
     300:                 }
     301:         ;
     302:
     303: name_list:     NAME
     304:             ={ ftnarg( $1 );  stwart = SEENAME; }
     305:         |  name_list  CM  NAME
     306:             ={ ftnarg( $3 );  stwart = SEENAME; }
     307:         | error
     308:         ;
     309:         /* always preceeded by attributes: thus the $<nodep>0's */
     310: init_dcl_list:     init_declarator
     311:             %prec CM
     312:         |  init_dcl_list  CM {$<nodep>$=$<nodep>0;}  init_declarator
     313:         ;
     314:         /* always preceeded by attributes */
     315: xnfdeclarator:     nfdeclarator
     316:             ={  defid( $1 = tymerge($<nodep>0,$1), curclass);
     317:                 beginit($1->tn.rval);
     318:                 }
     319:         |  error
     320:         ;
     321:         /* always preceeded by attributes */
     322: init_declarator:   nfdeclarator
     323:             ={  nidcl( tymerge($<nodep>0,$1) ); }
     324:         |  fdeclarator
     325:             ={  defid( tymerge($<nodep>0,$1), uclass(curclass) );
     326:                 if( paramno > 0 ){
     327:                 uerror("illegal argument" );
     328:                 paramno = 0;
     329:                 }
     330:             }
     331:         |  xnfdeclarator optasgn e
     332:             %prec CM
     333:             ={  doinit( $3 );
     334:                 endinit(); }
     335:         |  xnfdeclarator optasgn LC init_list optcomma RC
     336:             ={  endinit(); }
     337:         | error
     338:         ;
     339:
     340: init_list:     initializer
     341:             %prec CM
     342:         |  init_list  CM  initializer
     343:         ;
     344: initializer:       e
     345:             %prec CM
     346:             ={  doinit( $1 ); }
     347:         |  ibrace init_list optcomma RC
     348:             ={  irbrace(); }
     349:         ;
     350:
     351: optcomma    :   /* VOID */
     352:         |  CM
     353:         ;
     354:
     355: optsemi     :   /* VOID */
     356:         |  SM
     357:         ;
     358:
     359: optasgn     :   /* VOID */
     360:             ={  werror("old-fashioned initialization: use =" ); }
     361:         |  ASSIGN
     362:         ;
     363:
     364: ibrace      : LC
     365:             ={  ilbrace(); }
     366:         ;
     367:
     368: /*	STATEMENTS	*/
     369:
     370: compoundstmt:      dcmpstmt
     371:         |  cmpstmt
     372:         ;
     373:
     374: dcmpstmt:      begin r_dcl_stat_list stmt_list RC
     375:             ={
     376: #ifndef LINT
     377:                 prcstab(blevel);
     378: #endif
     379:                 --blevel;
     380:                 if( blevel == 1 ) blevel = 0;
     381:                 clearst( blevel );
     382:                 checkst( blevel );
     383:                 autooff = (unsigned)*--psavbc;
     384:                 regvar = *--psavbc;
     385:                 }
     386:         ;
     387:
     388: cmpstmt:       begin stmt_list RC
     389:             ={  --blevel;
     390:                 if( blevel == 1 ) blevel = 0;
     391:                 clearst( blevel );
     392:                 checkst( blevel );
     393:                 autooff = (unsigned)*--psavbc;
     394:                 regvar = *--psavbc;
     395:                 }
     396:         ;
     397:
     398: begin:        LC
     399:             ={  if( blevel == 1 ) dclargs();
     400:                 ++blevel;
     401:                 if( psavbc > &asavbc[BCSZ-2] ) cerror("nesting too deep" );
     402:                 *psavbc++ = regvar;
     403:                 *psavbc++ = autooff;
     404:                 }
     405:         ;
     406:
     407: statement:     e   SM
     408:             ={ ecomp( $1 ); }
     409:         |  compoundstmt
     410:         |  ifprefix statement
     411:             ={ deflab($1);
     412:                reached = 1;
     413:                }
     414:         |  ifelprefix statement
     415:             ={  if( $1 != NOLAB ){
     416:                 deflab( $1 );
     417:                 reached = 1;
     418:                 }
     419:                 }
     420:         |  whprefix statement
     421:             ={  branch(  contlab );
     422:                 deflab( brklab );
     423:                 if( (flostat&FBRK) || !(flostat&FLOOP)) reached = 1;
     424:                 else reached = 0;
     425:                 resetbc(0);
     426:                 }
     427:         |  doprefix statement WHILE  LP  e  RP   SM
     428:             ={  deflab( contlab );
     429:                 if( flostat & FCONT ) reached = 1;
     430:                 ecomp( buildtree( CBRANCH, buildtree( NOT, $5, NIL ), bcon( $1 ) ) );
     431:                 deflab( brklab );
     432:                 reached = 1;
     433:                 resetbc(0);
     434:                 }
     435:         |  forprefix .e RP statement
     436:             ={  deflab( contlab );
     437:                 if( flostat&FCONT ) reached = 1;
     438:                 if( $2 ) ecomp( $2 );
     439:                 branch( $1 );
     440:                 deflab( brklab );
     441:                 if( (flostat&FBRK) || !(flostat&FLOOP) ) reached = 1;
     442:                 else reached = 0;
     443:                 resetbc(0);
     444:                 }
     445:         | switchpart statement
     446:             ={  if( reached ) branch( brklab );
     447:                 deflab( $1 );
     448:                swend();
     449:                 deflab(brklab);
     450:                 if( (flostat&FBRK) || !(flostat&FDEF) ) reached = 1;
     451:                 resetbc(FCONT);
     452:                 }
     453:         |  BREAK  SM
     454:             ={  if( brklab == NOLAB ) uerror("illegal break");
     455:                 else if(reached) branch( brklab );
     456:                 flostat |= FBRK;
     457:                 if( brkflag ) goto rch;
     458:                 reached = 0;
     459:                 }
     460:         |  CONTINUE  SM
     461:             ={  if( contlab == NOLAB ) uerror("illegal continue");
     462:                 else branch( contlab );
     463:                 flostat |= FCONT;
     464:                 goto rch;
     465:                 }
     466:         |  RETURN  SM
     467:             ={  retstat |= NRETVAL;
     468:                 branch( retlab );
     469:             rch:
     470:                 if( !reached ) werror("statement not reached");
     471:                 reached = 0;
     472:                 }
     473:         |  RETURN e  SM
     474:             ={  register NODE *temp;
     475:                 idname = curftn;
     476:                 temp = buildtree( NAME, NIL, NIL );
     477:                 if(temp->in.type == TVOID)
     478:                 uerror("void function %s cannot return value",
     479:                     stab[idname].sname);
     480:                 temp->in.type = DECREF( temp->in.type );
     481:                 temp = buildtree( RETURN, temp, $2 );
     482:                 /* now, we have the type of the RHS correct */
     483:                 temp->in.left->in.op = FREE;
     484:                 temp->in.op = FREE;
     485:                 ecomp( buildtree( FORCE, temp->in.right, NIL ) );
     486:                 retstat |= RETVAL;
     487:                 branch( retlab );
     488:                 reached = 0;
     489:                 }
     490:         |  GOTO NAME SM
     491:             ={  register NODE *q;
     492:                 q = block( FREE, NIL, NIL, INT|ARY, 0, INT );
     493:                 q->tn.rval = idname = $2;
     494:                 defid( q, ULABEL );
     495:                 stab[idname].suse = -lineno;
     496:                 branch( stab[idname].offset );
     497:                 goto rch;
     498:                 }
     499:         |   SM
     500:         |  error  SM
     501:         |  error RC
     502:         |  label statement
     503:         ;
     504: label:         NAME COLON
     505:             ={  register NODE *q;
     506:                 q = block( FREE, NIL, NIL, INT|ARY, 0, LABEL );
     507:                 q->tn.rval = $1;
     508:                 defid( q, LABEL );
     509:                 reached = 1;
     510:                 }
     511:         |  CASE e COLON
     512:             ={  addcase($2);
     513:                 reached = 1;
     514:                 }
     515:         |  DEFAULT COLON
     516:             ={  reached = 1;
     517:                 adddef();
     518:                 flostat |= FDEF;
     519:                 }
     520:         ;
     521: doprefix:   DO
     522:             ={  savebc();
     523:                 if( !reached ) werror("loop not entered at top");
     524:                 brklab = getlab();
     525:                 contlab = getlab();
     526:                 deflab( $$ = getlab() );
     527:                 reached = 1;
     528:                 }
     529:         ;
     530: ifprefix:   IF LP e RP
     531:             ={  ecomp( buildtree( CBRANCH, $3, bcon( $$=getlab()) ) ) ;
     532:                 reached = 1;
     533:                 }
     534:         ;
     535: ifelprefix:   ifprefix statement ELSE
     536:             ={  if( reached ) branch( $$ = getlab() );
     537:                 else $$ = NOLAB;
     538:                 deflab( $1 );
     539:                 reached = 1;
     540:                 }
     541:         ;
     542:
     543: whprefix:     WHILE  LP  e  RP
     544:             ={  savebc();
     545:                 if( !reached ) werror("loop not entered at top");
     546:                 if( $3->in.op == ICON && $3->tn.lval != 0 ) flostat = FLOOP;
     547:                 deflab( contlab = getlab() );
     548:                 reached = 1;
     549:                 brklab = getlab();
     550:                 if( flostat == FLOOP ) tfree( $3 );
     551:                 else ecomp( buildtree( CBRANCH, $3, bcon( brklab) ) );
     552:                 }
     553:         ;
     554: forprefix:    FOR  LP  .e  SM .e  SM
     555:             ={  if( $3 ) ecomp( $3 );
     556:                 else if( !reached ) werror("loop not entered at top");
     557:                 savebc();
     558:                 contlab = getlab();
     559:                 brklab = getlab();
     560:                 deflab( $$ = getlab() );
     561:                 reached = 1;
     562:                 if( $5 ) ecomp( buildtree( CBRANCH, $5, bcon( brklab) ) );
     563:                 else flostat |= FLOOP;
     564:                 }
     565:         ;
     566: switchpart:    SWITCH  LP  e  RP
     567:             ={  register NODE *q;
     568:
     569:                 savebc();
     570:                 brklab = getlab();
     571:                 q = $3;
     572:                 switch( q->in.type ) {
     573:                 case CHAR:  case UCHAR:
     574:                 case SHORT: case USHORT:
     575:                 case INT:   case UNSIGNED:
     576:                 case MOE:   case ENUMTY:
     577:                     break;
     578:                 default:
     579:                 werror("switch expression not type int");
     580:                 q = makety( q, INT, q->fn.cdim, q->fn.csiz );
     581:                 }
     582:                 ecomp( buildtree( FORCE, q, NIL ) );
     583:                 branch( $$ = getlab() );
     584:                 swstart();
     585:                 reached = 0;
     586:                 }
     587:         ;
     588: /*	EXPRESSIONS	*/
     589: con_e:         { $<intval>$=instruct; stwart=instruct=0; } e
     590:             %prec CM
     591:             ={  $$ = icons( $2 );  instruct=$<intval>1; }
     592:         ;
     593: .e:        e
     594:         |
     595:             ={ $$=0; }
     596:         ;
     597: elist:         e
     598:             %prec CM
     599:         |  elist  CM  e
     600:             ={  goto bop; }
     601:         ;
     602:
     603: e:         e RELOP e
     604:             ={
     605:             preconf:
     606:                 if( yychar==RELOP||yychar==EQUOP||yychar==AND||yychar==OR||yychar==ER ){
     607:                 precplaint:
     608:                 if( hflag ) werror("precedence confusion possible: parenthesize!" );
     609:                 }
     610:             bop:
     611:                 $$ = buildtree( $2, $1, $3 );
     612:                 }
     613:         |  e CM e
     614:             ={  $2 = COMOP;
     615:                 goto bop;
     616:                 }
     617:         |  e DIVOP e
     618:             ={  goto bop; }
     619:         |  e PLUS e
     620:             ={  if(yychar==SHIFTOP) goto precplaint; else goto bop; }
     621:         |  e MINUS e
     622:             ={  if(yychar==SHIFTOP ) goto precplaint; else goto bop; }
     623:         |  e SHIFTOP e
     624:             ={  if(yychar==PLUS||yychar==MINUS) goto precplaint; else goto bop; }
     625:         |  e MUL e
     626:             ={  goto bop; }
     627:         |  e EQUOP  e
     628:             ={  goto preconf; }
     629:         |  e AND e
     630:             ={  if( yychar==RELOP||yychar==EQUOP ) goto preconf;  else goto bop; }
     631:         |  e OR e
     632:             ={  if(yychar==RELOP||yychar==EQUOP) goto preconf; else goto bop; }
     633:         |  e ER e
     634:             ={  if(yychar==RELOP||yychar==EQUOP) goto preconf; else goto bop; }
     635:         |  e ANDAND e
     636:             ={  goto bop; }
     637:         |  e OROR e
     638:             ={  goto bop; }
     639:         |  e MUL ASSIGN e
     640:             ={  abop:
     641:                 $$ = buildtree( ASG $2, $1, $4 );
     642:                 }
     643:         |  e DIVOP ASSIGN e
     644:             ={  goto abop; }
     645:         |  e PLUS ASSIGN e
     646:             ={  goto abop; }
     647:         |  e MINUS ASSIGN e
     648:             ={  goto abop; }
     649:         |  e SHIFTOP ASSIGN e
     650:             ={  goto abop; }
     651:         |  e AND ASSIGN e
     652:             ={  goto abop; }
     653:         |  e OR ASSIGN e
     654:             ={  goto abop; }
     655:         |  e ER ASSIGN e
     656:             ={  goto abop; }
     657:         |  e QUEST e COLON e
     658:             ={  $$=buildtree(QUEST, $1, buildtree( COLON, $3, $5 ) );
     659:                 }
     660:         |  e ASOP e
     661:             ={  werror("old-fashioned assignment operator" );  goto bop; }
     662:         |  e ASSIGN e
     663:             ={  goto bop; }
     664:         |  term
     665:         ;
     666: term:          term INCOP
     667:             ={  $$ = buildtree( $2, $1, bcon(1) ); }
     668:         |  MUL term
     669:             ={ ubop:
     670:                 $$ = buildtree( UNARY $1, $2, NIL );
     671:                 }
     672:         |  AND term
     673:             ={  if( ISFTN($2->in.type) || ISARY($2->in.type) ){
     674:                 werror("& before array or function: ignored" );
     675:                 $$ = $2;
     676:                 }
     677:                 else goto ubop;
     678:                 }
     679:         |  MINUS term
     680:             ={  goto ubop; }
     681:         |  UNOP term
     682:             ={
     683:                 $$ = buildtree( $1, $2, NIL );
     684:                 }
     685:         |  INCOP term
     686:             ={  $$ = buildtree( $1==INCR ? ASG PLUS : ASG MINUS,
     687:                         $2,
     688:                         bcon(1)  );
     689:                 }
     690:         |  SIZEOF term
     691:             ={  $$ = doszof( $2 ); }
     692:         |  LP cast_type RP term  %prec INCOP
     693:             ={  $$ = buildtree( CAST, $2, $4 );
     694:                 $$->in.left->in.op = FREE;
     695:                 $$->in.op = FREE;
     696:                 $$ = $$->in.right;
     697:                 }
     698:         |  SIZEOF LP cast_type RP  %prec SIZEOF
     699:             ={  $$ = doszof( $3 ); }
     700:         |  term LB e RB
     701:             ={  $$ = buildtree( UNARY MUL, buildtree( PLUS, $1, $3 ), NIL ); }
     702:         |  funct_idn  RP
     703:             ={  $$=buildtree(UNARY CALL,$1,NIL); }
     704:         |  funct_idn elist  RP
     705:             ={  $$=buildtree(CALL,$1,$2); }
     706:         |  term STROP NAME
     707:             ={  if( $2 == DOT ){
     708:                 if( notlval( $1 ) )uerror("structure reference must be addressable");
     709:                 $1 = buildtree( UNARY AND, $1, NIL );
     710:                 }
     711:                 idname = $3;
     712:                 $$ = buildtree( STREF, $1, buildtree( NAME, NIL, NIL ) );
     713:                 }
     714:         |  NAME
     715:             ={  idname = $1;
     716:                 /* recognize identifiers in initializations */
     717:                 if( blevel==0 && stab[idname].stype == UNDEF ) {
     718:                 register NODE *q;
     719: #ifndef FLEXNAMES
     720:                 werror("undeclared initializer name %.8s", stab[idname].sname );
     721: #else
     722:                 werror("undeclared initializer name %s", stab[idname].sname );
     723: #endif
     724:                 q = block( FREE, NIL, NIL, INT, 0, INT );
     725:                 q->tn.rval = idname;
     726:                 defid( q, EXTERN );
     727:                 }
     728:                 $$=buildtree(NAME,NIL,NIL);
     729:                 stab[$1].suse = -lineno;
     730:             }
     731:         |  ICON
     732:             ={  $$=bcon(0);
     733:                 $$->tn.lval = lastcon;
     734:                 $$->tn.rval = NONAME;
     735:                 if( $1 ) $$->fn.csiz = $$->in.type = ctype(LONG);
     736:                 }
     737:         |  FCON
     738:             ={  $$=buildtree(FCON,NIL,NIL);
     739:                 $$->fpn.fval = fcon;
     740:                 }
     741:         |  DCON
     742:             ={  $$=buildtree(DCON,NIL,NIL);
     743:                 $$->dpn.dval = dcon;
     744:                 }
     745:         |  STRING
     746:             ={  $$ = getstr(); /* get string contents */ }
     747:         |   LP  e  RP
     748:             ={ $$=$2; }
     749:         ;
     750:
     751: cast_type:    type null_decl
     752:             ={
     753:             $$ = tymerge( $1, $2 );
     754:             $$->in.op = NAME;
     755:             $1->in.op = FREE;
     756:             }
     757:         ;
     758:
     759: null_decl:     /* empty */
     760:             ={ $$ = bdty( NAME, NIL, -1 ); }
     761:         |  LP RP
     762:             ={ $$ = bdty( UNARY CALL, bdty(NAME,NIL,-1),0); }
     763:         |  LP null_decl RP LP RP
     764:             ={  $$ = bdty( UNARY CALL, $2, 0 ); }
     765:         |  MUL null_decl
     766:             ={  goto umul; }
     767:         |  null_decl LB RB
     768:             ={  goto uary; }
     769:         |  null_decl LB con_e RB
     770:             ={  goto bary;  }
     771:         |  LP null_decl RP
     772:             ={ $$ = $2; }
     773:         ;
     774:
     775: funct_idn:     NAME  LP
     776:             ={  if( stab[$1].stype == UNDEF ){
     777:                 register NODE *q;
     778:                 q = block( FREE, NIL, NIL, FTN|INT, 0, INT );
     779:                 q->tn.rval = $1;
     780:                 defid( q, EXTERN );
     781:                 }
     782:                 idname = $1;
     783:                 $$=buildtree(NAME,NIL,NIL);
     784:                 stab[idname].suse = -lineno;
     785:             }
     786:         |  term  LP
     787:         ;
     788: %%
     789:
     790: NODE *
     791: mkty( t, d, s ) unsigned t; {
     792:     return( block( TYPE, NIL, NIL, t, d, s ) );
     793:     }
     794:
     795: NODE *
     796: bdty( op, p, v ) NODE *p; {
     797:     register NODE *q;
     798:
     799:     q = block( op, p, NIL, INT, 0, INT );
     800:
     801:     switch( op ){
     802:
     803:     case UNARY MUL:
     804:     case UNARY CALL:
     805:         break;
     806:
     807:     case LB:
     808:         q->in.right = bcon(v);
     809:         break;
     810:
     811:     case NAME:
     812:         q->tn.rval = v;
     813:         break;
     814:
     815:     default:
     816:         cerror("bad bdty" );
     817:         }
     818:
     819:     return( q );
     820:     }
     821:
     822: dstash( n ) OFFSZ n;{ /* put n into the dimension table */
     823:     if( curdim >= DIMTABSZ-1 ){
     824:         cerror("dimension table overflow");
     825:         }
     826:     dimtab[ curdim++ ] = n;
     827:     }
     828:
     829: savebc() {
     830:     if( psavbc > & asavbc[BCSZ-4 ] ){
     831:         cerror("whiles, fors, etc. too deeply nested");
     832:         }
     833:     *psavbc++ = brklab;
     834:     *psavbc++ = contlab;
     835:     *psavbc++ = flostat;
     836:     *psavbc++ = swx;
     837:     flostat = 0;
     838:     }
     839:
     840: resetbc(mask){
     841:
     842:     swx = *--psavbc;
     843:     flostat = *--psavbc | (flostat&mask);
     844:     contlab = *--psavbc;
     845:     brklab = *--psavbc;
     846:
     847:     }
     848:
     849: addcase(p) NODE *p; { /* add case to switch */
     850:
     851:     p = optim( p );  /* change enum to ints */
     852:     if( p->in.op != ICON ){
     853:         uerror("non-constant case expression");
     854:         return;
     855:         }
     856:     if( swp == swtab ){
     857:         uerror("case not in switch");
     858:         return;
     859:         }
     860:     if( swp >= &swtab[SWITSZ] ){
     861:         cerror("switch table overflow");
     862:         }
     863:     swp->sval = p->tn.lval;
     864:     deflab( swp->slab = getlab() );
     865:     ++swp;
     866:     tfree(p);
     867:     }
     868:
     869: adddef(){ /* add default case to switch */
     870:     if( swtab[swx].slab >= 0 ){
     871:         uerror("duplicate default in switch");
     872:         return;
     873:         }
     874:     if( swp == swtab ){
     875:         uerror("default not inside switch");
     876:         return;
     877:         }
     878:     deflab( swtab[swx].slab = getlab() );
     879:     }
     880:
     881: swstart(){
     882:     /* begin a switch block */
     883:     if( swp >= &swtab[SWITSZ] ){
     884:         cerror("switch table overflow");
     885:         }
     886:     swx = swp - swtab;
     887:     swp->slab = -1;
     888:     ++swp;
     889:     }
     890:
     891: swend(){ /* end a switch block */
     892:
     893:     register struct sw *swbeg, *p, *q, *r, *r1;
     894:     CONSZ temp;
     895:     int tempi;
     896:
     897:     swbeg = &swtab[swx+1];
     898:
     899:     /* sort */
     900:
     901:     r1 = swbeg;
     902:     r = swp-1;
     903:
     904:     while( swbeg < r ){
     905:         /* bubble largest to end */
     906:         for( q=swbeg; q<r; ++q ){
     907:             if( q->sval > (q+1)->sval ){
     908:                 /* swap */
     909:                 r1 = q+1;
     910:                 temp = q->sval;
     911:                 q->sval = r1->sval;
     912:                 r1->sval = temp;
     913:                 tempi = q->slab;
     914:                 q->slab = r1->slab;
     915:                 r1->slab = tempi;
     916:                 }
     917:             }
     918:         r = r1;
     919:         r1 = swbeg;
     920:         }
     921:
     922:     /* it is now sorted */
     923:
     924:     for( p = swbeg+1; p<swp; ++p ){
     925:         if( p->sval == (p-1)->sval ){
     926:             uerror("duplicate case in switch, %d", tempi=p->sval );
     927:             return;
     928:             }
     929:         }
     930:
     931:     genswitch( swbeg-1, swp-swbeg );
     932:     swp = swbeg-1;
     933:     }

#### Defined functions

_addcase defined in line 849; used 1 times

- in line 512

_adddef defined in line 869; used 1 times

- in line 517

_bdty defined in line 795; used 16 times

- in line 213-215(2), 255-267(5), 284-289(4), 760-764(4)
- in /usr/src/lib/mip/pass1.h line 173

_dstash defined in line 822; used 12 times

- in /usr/src/lib/mip/pftn.c line 306-309(4), 557-560(4), 584, 611, 1502, 1542

_mkty defined in line 788; used 7 times

- in line 132, 138
- in /usr/src/lib/mip/pass1.h line 174
- in /usr/src/lib/mip/pftn.c line 494, 651
- in /usr/src/lib/mip/scan.c line 538, 927

_resetbc defined in line 840; used 4 times

- in line 425, 433, 443, 451

_savebc defined in line 829; used 4 times

- in line 522, 544, 557, 569

_swend defined in line 891; used 1 times

- in line 448

_swstart defined in line 881; used 1 times

- in line 584

Last modified: 1995-01-18 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1938 |