home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / mip / pftn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  33.9 KB  |  1,674 lines

  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.     }
  1674.