📄 pftn.c
字号:
case UNSIGNED: al = ALINT; sz = SZINT; break;#ifdef LONGFIELDS case LONG: case ULONG: al = ALLONG; sz = SZLONG; break;#endif default: if( new < 0 ) { uerror( "illegal field type" ); al = ALINT; } else { al = fldal( p->stype ); sz =SZINT; } } if( w > sz ) { uerror( "field too big"); w = sz; } if( w == 0 ){ /* align only */ SETOFF( strucoff, al ); if( new >= 0 ) uerror( "zero size field"); return(0); } if( strucoff%al + w > sz ) SETOFF( strucoff, al ); if( new < 0 ) { if( (offsz-strucoff) < w ) cerror("structure too large"); strucoff += w; /* we know it will fit */ return(0); } /* establish the field */ if( new == 1 ) { /* previous definition */ if( p->offset != strucoff || p->sclass != (FIELD|w) ) return(1); } p->offset = strucoff; if( (offsz-strucoff) < w ) cerror("structure too large"); strucoff += w; p->stype = type; fldty( p ); return(0); }nidcl( p ) NODE *p; { /* handle unitialized declarations */ /* assumed to be not functions */ register class; register commflag; /* flag for labelled common declarations */ commflag = 0; /* compute class */ if( (class=curclass) == SNULL ){ if( blevel > 1 ) class = AUTO; else if( blevel != 0 || instruct ) cerror( "nidcl error" ); else { /* blevel = 0 */ class = noinit(); if( class == EXTERN ) commflag = 1; } }#ifdef LCOMM /* hack so stab will come at as LCSYM rather than STSYM */ if (class == STATIC) { extern int stabLCSYM; stabLCSYM = 1; }#endif defid( p, class );#ifndef LCOMM if( class==EXTDEF || class==STATIC ){#else if (class==STATIC) { register struct symtab *s = &stab[p->tn.rval]; extern int stabLCSYM; int sz = tsize(s->stype, s->dimoff, s->sizoff)/SZCHAR; stabLCSYM = 0; if (sz % sizeof (int)) sz += sizeof (int) - (sz % sizeof (int)); if (s->slevel > 1) printf(" .lcomm L%d,%d\n", s->offset, sz); else printf(" .lcomm %s,%d\n", exname(s->sname), sz); }else if (class == EXTDEF) {#endif /* simulate initialization by 0 */ beginit(p->tn.rval); endinit(); } if( commflag ) commdec( p->tn.rval ); }TWORDtypes( t1, t2, t3 ) TWORD t1, t2, t3; { /* return a basic type from basic types t1, t2, and t3 */ TWORD t[3], noun, adj, unsg; register i; t[0] = t1; t[1] = t2; t[2] = t3; unsg = INT; /* INT or UNSIGNED */ noun = UNDEF; /* INT, CHAR, or FLOAT */ adj = INT; /* INT, LONG, or SHORT */ for( i=0; i<3; ++i ){ switch( t[i] ){ default: bad: uerror( "illegal type combination" ); return( INT ); case UNDEF: continue; case UNSIGNED: if( unsg != INT ) goto bad; unsg = UNSIGNED; continue; case LONG: case SHORT: if( adj != INT ) goto bad; adj = t[i]; continue; case INT: case CHAR: case FLOAT: if( noun != UNDEF ) goto bad; noun = t[i]; continue; } } /* now, construct final type */ if( noun == UNDEF ) noun = INT; else if( noun == FLOAT ){ if( unsg != INT || adj == SHORT ) goto bad; return( adj==LONG ? DOUBLE : FLOAT ); } else if( noun == CHAR && adj != INT ) goto bad; /* now, noun is INT or CHAR */ if( adj != INT ) noun = adj; if( unsg == UNSIGNED ) return( noun + (UNSIGNED-INT) ); else return( noun ); }NODE *tymerge( typ, idp ) NODE *typ, *idp; { /* merge type typ with identifier idp */ register unsigned t; register i; extern int eprint(); if( typ->in.op != TYPE ) cerror( "tymerge: arg 1" ); if(idp == NIL ) return( NIL );# ifndef BUG1 if( ddebug > 2 ) fwalk( idp, eprint, 0 );# endif idp->in.type = typ->in.type; idp->fn.cdim = curdim; tyreduce( idp ); idp->fn.csiz = typ->fn.csiz; for( t=typ->in.type, i=typ->fn.cdim; t&TMASK; t = DECREF(t) ){ if( ISARY(t) ) dstash( dimtab[i++] ); } /* now idp is a single node: fix up type */ idp->in.type = ctype( idp->in.type ); if( (t = BTYPE(idp->in.type)) != STRTY && t != UNIONTY && t != ENUMTY ){ idp->fn.csiz = t; /* in case ctype has rewritten things */ } return( idp ); }tyreduce( p ) register NODE *p; { /* build a type, and stash away dimensions, from a parse tree of the declaration */ /* the type is build top down, the dimensions bottom up */ register o, temp; register unsigned t; o = p->in.op; p->in.op = FREE; if( o == NAME ) return; t = INCREF( p->in.type ); if( o == UNARY CALL ) t += (FTN-PTR); else if( o == LB ){ t += (ARY-PTR); temp = p->in.right->tn.lval; p->in.right->in.op = FREE; if( ( temp == 0 ) & ( p->in.left->tn.op == LB ) ) uerror( "Null dimension" ); } p->in.left->in.type = t; tyreduce( p->in.left ); if( o == LB ) dstash( temp ); p->tn.rval = p->in.left->tn.rval; p->in.type = p->in.left->in.type; }fixtype( p, class ) register NODE *p; { register unsigned t, type; register mod1, mod2; /* fix up the types, and check for legality */ if( (type = p->in.type) == UNDEF ) return; if( mod2 = (type&TMASK) ){ t = DECREF(type); while( mod1=mod2, mod2 = (t&TMASK) ){ if( mod1 == ARY && mod2 == FTN ){ uerror( "array of functions is illegal" ); type = 0; } else if( mod1 == FTN && ( mod2 == ARY || mod2 == FTN ) ){ uerror( "function returns illegal type" ); type = 0; } t = DECREF(t); } } /* detect function arguments, watching out for structure declarations */ /* for example, beware of f(x) struct [ int a[10]; } *x; { ... } */ /* the danger is that "a" will be converted to a pointer */ if( class==SNULL && blevel==1 && !(instruct&(INSTRUCT|INUNION)) ) class = PARAM; if( class == PARAM || ( class==REGISTER && blevel==1 ) ){ if( type == FLOAT ) type = DOUBLE; else if( ISARY(type) ){ ++p->fn.cdim; type += (PTR-ARY); } else if( ISFTN(type) ){ werror( "a function is declared as an argument" ); type = INCREF(type); } } if( instruct && ISFTN(type) ){ uerror( "function illegal in structure or union" ); type = INCREF(type); } p->in.type = type; }uclass( class ) register class; { /* give undefined version of class */ if( class == SNULL ) return( EXTERN ); else if( class == STATIC ) return( USTATIC ); else if( class == FORTRAN ) return( UFORTRAN ); else return( class ); }fixclass( class, type ) TWORD type; { /* first, fix null class */ if( class == SNULL ){ if( instruct&INSTRUCT ) class = MOS; else if( instruct&INUNION ) class = MOU; else if( blevel == 0 ) class = EXTDEF; else if( blevel == 1 ) class = PARAM; else class = AUTO; } /* now, do general checking */ if( ISFTN( type ) ){ switch( class ) { default: uerror( "function has illegal storage class" ); case AUTO: class = EXTERN; case EXTERN: case EXTDEF: case FORTRAN: case TYPEDEF: case STATIC: case UFORTRAN: case USTATIC: ; } } if( class&FIELD ){ if( !(instruct&INSTRUCT) ) uerror( "illegal use of field" ); return( class ); } switch( class ){ case MOU: if( !(instruct&INUNION) ) uerror( "illegal class" ); return( class ); case MOS: if( !(instruct&INSTRUCT) ) uerror( "illegal class" ); return( class ); case MOE: if( instruct & (INSTRUCT|INUNION) ) uerror( "illegal class" ); return( class ); case REGISTER: if( blevel == 0 ) uerror( "illegal register declaration" ); else if( regvar >= MINRVAR && cisreg( type ) ) return( class ); if( blevel == 1 ) return( PARAM ); else return( AUTO ); case AUTO: case LABEL: case ULABEL: if( blevel < 2 ) uerror( "illegal class" ); return( class ); case PARAM: if( blevel != 1 ) uerror( "illegal class" ); return( class ); case UFORTRAN: case FORTRAN:# ifdef NOFORTRAN NOFORTRAN; /* a condition which can regulate the FORTRAN usage */# endif if( !ISFTN(type) ) uerror( "fortran declaration must apply to function" ); else { type = DECREF(type); if( ISFTN(type) || ISARY(type) || ISPTR(type) ) { uerror( "fortran function has wrong type" ); } } case STNAME: case UNAME: case ENAME: case EXTERN: case STATIC: case EXTDEF: case TYPEDEF: case USTATIC: return( class ); default: cerror( "illegal class: %d", class ); /* NOTREACHED */ } }struct symtab *mknonuniq(idindex) int *idindex; {/* locate a symbol table entry for */ /* an occurrence of a nonunique structure member name */ /* or field */ register i; register struct symtab * sp; char *p,*q; sp = & stab[ i= *idindex ]; /* position search at old entry */ while( sp->stype != TNULL ){ /* locate unused entry */ if( ++i >= SYMTSZ ){/* wrap around symbol table */ i = 0; sp = stab; } else ++sp; if( i == *idindex ) cerror("Symbol table full"); } sp->sflags = SNONUNIQ | SMOS; p = sp->sname; q = stab[*idindex].sname; /* old entry name */#ifdef FLEXNAMES sp->sname = stab[*idindex].sname;#endif# ifndef BUG1 if( ddebug ){ printf("\tnonunique entry for %s from %d to %d\n", q, *idindex, i ); }# endif *idindex = i;#ifndef FLEXNAMES for( i=1; i<=NCHNAM; ++i ){ /* copy name */ if( *p++ = *q /* assign */ ) ++q; }#endif return ( sp ); }lookup( name, s) char *name; { /* look up name: must agree with s w.r.t. STAG, SMOS and SHIDDEN */ register char *p, *q; int i, j, ii; register struct symtab *sp; /* compute initial hash index */# ifndef BUG1 if( ddebug > 2 ){ printf( "lookup( %s, %d ), stwart=%d, instruct=%d\n", name, s, stwart, instruct ); }# endif i = 0;#ifndef FLEXNAMES for( p=name, j=0; *p != '\0'; ++p ){ i += *p; if( ++j >= NCHNAM ) break; }#else i = (int)name;#endif i = i%SYMTSZ; sp = &stab[ii=i]; for(;;){ /* look for name */ if( sp->stype == TNULL ){ /* empty slot */ sp->sflags = s; /* set STAG, SMOS if needed, turn off all others */#ifndef FLEXNAMES p = sp->sname; for( j=0; j<NCHNAM; ++j ) if( *p++ = *name ) ++name;#else sp->sname = name;#endif sp->stype = UNDEF; sp->sclass = SNULL; return( i ); } if( (sp->sflags & (STAG|SMOS|SHIDDEN)) != s ) goto next; p = sp->sname; q = name;#ifndef FLEXNAMES for( j=0; j<NCHNAM;++j ){ if( *p++ != *q ) goto next; if( !*q++ ) break; } return( i );#else if (p == q) return ( i );#endif next: if( ++i >= SYMTSZ ){ i = 0; sp = stab; } else ++sp; if( i == ii ) cerror( "symbol table full" ); } }#ifndef checkst/* if not debugging, make checkst a macro */checkst(lev){ register int s, i, j; register struct symtab *p, *q; for( i=0, p=stab; i<SYMTSZ; ++i, ++p ){ if( p->stype == TNULL ) continue; j = lookup( p->sname, p->sflags&(SMOS|STAG) ); if( j != i ){ q = &stab[j]; if( q->stype == UNDEF || q->slevel <= p->slevel ){#ifndef FLEXNAMES cerror( "check error: %.8s", q->sname );#else cerror( "check error: %s", q->sname );#endif } }#ifndef FLEXNAMES else if( p->slevel > lev ) cerror( "%.8s check at level %d", p->sname, lev );#else else if( p->slevel > lev ) cerror( "%s check at level %d", p->sname, lev );#endif } }#endifstruct symtab *relook(p) register struct symtab *p; { /* look up p again, and see where it lies */ register struct symtab *q; /* I'm not sure that this handles towers of several hidden definitions in all cases */ q = &stab[lookup( p->sname, p->sflags&(STAG|SMOS|SHIDDEN) )]; /* make relook always point to either p or an empty cell */ if( q->stype == UNDEF ){ q->stype = TNULL; return(q); } while( q != p ){ if( q->stype == TNULL ) break; if( ++q >= &stab[SYMTSZ] ) q=stab; } return(q); }clearst( lev ){ /* clear entries of internal scope from the symbol table */ register struct symtab *p, *q, *r; register int temp, rehash; temp = lineno; aobeg(); /* first, find an empty slot to prevent newly hashed entries from being slopped into... */ for( q=stab; q< &stab[SYMTSZ]; ++q ){ if( q->stype == TNULL )goto search; } cerror( "symbol table full"); search: p = q; for(;;){ if( p->stype == TNULL ) { rehash = 0; goto next; } lineno = p->suse; if( lineno < 0 ) lineno = - lineno; if( p->slevel>lev ){ /* must clobber */ if( p->stype == UNDEF || ( p->sclass == ULABEL && lev < 2 ) ){ lineno = temp;#ifndef FLEXNAMES uerror( "%.8s undefined", p->sname );#else uerror( "%s undefined", p->sname );#endif } else aocode(p);# ifndef BUG1#ifndef FLEXNAMES if (ddebug) printf("removing %8s from stab[ %d], flags %o level %d\n",#else if (ddebug) printf("removing %s from stab[ %d], flags %o level %d\n",#endif p->sname,p-stab,p->sflags,p->slevel);# endif if( p->sflags & SHIDES ) unhide(p); p->stype = TNULL; rehash = 1; goto next; } if( rehash ){ if( (r=relook(p)) != p ){ movestab( r, p ); p->stype = TNULL; } } next: if( ++p >= &stab[SYMTSZ] ) p = stab; if( p == q ) break; } lineno = temp; aoend(); }movestab( p, q ) register struct symtab *p, *q; { int k; /* structure assignment: *p = *q; */ p->stype = q->stype; p->sclass = q->sclass; p->slevel = q->slevel; p->offset = q->offset; p->sflags = q->sflags; p->dimoff = q->dimoff; p->sizoff = q->sizoff; p->suse = q->suse;#ifndef FLEXNAMES for( k=0; k<NCHNAM; ++k ){ p->sname[k] = q->sname[k]; }#else p->sname = q->sname;#endif }hide( p ) register struct symtab *p; { register struct symtab *q; for( q=p+1; ; ++q ){ if( q >= &stab[SYMTSZ] ) q = stab; if( q == p ) cerror( "symbol table full" ); if( q->stype == TNULL ) break; } movestab( q, p ); p->sflags |= SHIDDEN; q->sflags = (p->sflags&(SMOS|STAG)) | SHIDES;#ifndef FLEXNAMES if( hflag ) werror( "%.8s redefinition hides earlier one", p->sname );#else if( hflag ) werror( "%s redefinition hides earlier one", p->sname );#endif# ifndef BUG1 if( ddebug ) printf( " %d hidden in %d\n", p-stab, q-stab );# endif return( idname = q-stab ); }unhide( p ) register struct symtab *p; { register struct symtab *q; register s, j; s = p->sflags & (SMOS|STAG); q = p; for(;;){ if( q == stab ) q = &stab[SYMTSZ-1]; else --q; if( q == p ) break; if( (q->sflags&(SMOS|STAG)) == s ){#ifndef FLEXNAMES for( j =0; j<NCHNAM; ++j ) if( p->sname[j] != q->sname[j] ) break; if( j == NCHNAM ){ /* found the name */#else if (p->sname == q->sname) {#endif q->sflags &= ~SHIDDEN;# ifndef BUG1 if( ddebug ) printf( "unhide uncovered %d from %d\n", q-stab,p-stab);# endif return; } } } cerror( "unhide fails" ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -