1: # include "mfile1"
   2: 
   3: struct instk {
   4:     int in_sz;   /* size of array element */
   5:     int in_x;    /* current index for structure member in structure initializations */
   6:     int in_n;    /* number of initializations seen */
   7:     int in_s;    /* sizoff */
   8:     int in_d;    /* dimoff */
   9:     TWORD in_t;    /* type */
  10:     int in_id;   /* stab index */
  11:     int in_fl;   /* flag which says if this level is controlled by {} */
  12:     OFFSZ in_off;  /* offset of the beginning of this level */
  13:     }
  14: instack[10],
  15: *pstk;
  16: 
  17:     /* defines used for getting things off of the initialization stack */
  18: 
  19: 
  20: struct symtab *relook();
  21: 
  22: 
  23: int ddebug = 0;
  24: 
  25: defid( q, class )  NODE *q; {
  26:     register struct symtab *p;
  27:     int idp;
  28:     TWORD type;
  29:     TWORD stp;
  30:     int scl;
  31:     int dsym, ddef;
  32:     int slev, temp;
  33: 
  34:     if( q == NIL ) return;  /* an error was detected */
  35: 
  36:     if( q < node || q >= &node[TREESZ] ) cerror( "defid call" );
  37: 
  38:     idp = q->rval;
  39: 
  40:     if( idp < 0 ) cerror( "tyreduce" );
  41:     p = &stab[idp];
  42: 
  43:     if( ddebug ){
  44:         printf( "defid( %.8s (%d), ", p->sname, idp );
  45:         tprint( q->type );
  46:         printf( ", %s, (%d,%d) ), level %d\n", scnames(class), q->cdim, q->csiz, blevel );
  47:         }
  48: 
  49:     fixtype( q, class );
  50: 
  51:     type = q->type;
  52:     class = fixclass( class, type );
  53: 
  54:     stp = p->stype;
  55:     slev = p->slevel;
  56: 
  57:     if( ddebug ){
  58:         printf( "	modified to " );
  59:         tprint( type );
  60:         printf( ", %s\n", scnames(class) );
  61:         printf( "	previous def'n: " );
  62:         tprint( stp );
  63:         printf( ", %s, (%d,%d) ), level %d\n", scnames(p->sclass), p->dimoff, p->sizoff, slev );
  64:         }
  65: 
  66:     if( stp == UNDEF|| stp == FARG ){
  67:         if( blevel==1 && stp!=FARG ) switch( class ){
  68: 
  69:         default:
  70:             if(!(class&FIELD)) uerror( "declared argument %.8s is missing", p->sname );
  71:         case MOS:
  72:         case STNAME:
  73:         case MOU:
  74:         case UNAME:
  75:         case MOE:
  76:         case ENAME:
  77:         case TYPEDEF:
  78:             ;
  79:             }
  80:         goto enter;
  81:         }
  82:     if( type != stp ) goto mismatch;
  83:     /* test (and possibly adjust) dimensions */
  84:     dsym = p->dimoff;
  85:     ddef = q->cdim;
  86:     for( temp=type; temp&TMASK; temp = DECREF(temp) ){
  87:         if( ISARY(temp) ){
  88:             if( dimtab[dsym] == 0 ) dimtab[dsym] = dimtab[ddef];
  89:             else if( dimtab[ddef]!=0 && dimtab[dsym] != dimtab[ddef] ){
  90:                 goto mismatch;
  91:                 }
  92:             ++dsym;
  93:             ++ddef;
  94:             }
  95:         }
  96: 
  97:     /* check that redeclarations are to the same structure */
  98:     if( (temp==STRTY||temp==UNIONTY||temp==ENUMTY) && p->sizoff != q->csiz && (type&TMASK) ) {
  99:         goto mismatch;
 100:         }
 101: 
 102:     scl = ( p->sclass );
 103: 
 104:     if( ddebug ){
 105:         printf( "	previous class: %s\n", scnames(scl) );
 106:         }
 107: 
 108:     if( class&FIELD ){
 109:         /* redefinition */
 110:         if( !falloc( p, class&FLDSIZ, 1, NIL ) ) {
 111:             /* successful allocation */
 112:             psave( idp );
 113:             return;
 114:             }
 115:         /* blew it: resume at end of switch... */
 116:         }
 117: 
 118:     else switch( class ){
 119: 
 120:     case EXTERN:
 121:         switch( scl ){
 122:         case STATIC:
 123:         case USTATIC:
 124:             if( slev==0 ) return;
 125:             break;
 126:         case EXTDEF:
 127:         case EXTERN:
 128:         case FORTRAN:
 129:         case UFORTRAN:
 130:             return;
 131:             }
 132:         break;
 133: 
 134:     case STATIC:
 135:         if( scl==USTATIC || (scl==EXTERN && blevel==0) ){
 136:             p->sclass = STATIC;
 137:             if( ISFTN(type) ) curftn = idp;
 138:             return;
 139:             }
 140:         break;
 141: 
 142:     case USTATIC:
 143:         if( scl==STATIC || scl==USTATIC ) return;
 144:         break;
 145: 
 146:     case LABEL:
 147:         if( scl == ULABEL ){
 148:             p->sclass = LABEL;
 149:             deflab( p->offset );
 150:             return;
 151:             }
 152:         break;
 153: 
 154:     case TYPEDEF:
 155:         if( scl == class ) return;
 156:         break;
 157: 
 158:     case UFORTRAN:
 159:         if( scl == UFORTRAN || scl == FORTRAN ) return;
 160:         break;
 161: 
 162:     case FORTRAN:
 163:         if( scl == UFORTRAN ){
 164:             p->sclass = FORTRAN;
 165:             if( ISFTN(type) ) curftn = idp;
 166:             return;
 167:             }
 168:         break;
 169: 
 170:     case MOU:
 171:     case MOS:
 172:         if( scl == class ) {
 173:             if( oalloc( p, &strucoff ) ) break;
 174:             if( class == MOU ) strucoff = 0;
 175:             psave( idp );
 176:             return;
 177:             }
 178:         break;
 179: 
 180:     case MOE:
 181:         if( scl == class ){
 182:             if( p->offset!= strucoff++ ) break;
 183:             psave( idp );
 184:             }
 185:         break;
 186: 
 187:     case EXTDEF:
 188:         if( scl == EXTERN ) {
 189:             p->sclass = EXTDEF;
 190:             if( ISFTN(type) ) curftn = idp;
 191:             return;
 192:             }
 193:         break;
 194: 
 195:     case STNAME:
 196:     case UNAME:
 197:     case ENAME:
 198:         if( scl != class ) break;
 199:         if( dimtab[p->sizoff] == 0 ) return;  /* previous entry just a mention */
 200:         break;
 201: 
 202:     case ULABEL:
 203:         if( scl == LABEL || scl == ULABEL ) return;
 204:     case PARAM:
 205:     case AUTO:
 206:     case REGISTER:
 207:         ;  /* mismatch.. */
 208: 
 209:         }
 210: 
 211:     mismatch:
 212:     if( blevel > slev && class != EXTERN && class != FORTRAN &&
 213:         class != UFORTRAN && !( class == LABEL && slev >= 2 ) ){
 214:         q->rval = idp = hide( p );
 215:         p = &stab[idp];
 216:         goto enter;
 217:         }
 218:     uerror( "redeclaration of %.8s", p->sname );
 219:     if( class==EXTDEF && ISFTN(type) ) curftn = idp;
 220:     return;
 221: 
 222:     enter:  /* make a new entry */
 223: 
 224:     if( ddebug ) printf( "	new entry made\n" );
 225:     p->stype = type;
 226:     p->sclass = class;
 227:     p->slevel = blevel;
 228:     p->offset = NOOFFSET;
 229:     p->suse = lineno;
 230:     if( class == STNAME || class == UNAME || class == ENAME ) {
 231:         p->sizoff = curdim;
 232:         dstash( 0 );  /* size */
 233:         dstash( -1 ); /* index to members of str or union */
 234:         dstash( ALSTRUCT );  /* alignment */
 235:         }
 236:     else {
 237:         switch( BTYPE(type) ){
 238:         case STRTY:
 239:         case UNIONTY:
 240:         case ENUMTY:
 241:             p->sizoff = q->csiz;
 242:             break;
 243:         default:
 244:             p->sizoff = BTYPE(type);
 245:             }
 246:         }
 247: 
 248:     /* copy dimensions */
 249: 
 250:     p->dimoff = q->cdim;
 251: 
 252:     /* allocate offsets */
 253:     if( class&FIELD ){
 254:         falloc( p, class&FLDSIZ, 0, NIL );  /* new entry */
 255:         psave( idp );
 256:         }
 257:     else switch( class ){
 258: 
 259:     case AUTO:
 260:         oalloc( p, &autooff );
 261:         break;
 262:     case STATIC:
 263:     case EXTDEF:
 264:         p->offset = getlab();
 265:         if( ISFTN(type) ) curftn = idp;
 266:         break;
 267:     case ULABEL:
 268:     case LABEL:
 269:         p->offset = getlab();
 270:         p->slevel = 2;
 271:         if( class == LABEL ){
 272:             locctr( PROG );
 273:             deflab( p->offset );
 274:             }
 275:         break;
 276: 
 277:     case EXTERN:
 278:     case UFORTRAN:
 279:     case FORTRAN:
 280:         p->offset = getlab();
 281:         p->slevel = 0;
 282:         break;
 283:     case MOU:
 284:     case MOS:
 285:         oalloc( p, &strucoff );
 286:         if( class == MOU ) strucoff = 0;
 287:         psave( idp );
 288:         break;
 289: 
 290:     case MOE:
 291:         p->offset = strucoff++;
 292:         psave( idp );
 293:         break;
 294:     case REGISTER:
 295:         p->offset = regvar--;
 296:         if( blevel == 1 ) p->sflags |= SSET;
 297:         if( regvar < minrvar ) minrvar = regvar;
 298:         break;
 299:         }
 300: 
 301:     /* user-supplied routine to fix up new definitions */
 302: 
 303:     FIXDEF(p);
 304: 
 305:     if( ddebug ) printf( "	dimoff, sizoff, offset: %d, %d, %d\n", p->dimoff, p->sizoff, p->offset );
 306: 
 307:     }
 308: 
 309: psave( i ){
 310:     if( paramno >= PARAMSZ ){
 311:         cerror( "parameter stack overflow");
 312:         }
 313:     paramstk[ paramno++ ] = i;
 314:     }
 315: 
 316: ftnend(){ /* end of function */
 317:     if( retlab != NOLAB ){ /* inside a real function */
 318:         efcode();
 319:         }
 320:     checkst(0);
 321:     retstat = 0;
 322:     tcheck();
 323:     curclass = SNULL;
 324:     brklab = contlab = retlab = NOLAB;
 325:     flostat = 0;
 326:     if( nerrors == 0 ){
 327:         if( psavbc != & asavbc[0] ) cerror("bcsave error");
 328:         if( paramno != 0 ) cerror("parameter reset error");
 329:         if( swx != 0 ) cerror( "switch error");
 330:         }
 331:     psavbc = &asavbc[0];
 332:     paramno = 0;
 333:     autooff = AUTOINIT;
 334:     minrvar = regvar = MAXRVAR;
 335:     reached = 1;
 336:     swx = 0;
 337:     swp = swtab;
 338:     locctr(DATA);
 339:     }
 340: 
 341: dclargs(){
 342:     register i, j;
 343:     register struct symtab *p;
 344:     register NODE *q;
 345:     argoff = ARGINIT;
 346:     for( i=0; i<paramno; ++i ){
 347:         if( (j = paramstk[i]) < 0 ) continue;
 348:         p = &stab[j];
 349:         if( p->stype == FARG ) {
 350:             q = block(FREE,NIL,NIL,INT,0,INT);
 351:             q->rval = j;
 352:             defid( q, PARAM );
 353:             }
 354:         oalloc( p, &argoff );  /* always set aside space, even for register arguments */
 355:         }
 356:     cendarg();
 357:     locctr(PROG);
 358:     defalign(ALINT);
 359:     ++ftnno;
 360:     bfcode( paramstk, paramno );
 361:     paramno = 0;
 362:     }
 363: 
 364: NODE *
 365: rstruct( idn, soru ){ /* reference to a structure or union, with no definition */
 366:     register struct symtab *p;
 367:     register NODE *q;
 368:     p = &stab[idn];
 369:     switch( p->stype ){
 370: 
 371:     case UNDEF:
 372:     def:
 373:         q = block( FREE, NIL, NIL, 0, 0, 0 );
 374:         q->rval = idn;
 375:         q->type = (soru&INSTRUCT) ? STRTY : ( (soru&INUNION) ? UNIONTY : ENUMTY );
 376:         defid( q, (soru&INSTRUCT) ? STNAME : ( (soru&INUNION) ? UNAME : ENAME ) );
 377:         break;
 378: 
 379:     case STRTY:
 380:         if( soru & INSTRUCT ) break;
 381:         goto def;
 382: 
 383:     case UNIONTY:
 384:         if( soru & INUNION ) break;
 385:         goto def;
 386: 
 387:     case ENUMTY:
 388:         if( !(soru&(INUNION|INSTRUCT)) ) break;
 389:         goto def;
 390: 
 391:         }
 392:     stwart = instruct;
 393:     return( mkty( p->stype, 0, p->sizoff ) );
 394:     }
 395: 
 396: moedef( idn ){
 397:     register NODE *q;
 398: 
 399:     q = block( FREE, NIL, NIL, MOETY, 0, 0 );
 400:     q -> rval = idn;
 401:     if( idn>=0 ) defid( q, MOE );
 402:     }
 403: 
 404: bstruct( idn, soru ){ /* begining of structure or union declaration */
 405:     register NODE *q;
 406: 
 407:     psave( instruct );
 408:     psave( curclass );
 409:     psave( strucoff );
 410:     strucoff = 0;
 411:     instruct = soru;
 412:     q = block( FREE, NIL, NIL, 0, 0, 0 );
 413:     q->rval = idn;
 414:     if( instruct==INSTRUCT ){
 415:         curclass = MOS;
 416:         q->type = STRTY;
 417:         if( idn >= 0 ) defid( q, STNAME );
 418:         }
 419:     else if( instruct == INUNION ) {
 420:         curclass = MOU;
 421:         q->type = UNIONTY;
 422:         if( idn >= 0 ) defid( q, UNAME );
 423:         }
 424:     else { /* enum */
 425:         curclass = MOE;
 426:         q->type = ENUMTY;
 427:         if( idn >= 0 ) defid( q, ENAME );
 428:         }
 429:     psave( q->rval );
 430:     return( paramno-4 );
 431:     }
 432: 
 433: NODE *
 434: dclstruct( oparam ){
 435:     register struct symtab *p;
 436:     register i, al, sa, j, sz, szindex;
 437:     register TWORD temp;
 438:     register high, low;
 439: 
 440:     /* paramstack contains:
 441: 		paramstack[ oparam ] = previous instruct
 442: 		paramstack[ oparam+1 ] = previous class
 443: 		paramstk[ oparam+2 ] = previous strucoff
 444: 		paramstk[ oparam+3 ] = structure name
 445: 
 446: 		paramstk[ oparam+4, ... ]  = member stab indices
 447: 
 448: 		*/
 449: 
 450: 
 451:     if( (i=paramstk[oparam+3]) < 0 ){
 452:         szindex = curdim;
 453:         dstash( 0 );  /* size */
 454:         dstash( -1 );  /* index to member names */
 455:         dstash( ALSTRUCT );  /* alignment */
 456:         }
 457:     else {
 458:         szindex = stab[i].sizoff;
 459:         }
 460: 
 461:     if( ddebug ){
 462:         printf( "dclstruct( %.8s ), szindex = %d\n", (i>=0)? stab[i].sname : "??", szindex );
 463:         }
 464:     temp = (instruct&INSTRUCT)?STRTY:((instruct&INUNION)?UNIONTY:ENUMTY);
 465:     stwart = instruct = paramstk[ oparam ];
 466:     curclass = paramstk[ oparam+1 ];
 467:     dimtab[ szindex+1 ] = curdim;
 468:     al = ALSTRUCT;
 469: 
 470:     high = low = 0;
 471: 
 472:     for( i = oparam+4;  i< paramno; ++i ){
 473:         dstash( j=paramstk[i] );
 474:         if( j<0 || j>= SYMTSZ ) cerror( "gummy structure member" );
 475:         p = &stab[j];
 476:         if( temp == ENUMTY ){
 477:             if( p->offset < low ) low = p->offset;
 478:             if( p->offset > high ) high = p->offset;
 479:             p->sizoff = szindex;
 480:             continue;
 481:             }
 482:         sa = talign( p->stype, p->sizoff );
 483:         if( p->sclass & FIELD ){
 484:             sz = p->sclass&FLDSIZ;
 485:             }
 486:         else {
 487:             sz = tsize( p->stype, p->dimoff, p->sizoff );
 488:             }
 489:         if( sz == 0 ){
 490:             uerror( "illegal zero sized structure member: %.8s", p->sname );
 491:             }
 492:         if( sz > strucoff ) strucoff = sz;  /* for use with unions */
 493:         SETOFF( al, sa );
 494:         /* set al, the alignment, to the lcm of the alignments of the members */
 495:         }
 496:     dstash( -1 );  /* endmarker */
 497:     SETOFF( strucoff, al );
 498: 
 499:     if( temp == ENUMTY ){
 500:         register TWORD ty;
 501: 
 502: # ifdef ENUMSIZE
 503:         ty = ENUMSIZE(high,low);
 504: # else
 505:         if( (char)high == high && (char)low == low ) ty = ctype( CHAR );
 506:         else if( (short)high == high && (short)low == low ) ty = ctype( SHORT );
 507:         else ty = ctype(INT);
 508: #endif
 509:         strucoff = tsize( ty, 0, (int)ty );
 510:         dimtab[ szindex+2 ] = al = talign( ty, (int)ty );
 511:         }
 512: 
 513:     if( strucoff == 0 ) uerror( "zero sized structure" );
 514:     dimtab[ szindex ] = strucoff;
 515:     dimtab[ szindex+2 ] = al;
 516: 
 517:     if( ddebug>1 ){
 518:         printf( "\tdimtab[%d,%d,%d] = %d,%d,%d\n", szindex,szindex+1,szindex+2,
 519:                 dimtab[szindex],dimtab[szindex+1],dimtab[szindex+2] );
 520:         for( i = dimtab[szindex+1]; dimtab[i] >= 0; ++i ){
 521:             printf( "\tmember %.8s(%d)\n", stab[dimtab[i]].sname, dimtab[i] );
 522:             }
 523:         }
 524: 
 525:     strucoff = paramstk[ oparam+2 ];
 526:     paramno = oparam;
 527: 
 528:     return( mkty( temp, 0, szindex ) );
 529:     }
 530: 
 531:     /* VARARGS */
 532: yyerror( s ) char *s; { /* error printing routine in parser */
 533: 
 534:     uerror( s );
 535: 
 536:     }
 537: 
 538: yyaccpt(){
 539:     ftnend();
 540:     }
 541: 
 542: ftnarg( idn ) {
 543:     if( stab[idn].stype != UNDEF ){
 544:         idn = hide( &stab[idn]);
 545:         }
 546:     stab[idn].stype = FARG;
 547:     stab[idn].sclass = PARAM;
 548:     psave( idn );
 549:     }
 550: 
 551: talign( ty, s) register unsigned ty; register s; {
 552:     /* compute the alignment of an object with type ty, sizeoff index s */
 553: 
 554:     register i;
 555:     if( s<0 && ty!=INT && ty!=CHAR && ty!=SHORT && ty!=UNSIGNED && ty!=UCHAR && ty!=USHORT
 556: #ifdef LONGFIELDS
 557:         && ty!=LONG && ty!=ULONG
 558: #endif
 559:                     ){
 560:         return( fldal( ty ) );
 561:         }
 562: 
 563:     for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){
 564:         switch( (ty>>i)&TMASK ){
 565: 
 566:         case FTN:
 567:             cerror( "compiler takes alignment of function");
 568:         case PTR:
 569:             return( ALPOINT );
 570:         case ARY:
 571:             continue;
 572:         case 0:
 573:             break;
 574:             }
 575:         }
 576: 
 577:     switch( BTYPE(ty) ){
 578: 
 579:     case UNIONTY:
 580:     case ENUMTY:
 581:     case STRTY:
 582:         return( dimtab[ s+2 ] );
 583:     case CHAR:
 584:     case UCHAR:
 585:         return( ALCHAR );
 586:     case FLOAT:
 587:         return( ALFLOAT );
 588:     case DOUBLE:
 589:         return( ALDOUBLE );
 590:     case LONG:
 591:     case ULONG:
 592:         return( ALLONG );
 593:     case SHORT:
 594:     case USHORT:
 595:         return( ALSHORT );
 596:     default:
 597:         return( ALINT );
 598:         }
 599:     }
 600: 
 601: OFFSZ
 602: tsize( ty, d, s )  TWORD ty; {
 603:     /* compute the size associated with type ty,
 604: 	    dimoff d, and sizoff s */
 605:     /* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */
 606: 
 607:     int i;
 608:     OFFSZ mult;
 609: 
 610:     mult = 1;
 611: 
 612:     for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){
 613:         switch( (ty>>i)&TMASK ){
 614: 
 615:         case FTN:
 616:             cerror( "compiler takes size of function");
 617:         case PTR:
 618:             return( SZPOINT * mult );
 619:         case ARY:
 620:             mult *= dimtab[ d++ ];
 621:             continue;
 622:         case 0:
 623:             break;
 624: 
 625:             }
 626:         }
 627: 
 628:     if( dimtab[s]==0 ) {
 629:         uerror( "unknown size");
 630:         return( SZINT );
 631:         }
 632:     return( dimtab[ s ] * mult );
 633:     }
 634: 
 635: inforce( n ) OFFSZ n; {  /* force inoff to have the value n */
 636:     /* inoff is updated to have the value n */
 637:     OFFSZ wb;
 638:     register rest;
 639:     /* rest is used to do a lot of conversion to ints... */
 640: 
 641:     if( inoff == n ) return;
 642:     if( inoff > n ) {
 643:         cerror( "initialization alignment error");
 644:         }
 645: 
 646:     wb = inoff;
 647:     SETOFF( wb, SZINT );
 648: 
 649:     /* wb now has the next higher word boundary */
 650: 
 651:     if( wb >= n ){ /* in the same word */
 652:         rest = n - inoff;
 653:         vfdzero( rest );
 654:         return;
 655:         }
 656: 
 657:     /* otherwise, extend inoff to be word aligned */
 658: 
 659:     rest = wb - inoff;
 660:     vfdzero( rest );
 661: 
 662:     /* now, skip full words until near to n */
 663: 
 664:     rest = (n-inoff)/SZINT;
 665:     zecode( rest );
 666: 
 667:     /* now, the remainder of the last word */
 668: 
 669:     rest = n-inoff;
 670:     vfdzero( rest );
 671:     if( inoff != n ) cerror( "inoff error");
 672: 
 673:     }
 674: 
 675: vfdalign( n ){ /* make inoff have the offset the next alignment of n */
 676:     OFFSZ m;
 677: 
 678:     m = inoff;
 679:     SETOFF( m, n );
 680:     inforce( m );
 681:     }
 682: 
 683: 
 684: int idebug = 0;
 685: 
 686: int ibseen = 0;  /* the number of } constructions which have been filled */
 687: 
 688: int iclass;  /* storage class of thing being initialized */
 689: 
 690: int ilocctr = 0;  /* location counter for current initialization */
 691: 
 692: beginit(curid){
 693:     /* beginning of initilization; set location ctr and set type */
 694:     register struct symtab *p;
 695: 
 696:     if( idebug >= 3 ) printf( "beginit(), curid = %d\n", curid );
 697: 
 698:     p = &stab[curid];
 699: 
 700:     iclass = p->sclass;
 701:     if( curclass == EXTERN || curclass == FORTRAN ) iclass = EXTERN;
 702:     switch( iclass ){
 703: 
 704:     case UNAME:
 705:     case EXTERN:
 706:         return;
 707:     case AUTO:
 708:     case REGISTER:
 709:         break;
 710:     case EXTDEF:
 711:     case STATIC:
 712:         ilocctr = ISARY(p->stype)?ADATA:DATA;
 713:         locctr( ilocctr );
 714:         defalign( talign( p->stype, p->sizoff ) );
 715:         defnam( p );
 716: 
 717:         }
 718: 
 719:     inoff = 0;
 720:     ibseen = 0;
 721: 
 722:     pstk = 0;
 723: 
 724:     instk( curid, p->stype, p->dimoff, p->sizoff, inoff );
 725: 
 726:     }
 727: 
 728: instk( id, t, d, s, off ) OFFSZ off; TWORD t; {
 729:     /* make a new entry on the parameter stack to initialize id */
 730: 
 731:     register struct symtab *p;
 732: 
 733:     for(;;){
 734:         if( idebug ) printf( "instk((%d, %o,%d,%d, %d)\n", id, t, d, s, off );
 735: 
 736:         /* save information on the stack */
 737: 
 738:         if( !pstk ) pstk = instack;
 739:         else ++pstk;
 740: 
 741:         pstk->in_fl = 0;    /* { flag */
 742:         pstk->in_id =  id ;
 743:         pstk->in_t =  t ;
 744:         pstk->in_d =  d ;
 745:         pstk->in_s =  s ;
 746:         pstk->in_n = 0;  /* number seen */
 747:         pstk->in_x =  t==STRTY ?dimtab[s+1] : 0 ;
 748:         pstk->in_off =  off;   /* offset at the beginning of this element */
 749:         /* if t is an array, DECREF(t) can't be a field */
 750:         /* INS_sz has size of array elements, and -size for fields */
 751:         if( ISARY(t) ){
 752:             pstk->in_sz = tsize( DECREF(t), d+1, s );
 753:             }
 754:         else if( stab[id].sclass & FIELD ){
 755:             pstk->in_sz = - ( stab[id].sclass & FLDSIZ );
 756:             }
 757:         else {
 758:             pstk->in_sz = 0;
 759:             }
 760: 
 761:         if( (iclass==AUTO || iclass == REGISTER ) &&
 762:             (ISARY(t) || t==STRTY) ) uerror( "no automatic aggregate initialization" );
 763: 
 764:         /* now, if this is not a scalar, put on another element */
 765: 
 766:         if( ISARY(t) ){
 767:             t = DECREF(t);
 768:             ++d;
 769:             continue;
 770:             }
 771:         else if( t == STRTY ){
 772:             id = dimtab[pstk->in_x];
 773:             p = &stab[id];
 774:             if( p->sclass != MOS && !(p->sclass&FIELD) ) cerror( "insane structure member list" );
 775:             t = p->stype;
 776:             d = p->dimoff;
 777:             s = p->sizoff;
 778:             off += p->offset;
 779:             continue;
 780:             }
 781:         else return;
 782:         }
 783:     }
 784: 
 785: NODE *
 786: getstr(){ /* decide if the string is external or an initializer, and get the contents accordingly */
 787: 
 788:     register l, temp;
 789:     register NODE *p;
 790: 
 791:     if( (iclass==EXTDEF||iclass==STATIC) && (pstk->in_t == CHAR || pstk->in_t == UCHAR) &&
 792:             pstk!=instack && ISARY( pstk[-1].in_t ) ){
 793:         /* treat "abc" as { 'a', 'b', 'c', 0 } */
 794:         strflg = 1;
 795:         ilbrace();  /* simulate { */
 796:         inforce( pstk->in_off );
 797:         /* if the array is inflexible (not top level), pass in the size and
 798: 			be prepared to throw away unwanted initializers */
 799:         lxstr((pstk-1)!=instack?dimtab[(pstk-1)->in_d]:0);  /* get the contents */
 800:         irbrace();  /* simulate } */
 801:         return( NIL );
 802:         }
 803:     else { /* make a label, and get the contents and stash them away */
 804:         if( iclass != SNULL ){ /* initializing */
 805:             /* fill out previous word, to permit pointer */
 806:             vfdalign( ALPOINT );
 807:             }
 808:         temp = locctr( blevel==0?ISTRNG:STRNG ); /* set up location counter */
 809:         deflab( l = getlab() );
 810:         strflg = 0;
 811:         lxstr(0); /* get the contents */
 812:         locctr( blevel==0?ilocctr:temp );
 813:         p = buildtree( STRING, NIL, NIL );
 814:         p->rval = -l;
 815:         return(p);
 816:         }
 817:     }
 818: 
 819: putbyte( v ){ /* simulate byte v appearing in a list of integer values */
 820:     register NODE *p;
 821:     p = bcon(v);
 822:     incode( p, SZCHAR );
 823:     tfree( p );
 824:     gotscal();
 825:     }
 826: 
 827: endinit(){
 828:     register TWORD t;
 829:     register d, s, n, d1;
 830: 
 831:     if( idebug ) printf( "endinit(), inoff = %d\n", inoff );
 832: 
 833:     switch( iclass ){
 834: 
 835:     case EXTERN:
 836:     case AUTO:
 837:     case REGISTER:
 838:         return;
 839:         }
 840: 
 841:     pstk = instack;
 842: 
 843:     t = pstk->in_t;
 844:     d = pstk->in_d;
 845:     s = pstk->in_s;
 846:     n = pstk->in_n;
 847: 
 848:     if( ISARY(t) ){
 849:         d1 = dimtab[d];
 850: 
 851:         vfdalign( pstk->in_sz );  /* fill out part of the last element, if needed */
 852:         n = inoff/pstk->in_sz;  /* real number of initializers */
 853:         if( d1 >= n ){
 854:             /* once again, t is an array, so no fields */
 855:             inforce( tsize( t, d, s ) );
 856:             n = d1;
 857:             }
 858:         if( d1!=0 && d1!=n ) uerror( "too many initializers");
 859:         if( n==0 ) werror( "empty array declaration");
 860:         dimtab[d] = n;
 861:         }
 862: 
 863:     else if( t == STRTY || t == UNIONTY ){
 864:         /* clearly not fields either */
 865:         inforce( tsize( t, d, s ) );
 866:         }
 867:     else if( n > 1 ) uerror( "bad scalar initialization");
 868:     /* this will never be called with a field element... */
 869:     else inforce( tsize(t,d,s) );
 870: 
 871:     paramno = 0;
 872:     vfdalign( AL_INIT );
 873:     inoff = 0;
 874:     iclass = SNULL;
 875: 
 876:     }
 877: 
 878: doinit( p ) register NODE *p; {
 879: 
 880:     /* take care of generating a value for the initializer p */
 881:     /* inoff has the current offset (last bit written)
 882: 		in the current word being generated */
 883: 
 884:     register sz, d, s;
 885:     register TWORD t;
 886: 
 887:     /* note: size of an individual initializer is assumed to fit into an int */
 888: 
 889:     if( iclass < 0 ) goto leave;
 890:     if( iclass == EXTERN || iclass == UNAME ){
 891:         uerror( "cannot initialize extern or union" );
 892:         iclass = -1;
 893:         goto leave;
 894:         }
 895: 
 896:     if( iclass == AUTO || iclass == REGISTER ){
 897:         /* do the initialization and get out, without regard
 898: 		    for filing out the variable with zeros, etc. */
 899:         bccode();
 900:         idname = pstk->in_id;
 901:         p = buildtree( ASSIGN, buildtree( NAME, NIL, NIL ), p );
 902:         ecomp(p);
 903:         return;
 904:         }
 905: 
 906:     if( p == NIL ) return;  /* for throwing away strings that have been turned into lists */
 907: 
 908:     if( ibseen ){
 909:         uerror( "} expected");
 910:         goto leave;
 911:         }
 912: 
 913:     if( idebug > 1 ) printf( "doinit(%o)\n", p );
 914: 
 915:     t = pstk->in_t;  /* type required */
 916:     d = pstk->in_d;
 917:     s = pstk->in_s;
 918:     if( pstk->in_sz < 0 ){  /* bit field */
 919:         sz = -pstk->in_sz;
 920:         }
 921:     else {
 922:         sz = tsize( t, d, s );
 923:         }
 924: 
 925:     inforce( pstk->in_off );
 926: 
 927:     p = buildtree( ASSIGN, block( NAME, NIL,NIL, t, d, s ), p );
 928:     p->left->op = FREE;
 929:     p->left = p->right;
 930:     p->right = NIL;
 931:     p->left = optim( p->left );
 932:     if( p->left->op == UNARY AND ){
 933:         p->left->op = FREE;
 934:         p->left = p->left->left;
 935:         }
 936:     p->op = INIT;
 937: 
 938:     if( sz < SZINT ){ /* special case: bit fields, etc. */
 939:         if( p->left->op != ICON ) uerror( "illegal initialization" );
 940:         else incode( p->left, sz );
 941:         }
 942:     else if( p->left->op == FCON ){
 943:         fincode( p->left->dval, sz );
 944:         }
 945:     else {
 946:         cinit( optim(p), sz );
 947:         }
 948: 
 949:     gotscal();
 950: 
 951:     leave:
 952:     tfree(p);
 953:     }
 954: 
 955: gotscal(){
 956:     register t, ix;
 957:     register n, id;
 958:     struct symtab *p;
 959:     OFFSZ temp;
 960: 
 961:     for( ; pstk > instack; ) {
 962: 
 963:         if( pstk->in_fl ) ++ibseen;
 964: 
 965:         --pstk;
 966: 
 967:         t = pstk->in_t;
 968: 
 969:         if( t == STRTY ){
 970:             ix = ++pstk->in_x;
 971:             if( (id=dimtab[ix]) < 0 ) continue;
 972: 
 973:             /* otherwise, put next element on the stack */
 974: 
 975:             p = &stab[id];
 976:             instk( id, p->stype, p->dimoff, p->sizoff, p->offset+pstk->in_off );
 977:             return;
 978:             }
 979:         else if( ISARY(t) ){
 980:             n = ++pstk->in_n;
 981:             if( n >= dimtab[pstk->in_d] && pstk > instack ) continue;
 982: 
 983:             /* put the new element onto the stack */
 984: 
 985:             temp = pstk->in_sz;
 986:             instk( pstk->in_id, (TWORD)DECREF(pstk->in_t), pstk->in_d+1, pstk->in_s,
 987:                 pstk->in_off+n*temp );
 988:             return;
 989:             }
 990: 
 991:         }
 992: 
 993:     }
 994: 
 995: ilbrace(){ /* process an initializer's left brace */
 996:     register t;
 997:     struct instk *temp;
 998: 
 999:     temp = pstk;
1000: 
1001:     for( ; pstk > instack; --pstk ){
1002: 
1003:         t = pstk->in_t;
1004:         if( t != STRTY && !ISARY(t) ) continue; /* not an aggregate */
1005:         if( pstk->in_fl ){ /* already associated with a { */
1006:             if( pstk->in_n ) uerror( "illegal {");
1007:             continue;
1008:             }
1009: 
1010:         /* we have one ... */
1011:         pstk->in_fl = 1;
1012:         break;
1013:         }
1014: 
1015:     /* cannot find one */
1016:     /* ignore such right braces */
1017: 
1018:     pstk = temp;
1019:     }
1020: 
1021: irbrace(){
1022:     /* called when a '}' is seen */
1023: 
1024:     if( idebug ) printf( "irbrace(): paramno = %d on entry\n", paramno );
1025: 
1026:     if( ibseen ) {
1027:         --ibseen;
1028:         return;
1029:         }
1030: 
1031:     for( ; pstk > instack; --pstk ){
1032:         if( !pstk->in_fl ) continue;
1033: 
1034:         /* we have one now */
1035: 
1036:         pstk->in_fl = 0;  /* cancel { */
1037:         gotscal();  /* take it away... */
1038:         return;
1039:         }
1040: 
1041:     /* these right braces match ignored left braces: throw out */
1042: 
1043:     }
1044: 
1045: upoff( size, alignment, poff ) register alignment, *poff; {
1046:     /* update the offset pointed to by poff; return the
1047: 	/* offset of a value of size `size', alignment `alignment',
1048: 	/* given that off is increasing */
1049: 
1050:     register off;
1051: 
1052:     off = *poff;
1053:     SETOFF( off, alignment );
1054:     *poff = off+size;
1055:     return( off );
1056:     }
1057: 
1058: oalloc( p, poff ) register struct symtab *p; register *poff; {
1059:     /* allocate p with offset *poff, and update *poff */
1060:     register al, off, tsz;
1061:     int noff;
1062: 
1063:     al = talign( p->stype, p->sizoff );
1064:     noff = off = *poff;
1065:     tsz = tsize( p->stype, p->dimoff, p->sizoff );
1066: #ifdef BACKAUTO
1067:     if( p->sclass == AUTO ){
1068:         noff = off + tsz;
1069:         SETOFF( noff, al );
1070:         off = -noff;
1071:         }
1072:     else
1073: #endif
1074:         if( p->sclass == PARAM && (p->stype==CHAR||p->stype==UCHAR||p->stype==SHORT||
1075:                 p->stype==USHORT) ){
1076:             off = upoff( SZINT, ALINT, &noff );
1077: # ifndef RTOLBYTES
1078:             off = noff - tsz;
1079: #endif
1080:             }
1081:         else
1082:         {
1083:         off = upoff( tsz, al, &noff );
1084:         }
1085: 
1086:     if( p->sclass != REGISTER ){ /* in case we are allocating stack space for register arguments */
1087:         if( p->offset == NOOFFSET ) p->offset = off;
1088:         else if( off != p->offset ) return(1);
1089:         }
1090: 
1091:     *poff = noff;
1092:     return(0);
1093:     }
1094: 
1095: falloc( p, w, new, pty )  register struct symtab *p; NODE *pty; {
1096:     /* allocate a field of width w */
1097:     /* new is 0 if new entry, 1 if redefinition, -1 if alignment */
1098: 
1099:     register al,sz,type;
1100: 
1101:     type = (new<0)? pty->type : p->stype;
1102: 
1103:     /* this must be fixed to use the current type in alignments */
1104:     switch( new<0?pty->type:p->stype ){
1105: 
1106:     case ENUMTY:
1107:         {
1108:             int s;
1109:             s = new<0 ? pty->csiz : p->sizoff;
1110:             al = dimtab[s+2];
1111:             sz = dimtab[s];
1112:             break;
1113:             }
1114: 
1115:     case CHAR:
1116:     case UCHAR:
1117:         al = ALCHAR;
1118:         sz = SZCHAR;
1119:         break;
1120: 
1121:     case SHORT:
1122:     case USHORT:
1123:         al = ALSHORT;
1124:         sz = SZSHORT;
1125:         break;
1126: 
1127:     case INT:
1128:     case UNSIGNED:
1129:         al = ALINT;
1130:         sz = SZINT;
1131:         break;
1132: #ifdef LONGFIELDS
1133: 
1134:     case LONG:
1135:     case ULONG:
1136:         al = ALLONG;
1137:         sz = SZLONG;
1138:         break;
1139: #endif
1140: 
1141:     default:
1142:         if( new < 0 ) {
1143:             uerror( "illegal field type" );
1144:             al = ALINT;
1145:             }
1146:         else {
1147:             al = fldal( p->stype );
1148:             sz =SZINT;
1149:             }
1150:         }
1151: 
1152:     if( w > sz ) {
1153:         uerror( "field too big");
1154:         w = sz;
1155:         }
1156: 
1157:     if( w == 0 ){ /* align only */
1158:         SETOFF( strucoff, al );
1159:         if( new >= 0 ) uerror( "zero size field");
1160:         return(0);
1161:         }
1162: 
1163:     if( strucoff%al + w > sz ) SETOFF( strucoff, al );
1164:     if( new < 0 ) {
1165:         strucoff += w;  /* we know it will fit */
1166:         return(0);
1167:         }
1168: 
1169:     /* establish the field */
1170: 
1171:     if( new == 1 ) { /* previous definition */
1172:         if( p->offset != strucoff || p->sclass != (FIELD|w) ) return(1);
1173:         }
1174:     p->offset = strucoff;
1175:     strucoff += w;
1176:     p->stype = type;
1177:     fldty( p );
1178:     return(0);
1179:     }
1180: 
1181: nidcl( p ) NODE *p; { /* handle unitialized declarations */
1182:     /* assumed to be not functions */
1183:     register class;
1184:     register commflag;  /* flag for labelled common declarations */
1185: 
1186:     commflag = 0;
1187: 
1188:     /* compute class */
1189:     if( (class=curclass) == SNULL ){
1190:         if( blevel > 1 ) class = AUTO;
1191:         else if( blevel != 0 || instruct ) cerror( "nidcl error" );
1192:         else { /* blevel = 0 */
1193:             class = noinit();
1194:             if( class == EXTERN ) commflag = 1;
1195:             }
1196:         }
1197: 
1198:     defid( p, class );
1199: 
1200:     if( class==EXTDEF || class==STATIC ){
1201:         /* simulate initialization by 0 */
1202:         beginit(p->rval);
1203:         endinit();
1204:         }
1205:     if( commflag ) commdec( p->rval );
1206:     }
1207: 
1208: TWORD
1209: types( t1, t2, t3 ) TWORD t1, t2, t3; {
1210:     /* return a basic type from basic types t1, t2, and t3 */
1211: 
1212:     TWORD t[3], noun, adj, unsg;
1213:     register i;
1214: 
1215:     t[0] = t1;
1216:     t[1] = t2;
1217:     t[2] = t3;
1218: 
1219:     unsg = INT;  /* INT or UNSIGNED */
1220:     noun = UNDEF;  /* INT, CHAR, or FLOAT */
1221:     adj = INT;  /* INT, LONG, or SHORT */
1222: 
1223:     for( i=0; i<3; ++i ){
1224:         switch( t[i] ){
1225: 
1226:         default:
1227:         bad:
1228:             uerror( "illegal type combination" );
1229:             return( INT );
1230: 
1231:         case UNDEF:
1232:             continue;
1233: 
1234:         case UNSIGNED:
1235:             if( unsg != INT ) goto bad;
1236:             unsg = UNSIGNED;
1237:             continue;
1238: 
1239:         case LONG:
1240:         case SHORT:
1241:             if( adj != INT ) goto bad;
1242:             adj = t[i];
1243:             continue;
1244: 
1245:         case INT:
1246:         case CHAR:
1247:         case FLOAT:
1248:             if( noun != UNDEF ) goto bad;
1249:             noun = t[i];
1250:             continue;
1251:             }
1252:         }
1253: 
1254:     /* now, construct final type */
1255:     if( noun == UNDEF ) noun = INT;
1256:     else if( noun == FLOAT ){
1257:         if( unsg != INT || adj == SHORT ) goto bad;
1258:         return( adj==LONG ? DOUBLE : FLOAT );
1259:         }
1260:     else if( noun == CHAR && adj != INT ) goto bad;
1261: 
1262:     /* now, noun is INT or CHAR */
1263:     if( adj != INT ) noun = adj;
1264:     if( unsg == UNSIGNED ) return( noun + (UNSIGNED-INT) );
1265:     else return( noun );
1266:     }
1267: 
1268: NODE *
1269: tymerge( typ, idp ) NODE *typ, *idp; {
1270:     /* merge type typ with identifier idp  */
1271: 
1272:     register unsigned t;
1273:     register i;
1274:     extern int eprint();
1275: 
1276:     if( typ->op != TYPE ) cerror( "tymerge: arg 1" );
1277:     if(idp == NIL ) return( NIL );
1278: 
1279:     if( ddebug > 2 ) fwalk( idp, eprint, 0 );
1280: 
1281:     idp->type = typ->type;
1282:     idp->cdim = curdim;
1283:     tyreduce( idp );
1284:     idp->csiz = typ->csiz;
1285: 
1286:     for( t=typ->type, i=typ->cdim; t&TMASK; t = DECREF(t) ){
1287:         if( ISARY(t) ) dstash( dimtab[i++] );
1288:         }
1289: 
1290:     /* now idp is a single node: fix up type */
1291: 
1292:     idp->type = ctype( idp->type );
1293: 
1294:     if( (t = BTYPE(idp->type)) != STRTY && t != UNIONTY && t != ENUMTY ){
1295:         idp->csiz = t;  /* in case ctype has rewritten things */
1296:         }
1297: 
1298:     return( idp );
1299:     }
1300: 
1301: tyreduce( p ) register NODE *p; {
1302: 
1303:     /* build a type, and stash away dimensions, from a parse tree of the declaration */
1304:     /* the type is build top down, the dimensions bottom up */
1305:     register o, temp;
1306:     register unsigned t;
1307: 
1308:     o = p->op;
1309:     p->op = FREE;
1310: 
1311:     if( o == NAME ) return;
1312: 
1313:     t = INCREF( p->type );
1314:     if( o == UNARY CALL ) t += (FTN-PTR);
1315:     else if( o == LB ){
1316:         t += (ARY-PTR);
1317:         temp = p->right->lval;
1318:         p->right->op = FREE;
1319:         }
1320: 
1321:     p->left->type = t;
1322:     tyreduce( p->left );
1323: 
1324:     if( o == LB ) dstash( temp );
1325: 
1326:     p->rval = p->left->rval;
1327:     p->type = p->left->type;
1328: 
1329:     }
1330: 
1331: fixtype( p, class ) register NODE *p; {
1332:     register unsigned t, type;
1333:     register mod1, mod2;
1334:     /* fix up the types, and check for legality */
1335: 
1336:     if( (type = p->type) == UNDEF ) return;
1337:     if( mod2 = (type&TMASK) ){
1338:         t = DECREF(type);
1339:         while( mod1=mod2, mod2 = (t&TMASK) ){
1340:             if( mod1 == ARY && mod2 == FTN ){
1341:                 uerror( "array of functions is illegal" );
1342:                 type = 0;
1343:                 }
1344:             else if( mod1 == FTN && ( mod2 == ARY || mod2 == FTN ) ){
1345:                 uerror( "function returns illegal type" );
1346:                 type = 0;
1347:                 }
1348:             t = DECREF(t);
1349:             }
1350:         }
1351: 
1352:     /* detect function arguments, watching out for structure declarations */
1353: 
1354:     if( class==SNULL && blevel==1 && !(instruct&(INSTRUCT|INUNION)) ) class = PARAM;
1355:     if( class == PARAM || ( class==REGISTER && blevel==1 ) ){
1356:         if( type == FLOAT ) type = DOUBLE;
1357:         else if( ISARY(type) ){
1358:             ++p->cdim;
1359:             type += (PTR-ARY);
1360:             }
1361:         else if( ISFTN(type) ) type = INCREF(type);
1362: 
1363:         }
1364: 
1365:     if( instruct && ISFTN(type) ){
1366:         uerror( "function illegal in structure or union" );
1367:         type = INCREF(type);
1368:         }
1369:     p->type = type;
1370:     }
1371: 
1372: uclass( class ) register class; {
1373:     /* give undefined version of class */
1374:     if( class == SNULL ) return( EXTERN );
1375:     else if( class == STATIC ) return( USTATIC );
1376:     else if( class == FORTRAN ) return( UFORTRAN );
1377:     else return( class );
1378:     }
1379: 
1380: fixclass( class, type ) TWORD type; {
1381: 
1382:     /* first, fix null class */
1383: 
1384:     if( class == SNULL ){
1385:         if( instruct&INSTRUCT ) class = MOS;
1386:         else if( instruct&INUNION ) class = MOU;
1387:         else if( blevel == 0 ) class = EXTDEF;
1388:         else if( blevel == 1 ) class = PARAM;
1389:         else class = AUTO;
1390: 
1391:         }
1392: 
1393:     /* now, do general checking */
1394: 
1395:     if( ISFTN( type ) ){
1396:         switch( class ) {
1397:         default:
1398:             uerror( "function has illegal storage class" );
1399:         case AUTO:
1400:             class = EXTERN;
1401:         case EXTERN:
1402:         case EXTDEF:
1403:         case FORTRAN:
1404:         case TYPEDEF:
1405:         case STATIC:
1406:         case UFORTRAN:
1407:         case USTATIC:
1408:             ;
1409:             }
1410:         }
1411: 
1412:     if( class&FIELD ){
1413:         if( !(instruct&INSTRUCT) ) uerror( "illegal use of field" );
1414:         return( class );
1415:         }
1416: 
1417:     switch( class ){
1418: 
1419:     case MOU:
1420:         if( !(instruct&INUNION) ) uerror( "illegal class" );
1421:         return( class );
1422: 
1423:     case MOS:
1424:         if( !(instruct&INSTRUCT) ) uerror( "illegal class" );
1425:         return( class );
1426: 
1427:     case MOE:
1428:         if( instruct & (INSTRUCT|INUNION) ) uerror( "illegal class" );
1429:         return( class );
1430: 
1431:     case REGISTER:
1432:         if( blevel == 0 ) uerror( "illegal register declaration" );
1433:         else if( regvar >= MINRVAR && cisreg( type ) ) return( class );
1434:         if( blevel == 1 ) return( PARAM );
1435:         else return( AUTO );
1436: 
1437:     case AUTO:
1438:     case LABEL:
1439:     case ULABEL:
1440:         if( blevel < 2 ) uerror( "illegal class" );
1441:         return( class );
1442: 
1443:     case PARAM:
1444:         if( blevel != 1 ) uerror( "illegal class" );
1445:         return( class );
1446: 
1447:     case UFORTRAN:
1448:     case FORTRAN:
1449: # ifdef NOFORTRAN
1450:             NOFORTRAN;    /* a condition which can regulate the FORTRAN usage */
1451: # endif
1452:         if( !ISFTN(type) ) uerror( "fortran declaration must apply to function" );
1453:         else {
1454:             type = DECREF(type);
1455:             if( ISFTN(type) || ISARY(type) || ISPTR(type) ) {
1456:                 uerror( "fortran function has wrong type" );
1457:                 }
1458:             }
1459:     case STNAME:
1460:     case UNAME:
1461:     case ENAME:
1462:     case EXTERN:
1463:     case STATIC:
1464:     case EXTDEF:
1465:     case TYPEDEF:
1466:     case USTATIC:
1467:         return( class );
1468: 
1469:     default:
1470:         cerror( "illegal class: %d", class );
1471:         /* NOTREACHED */
1472: 
1473:         }
1474:     }
1475: 
1476: lookup( name, s) char *name; {
1477:     /* look up name: must agree with s w.r.t. SMOS and SHIDDEN */
1478: 
1479:     register char *p, *q;
1480:     int i, j, ii;
1481:     register struct symtab *sp;
1482: 
1483:     /* compute initial hash index */
1484:     if( ddebug > 2 ){
1485:         printf( "lookup( %s, %d ), stwart=%d, instruct=%d\n", name, s, stwart, instruct );
1486:         }
1487: 
1488:     i = 0;
1489:     for( p=name, j=0; *p != '\0'; ++p ){
1490:         i += *p;
1491:         if( ++j >= NCHNAM ) break;
1492:         }
1493:     i = i%SYMTSZ;
1494:     sp = &stab[ii=i];
1495: 
1496:     for(;;){ /* look for name */
1497: 
1498:         if( sp->stype == TNULL ){ /* empty slot */
1499:             p = sp->sname;
1500:             sp->sflags = s;  /* set SMOS if needed, turn off all others */
1501:             for( j=0; j<NCHNAM; ++j ) if( *p++ = *name ) ++name;
1502:             sp->stype = UNDEF;
1503:             sp->sclass = SNULL;
1504:             return( i );
1505:             }
1506:         if( (sp->sflags & (SMOS|SHIDDEN)) != s ) goto next;
1507:         p = sp->sname;
1508:         q = name;
1509:         for( j=0; j<NCHNAM;++j ){
1510:             if( *p++ != *q ) goto next;
1511:             if( !*q++ ) break;
1512:             }
1513:         return( i );
1514:     next:
1515:         if( ++i >= SYMTSZ ){
1516:             i = 0;
1517:             sp = stab;
1518:             }
1519:         else ++sp;
1520:         if( i == ii ) cerror( "symbol table full" );
1521:         }
1522:     }
1523: 
1524: #ifndef checkst
1525: /* if not debugging, make checkst a macro */
1526: checkst(lev){
1527:     register int s, i, j;
1528:     register struct symtab *p, *q;
1529: 
1530:     for( i=0, p=stab; i<SYMTSZ; ++i, ++p ){
1531:         if( p->stype == TNULL ) continue;
1532:         j = lookup( p->sname, p->sflags&SMOS );
1533:         if( j != i ){
1534:             q = &stab[j];
1535:             if( q->stype == UNDEF ||
1536:                 q->slevel <= p->slevel ){
1537:                 cerror( "check error: %.8s", q->sname );
1538:                 }
1539:             }
1540:         else if( p->slevel > lev ) cerror( "%.8s check at level %d", p->sname, lev );
1541:         }
1542:     }
1543: #endif
1544: 
1545: struct symtab *
1546: relook(p) register struct symtab *p; {  /* look up p again, and see where it lies */
1547: 
1548:     register struct symtab *q;
1549: 
1550:     /* I'm not sure that this handles towers of several hidden definitions in all cases */
1551:     q = &stab[lookup( p->sname, p->sflags&(SMOS|SHIDDEN) )];
1552:     /* make relook always point to either p or an empty cell */
1553:     if( q->stype == UNDEF ){
1554:         q->stype = TNULL;
1555:         return(q);
1556:         }
1557:     while( q != p ){
1558:         if( q->stype == TNULL ) break;
1559:         if( ++q >= &stab[SYMTSZ] ) q=stab;
1560:         }
1561:     return(q);
1562:     }
1563: 
1564: clearst( lev ){ /* clear entries of internal scope  from the symbol table */
1565:     register struct symtab *p, *q, *r;
1566:     register int temp, rehash;
1567: 
1568:     temp = lineno;
1569:     aobeg();
1570: 
1571:     /* first, find an empty slot to prevent newly hashed entries from
1572: 	   being slopped into... */
1573: 
1574:     for( q=stab; q< &stab[SYMTSZ]; ++q ){
1575:         if( q->stype == TNULL )goto search;
1576:         }
1577: 
1578:     cerror( "symbol table full");
1579: 
1580:     search:
1581:     p = q;
1582: 
1583:     for(;;){
1584:         if( p->stype == TNULL ) {
1585:             rehash = 0;
1586:             goto next;
1587:             }
1588:         lineno = p->suse;
1589:         if( lineno < 0 ) lineno = - lineno;
1590:         if( p->slevel>lev ){ /* must clobber */
1591:             if( p->stype == UNDEF || ( p->sclass == ULABEL && lev < 2 ) ){
1592:                 lineno = temp;
1593:                 uerror( "%.8s undefined", p->sname );
1594:                 }
1595:             else aocode(p);
1596:             if (ddebug) printf("removing %8s from stab[ %d], flags %o level %d\n",
1597:                 p->sname,p-stab,p->sflags,p->slevel);
1598:             if( p->sflags & SHIDES ) unhide(p);
1599:             p->stype = TNULL;
1600:             rehash = 1;
1601:             goto next;
1602:             }
1603:         if( rehash ){
1604:             if( (r=relook(p)) != p ){
1605:                 movestab( r, p );
1606:                 p->stype = TNULL;
1607:                 }
1608:             }
1609:         next:
1610:         if( ++p >= &stab[SYMTSZ] ) p = stab;
1611:         if( p == q ) break;
1612:         }
1613:     lineno = temp;
1614:     aoend();
1615:     }
1616: 
1617: movestab( p, q ) register struct symtab *p, *q; {
1618:     int k;
1619:     /* structure assignment: *p = *q; */
1620:     p->stype = q->stype;
1621:     p->sclass = q->sclass;
1622:     p->slevel = q->slevel;
1623:     p->offset = q->offset;
1624:     p->sflags = q->sflags;
1625:     p->dimoff = q->dimoff;
1626:     p->sizoff = q->sizoff;
1627:     p->suse = q->suse;
1628:     for( k=0; k<NCHNAM; ++k ){
1629:         p->sname[k] = q->sname[k];
1630:         }
1631:     }
1632: 
1633: hide( p ) register struct symtab *p; {
1634:     register struct symtab *q;
1635:     for( q=p+1; ; ++q ){
1636:         if( q >= &stab[SYMTSZ] ) q = stab;
1637:         if( q == p ) cerror( "symbol table full" );
1638:         if( q->stype == TNULL ) break;
1639:         }
1640:     movestab( q, p );
1641:     p->sflags |= SHIDDEN;
1642:     q->sflags = (p->sflags&SMOS) | SHIDES;
1643:     if( hflag ) werror( "%.8s redefinition hides earlier one", p->sname );
1644:     if( ddebug ) printf( "	%d hidden in %d\n", p-stab, q-stab );
1645:     return( idname = q-stab );
1646:     }
1647: 
1648: unhide( p ) register struct symtab *p; {
1649:     register struct symtab *q;
1650:     register s, j;
1651: 
1652:     s = p->sflags & SMOS;
1653:     q = p;
1654: 
1655:     for(;;){
1656: 
1657:         if( q == stab ) q = &stab[SYMTSZ-1];
1658:         else --q;
1659: 
1660:         if( q == p ) break;
1661: 
1662:         if( (q->sflags&SMOS) == s ){
1663:             for( j =0; j<NCHNAM; ++j ) if( p->sname[j] != q->sname[j] ) break;
1664:             if( j == NCHNAM ){ /* found the name */
1665:                 q->sflags &= ~SHIDDEN;
1666:                 if( ddebug ) printf( "unhide uncovered %d from %d\n", q-stab,p-stab);
1667:                 return;
1668:                 }
1669:             }
1670: 
1671:         }
1672:     cerror( "unhide fails" );
1673:     }

Defined functions

beginit defined in line 692; used 2 times
bstruct defined in line 404; used 4 times
checkst defined in line 1526; used 3 times
clearst defined in line 1564; used 1 times
dclargs defined in line 341; used 1 times
dclstruct defined in line 433; used 2 times
defid defined in line 25; used 27 times
doinit defined in line 878; used 2 times
endinit defined in line 827; used 3 times
falloc defined in line 1095; used 5 times
fixclass defined in line 1380; used 2 times
fixtype defined in line 1331; used 2 times
ftnarg defined in line 542; used 2 times
ftnend defined in line 316; used 3 times
getstr defined in line 785; used 1 times
gotscal defined in line 955; used 3 times
hide defined in line 1633; used 3 times
ilbrace defined in line 995; used 2 times
inforce defined in line 635; used 6 times
instk defined in line 728; used 3 times
irbrace defined in line 1021; used 2 times
lookup defined in line 1476; used 4 times
moedef defined in line 396; used 2 times
movestab defined in line 1617; used 2 times
nidcl defined in line 1181; used 1 times
oalloc defined in line 1058; used 7 times
psave defined in line 309; used 17 times
putbyte defined in line 819; used 2 times
relook defined in line 1545; used 3 times
rstruct defined in line 364; used 2 times
talign defined in line 551; used 8 times
tsize defined in line 601; used 13 times
tymerge defined in line 1268; used 9 times
types defined in line 1208; used 2 times
tyreduce defined in line 1301; used 2 times
uclass defined in line 1372; used 1 times
unhide defined in line 1648; used 1 times
upoff defined in line 1045; used 2 times
vfdalign defined in line 675; used 3 times
yyaccpt defined in line 538; used 1 times
yyerror defined in line 532; never used

Defined variables

ddebug defined in line 23; used 12 times
ibseen defined in line 686; used 5 times
iclass defined in line 688; used 16 times
idebug defined in line 684; used 5 times
ilocctr defined in line 690; used 3 times
instack defined in line 14; used 8 times
pstk defined in line 15; used 64 times

Defined struct's

instk defined in line 3; used 2 times
  • in line 997(2)
Last modified: 1982-08-28
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1307
Valid CSS Valid XHTML 1.0 Strict