📄 pftn.c
字号:
#endif } }# endif strucoff = paramstk[ oparam+2 ]; paramno = oparam; return( mkty( temp, 0, szindex ) ); } /* VARARGS */yyerror( s ) char *s; { /* error printing routine in parser */ uerror( s ); }yyaccpt(){ ftnend(); }ftnarg( idn ) { switch( stab[idn].stype ){ case UNDEF: /* this parameter, entered at scan */ break; case FARG:#ifndef FLEXNAMES uerror("redeclaration of formal parameter, %.8s",#else uerror("redeclaration of formal parameter, %s",#endif stab[idn].sname); /* fall thru */ case FTN: /* the name of this function matches parm */ /* fall thru */ default: idn = hide( &stab[idn]); break; case TNULL: /* unused entry, fill it */ ; } stab[idn].stype = FARG; stab[idn].sclass = PARAM; psave( idn ); }talign( ty, s) register unsigned ty; register s; { /* compute the alignment of an object with type ty, sizeoff index s */ register i; if( s<0 && ty!=INT && ty!=CHAR && ty!=SHORT && ty!=UNSIGNED && ty!=UCHAR && ty!=USHORT #ifdef LONGFIELDS && ty!=LONG && ty!=ULONG#endif ){ return( fldal( ty ) ); } for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){ switch( (ty>>i)&TMASK ){ case FTN: cerror( "compiler takes alignment of function"); case PTR: return( ALPOINT ); case ARY: continue; case 0: break; } } switch( BTYPE(ty) ){ case UNIONTY: case ENUMTY: case STRTY: return( (unsigned int) dimtab[ s+2 ] ); case CHAR: case UCHAR: return( ALCHAR ); case FLOAT: return( ALFLOAT ); case DOUBLE: return( ALDOUBLE ); case LONG: case ULONG: return( ALLONG ); case SHORT: case USHORT: return( ALSHORT ); default: return( ALINT ); } }OFFSZtsize( ty, d, s ) TWORD ty; { /* compute the size associated with type ty, dimoff d, and sizoff s */ /* BETTER NOT BE CALLED WHEN t, d, and s REFER TO A BIT FIELD... */ int i; OFFSZ mult; mult = 1; for( i=0; i<=(SZINT-BTSHIFT-1); i+=TSHIFT ){ switch( (ty>>i)&TMASK ){ case FTN: cerror( "compiler takes size of function"); case PTR: return( SZPOINT * mult ); case ARY: mult *= (unsigned int) dimtab[ d++ ]; continue; case 0: break; } } if( dimtab[s]==0 ) { uerror( "unknown size"); return( SZINT ); } return( (unsigned int) dimtab[ s ] * mult ); }inforce( n ) OFFSZ n; { /* force inoff to have the value n */ /* inoff is updated to have the value n */ OFFSZ wb; register rest; /* rest is used to do a lot of conversion to ints... */ if( inoff == n ) return; if( inoff > n ) { cerror( "initialization alignment error"); } wb = inoff; SETOFF( wb, SZINT ); /* wb now has the next higher word boundary */ if( wb >= n ){ /* in the same word */ rest = n - inoff; vfdzero( rest ); return; } /* otherwise, extend inoff to be word aligned */ rest = wb - inoff; vfdzero( rest ); /* now, skip full words until near to n */ rest = (n-inoff)/SZINT; zecode( rest ); /* now, the remainder of the last word */ rest = n-inoff; vfdzero( rest ); if( inoff != n ) cerror( "inoff error"); }vfdalign( n ){ /* make inoff have the offset the next alignment of n */ OFFSZ m; m = inoff; SETOFF( m, n ); inforce( m ); }int idebug = 0;int ibseen = 0; /* the number of } constructions which have been filled */int iclass; /* storage class of thing being initialized */int ilocctr = 0; /* location counter for current initialization */beginit(curid){ /* beginning of initilization; set location ctr and set type */ register struct symtab *p;# ifndef BUG1 if( idebug >= 3 ) printf( "beginit(), curid = %d\n", curid );# endif p = &stab[curid]; iclass = p->sclass; if( curclass == EXTERN || curclass == FORTRAN ) iclass = EXTERN; switch( iclass ){ case UNAME: case EXTERN: return; case AUTO: case REGISTER: break; case EXTDEF: case STATIC: ilocctr = ISARY(p->stype)?ADATA:DATA; locctr( ilocctr ); defalign( talign( p->stype, p->sizoff ) ); defnam( p ); } inoff = 0; ibseen = 0; pstk = 0; instk( curid, p->stype, p->dimoff, p->sizoff, inoff ); }instk( id, t, d, s, off ) OFFSZ off; TWORD t; { /* make a new entry on the parameter stack to initialize id */ register struct symtab *p; for(;;){# ifndef BUG1 if( idebug ) printf( "instk((%d, %o,%d,%d, %d)\n", id, t, d, s, off );# endif /* save information on the stack */ if( !pstk ) pstk = instack; else ++pstk; pstk->in_fl = 0; /* { flag */ pstk->in_id = id ; pstk->in_t = t ; pstk->in_d = d ; pstk->in_s = s ; pstk->in_n = 0; /* number seen */ pstk->in_x = t==STRTY ?dimtab[s+1] : 0 ; pstk->in_off = off; /* offset at the beginning of this element */ /* if t is an array, DECREF(t) can't be a field */ /* INS_sz has size of array elements, and -size for fields */ if( ISARY(t) ){ pstk->in_sz = tsize( DECREF(t), d+1, s ); } else if( stab[id].sclass & FIELD ){ pstk->in_sz = - ( stab[id].sclass & FLDSIZ ); } else { pstk->in_sz = 0; } if( (iclass==AUTO || iclass == REGISTER ) && (ISARY(t) || t==STRTY) ) uerror( "no automatic aggregate initialization" ); /* now, if this is not a scalar, put on another element */ if( ISARY(t) ){ t = DECREF(t); ++d; continue; } else if( t == STRTY ){ id = dimtab[pstk->in_x]; p = &stab[id]; if( p->sclass != MOS && !(p->sclass&FIELD) ) cerror( "insane structure member list" ); t = p->stype; d = p->dimoff; s = p->sizoff; off += p->offset; continue; } else return; } }NODE *getstr(){ /* decide if the string is external or an initializer, and get the contents accordingly */ register l, temp; register NODE *p; if( (iclass==EXTDEF||iclass==STATIC) && (pstk->in_t == CHAR || pstk->in_t == UCHAR) && pstk!=instack && ISARY( pstk[-1].in_t ) ){ /* treat "abc" as { 'a', 'b', 'c', 0 } */ strflg = 1; ilbrace(); /* simulate { */ inforce( pstk->in_off ); /* if the array is inflexible (not top level), pass in the size and be prepared to throw away unwanted initializers */ lxstr((pstk-1)!=instack?dimtab[(pstk-1)->in_d]:0); /* get the contents */ irbrace(); /* simulate } */ return( NIL ); } else { /* make a label, and get the contents and stash them away */ if( iclass != SNULL ){ /* initializing */ /* fill out previous word, to permit pointer */ vfdalign( ALPOINT ); } temp = locctr( blevel==0?ISTRNG:STRNG ); /* set up location counter */ deflab( l = getlab() ); strflg = 0; lxstr(0); /* get the contents */ locctr( blevel==0?ilocctr:temp ); p = buildtree( STRING, NIL, NIL ); p->tn.rval = -l; return(p); } }putbyte( v ){ /* simulate byte v appearing in a list of integer values */ register NODE *p; p = bcon(v); incode( p, SZCHAR ); tfree( p ); gotscal(); }endinit(){ register TWORD t; register d, s, n, d1;# ifndef BUG1 if( idebug ) printf( "endinit(), inoff = %d\n", inoff );# endif switch( iclass ){ case EXTERN: case AUTO: case REGISTER: return; } pstk = instack; t = pstk->in_t; d = pstk->in_d; s = pstk->in_s; n = pstk->in_n; if( ISARY(t) ){ d1 = dimtab[d]; vfdalign( pstk->in_sz ); /* fill out part of the last element, if needed */ n = inoff/pstk->in_sz; /* real number of initializers */ if( d1 >= n ){ /* once again, t is an array, so no fields */ inforce( tsize( t, d, s ) ); n = d1; } if( d1!=0 && d1!=n ) uerror( "too many initializers"); if( n==0 ) werror( "empty array declaration"); dimtab[d] = n; if( d1==0 ) FIXDEF(&stab[pstk->in_id]); } else if( t == STRTY || t == UNIONTY ){ /* clearly not fields either */ inforce( tsize( t, d, s ) ); } else if( n > 1 ) uerror( "bad scalar initialization"); /* this will never be called with a field element... */ else inforce( tsize(t,d,s) ); paramno = 0; vfdalign( AL_INIT ); inoff = 0; iclass = SNULL; }doinit( p ) register NODE *p; { /* take care of generating a value for the initializer p */ /* inoff has the current offset (last bit written) in the current word being generated */ register sz, d, s; register TWORD t; /* note: size of an individual initializer is assumed to fit into an int */ if( iclass < 0 ) goto leave; if( iclass == EXTERN || iclass == UNAME ){ uerror( "cannot initialize extern or union" ); iclass = -1; goto leave; } if( iclass == AUTO || iclass == REGISTER ){ /* do the initialization and get out, without regard for filing out the variable with zeros, etc. */ bccode(); idname = pstk->in_id; p = buildtree( ASSIGN, buildtree( NAME, NIL, NIL ), p ); ecomp(p); return; } if( p == NIL ) return; /* for throwing away strings that have been turned into lists */ if( ibseen ){ uerror( "} expected"); goto leave; }# ifndef BUG1 if( idebug > 1 ) printf( "doinit(%o)\n", p );# endif t = pstk->in_t; /* type required */ d = pstk->in_d; s = pstk->in_s; if( pstk->in_sz < 0 ){ /* bit field */ sz = -pstk->in_sz; } else { sz = tsize( t, d, s ); } inforce( pstk->in_off ); p = buildtree( ASSIGN, block( NAME, NIL,NIL, t, d, s ), p ); p->in.left->in.op = FREE; p->in.left = p->in.right; p->in.right = NIL; p->in.left = optim( p->in.left ); if( p->in.left->in.op == UNARY AND ){ p->in.left->in.op = FREE; p->in.left = p->in.left->in.left; } p->in.op = INIT; if( sz < SZINT ){ /* special case: bit fields, etc. */ if( p->in.left->in.op != ICON ) uerror( "illegal initialization" ); else incode( p->in.left, sz ); } else if( p->in.left->in.op == FCON ){ fincode( p->in.left->fpn.dval, sz ); } else { /* * SLR002 * Becuase of the way the tables are set-up for * the INIT node the code generator will loop * forever until internal table are full. This * test to see if the left node is an integer * will insure that we will not get in the case * where we loop. */ if ( optim(p)->in.left->in.op != ICON ) { /* * SL001 * We are not an integer so emit an error * and leave. This condition will prevent * us goin to the code generator with a * tree that it can not reduce */ uerror ( "illegal initialization"); goto leave; } else /* * Produce the initialization code */ cinit( p, sz ); } gotscal(); leave: tfree(p); }gotscal(){ register t, ix; register n, id; struct symtab *p; OFFSZ temp; for( ; pstk > instack; ) { if( pstk->in_fl ) ++ibseen; --pstk; t = pstk->in_t; if( t == STRTY ){ ix = ++pstk->in_x; if( (id=dimtab[ix]) < 0 ) continue; /* otherwise, put next element on the stack */ p = &stab[id]; instk( id, p->stype, p->dimoff, p->sizoff, p->offset+pstk->in_off ); return; } else if( ISARY(t) ){ n = ++pstk->in_n; if( n >= dimtab[pstk->in_d] && pstk > instack ) continue; /* put the new element onto the stack */ temp = pstk->in_sz; instk( pstk->in_id, (TWORD)DECREF(pstk->in_t), pstk->in_d+1, pstk->in_s, pstk->in_off+n*temp ); return; } } }ilbrace(){ /* process an initializer's left brace */ register t; struct instk *temp; temp = pstk; for( ; pstk > instack; --pstk ){ t = pstk->in_t; if( t != STRTY && !ISARY(t) ) continue; /* not an aggregate */ if( pstk->in_fl ){ /* already associated with a { */ if( pstk->in_n ) uerror( "illegal {"); continue; } /* we have one ... */ pstk->in_fl = 1; break; } /* cannot find one */ /* ignore such right braces */ pstk = temp; }irbrace(){ /* called when a '}' is seen */# ifndef BUG1 if( idebug ) printf( "irbrace(): paramno = %d on entry\n", paramno );# endif if( ibseen ) { --ibseen; return; } for( ; pstk > instack; --pstk ){ if( !pstk->in_fl ) continue; /* we have one now */ pstk->in_fl = 0; /* cancel { */ gotscal(); /* take it away... */ return; } /* these right braces match ignored left braces: throw out */ }upoff( size, alignment, poff ) register alignment, *poff; { /* update the offset pointed to by poff; return the /* offset of a value of size `size', alignment `alignment', /* given that off is increasing */ register off; off = *poff; SETOFF( off, alignment ); if( (offsz-off) < size ){ if( instruct!=INSTRUCT )cerror("too many local variables"); else cerror("Structure too large"); } *poff = off+size; return( off ); }oalloc( p, poff ) register struct symtab *p; register *poff; { /* allocate p with offset *poff, and update *poff */ register al, off, tsz; int noff; al = talign( p->stype, p->sizoff ); noff = off = *poff; tsz = tsize( p->stype, p->dimoff, p->sizoff );#ifdef BACKAUTO if( p->sclass == AUTO ){ if( (offsz-off) < tsz ) cerror("too many local variables"); noff = off + tsz; SETOFF( noff, al ); off = -noff; } else#endif if( p->sclass == PARAM && ( tsz < SZINT ) ){ off = upoff( SZINT, ALINT, &noff );# ifndef RTOLBYTES off = noff - tsz;#endif } else { off = upoff( tsz, al, &noff ); } if( p->sclass != REGISTER ){ /* in case we are allocating stack space for register arguments */ if( p->offset == NOOFFSET ) p->offset = off; else if( off != p->offset ) return(1); } *poff = noff; return(0); }falloc( p, w, new, pty ) register struct symtab *p; NODE *pty; { /* allocate a field of width w */ /* new is 0 if new entry, 1 if redefinition, -1 if alignment */ register al,sz,type; type = (new<0)? pty->in.type : p->stype; /* this must be fixed to use the current type in alignments */ switch( new<0?pty->in.type:p->stype ){ case ENUMTY: { int s; s = new<0 ? pty->fn.csiz : p->sizoff; al = dimtab[s+2]; sz = dimtab[s]; break; } case CHAR: case UCHAR: al = ALCHAR; sz = SZCHAR; break; case SHORT: case USHORT: al = ALSHORT; sz = SZSHORT; break; case INT:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -