⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trees.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
				l = block( STASG, l, r, t, d, s );				if( o == RETURN ){					p->in.op = FREE;					p = l;					break;					}				p->in.op = UNARY MUL;				p->in.left = l;				p->in.right = NIL;				break;				}		case COLON:			/* structure colon */			if( l->fn.csiz != r->fn.csiz ) uerror( "type clash in conditional" );			break;		case CALL:			p->in.right = r = strargs( p->in.right );		case UNARY CALL:			if( !ISPTR(l->in.type)) uerror("illegal function");			p->in.type = DECREF(l->in.type);			if( !ISFTN(p->in.type)) uerror("illegal function");			p->in.type = DECREF( p->in.type );			p->fn.cdim = l->fn.cdim;			p->fn.csiz = l->fn.csiz;			if( l->in.op == UNARY AND && l->in.left->in.op == NAME &&				l->in.left->tn.rval >= 0 && l->in.left->tn.rval != NONAME &&				( (i=stab[l->in.left->tn.rval].sclass) == FORTRAN || i==UFORTRAN ) ){				p->in.op += (FORTCALL-CALL);				}			if( p->in.type == STRTY || p->in.type == UNIONTY ){				/* function returning structure */				/*  make function really return ptr to str., with * */				p->in.op += STCALL-CALL;				p->in.type = INCREF( p->in.type );				p = buildtree( UNARY MUL, p, NIL );				}			break;		default:			cerror( "other code %d", o );			}		}	if( actions & CVTO ) p = oconvert(p);	p = clocal(p);# ifndef BUG1	if( bdebug ) fwalk( p, eprint, 0 );# endif	return(p);	}/* vdp012 report floating point exception.   * If fpe_count is not less then 0 then  * the floating point signal occured when  * we were combining constants in buildtree * (see call to setjmp) */int fpe_count = -1;jmp_buf gotfpe;voidfpe() {	if (fpe_count < 0)		cerror("floating point exception");	++fpe_count;	longjmp(gotfpe, 1);	}NODE *strargs( p ) register NODE *p;  { /* rewrite structure flavored arguments */	if( p->in.op == CM ){		p->in.left = strargs( p->in.left );		p->in.right = strargs( p->in.right );		return( p );		}	/*RAP005		Catch use of functions that don't return values used as		arguements.	*/	if ((p->in.op==UNARY CALL || p->in.op==CALL ) && p->in.type==UNDEF)		uerror("void or undef used in value required context");	if( p->in.type == STRTY || p->in.type == UNIONTY ){		p = block( STARG, p, NIL, p->in.type, p->fn.cdim, p->fn.csiz );		p->in.left = buildtree( UNARY AND, p->in.left, NIL );		p = clocal(p);		}       /* vdp Single	(e.g. 34.56f )   	* precision floating point constants are 	* cast to double (to eliminate convert code). 	*/	else if( p->in.op == FCON )		p = makety(p, DOUBLE, 0, 0);	return( p );	}chkstr( i, j, type ) TWORD type; {	/* is the MOS or MOU at stab[i] OK for strict reference by a ptr */	/* i has been checked to contain a MOS or MOU */	/* j is the index in dimtab of the members... */	int k, kk;	extern int ddebug;# ifndef BUG1#ifndef FLEXNAMES	if( ddebug > 1 ) printf( "chkstr( %.8s(%d), %d )\n", stab[i].sname, i, j );#else	if( ddebug > 1 ) printf( "chkstr( %s(%d), %d )\n", stab[i].sname, i, j );#endif# endif	if( (k = j) < 0 ) uerror( "undefined structure or union" );	else {		for( ; (kk = dimtab[k] ) >= 0; ++k ){			if( kk >= SYMTSZ ){				cerror( "gummy structure" );				return(1);				}			if( kk == i ) return( 1 );			switch( stab[kk].stype ){			case STRTY:			case UNIONTY:				if( type == STRTY ) continue;  /* no recursive looking for strs */				if( hflag && chkstr( i, dimtab[stab[kk].sizoff+1], stab[kk].stype ) ){					if( stab[kk].sname[0] == '$' ) return(0);  /* $FAKE */					werror(#ifndef FLEXNAMES					"illegal member use: perhaps %.8s.%.8s?",#else					"illegal member use: perhaps %s.%s?",#endif					stab[kk].sname, stab[i].sname );					return(1);					}				}			}		}	return( 0 );	}conval( p, o, q ) register NODE *p, *q; {	/* apply the op o to the lval part of p; if binary, rhs is val */	int i, u;	CONSZ val;	val = q->tn.lval;	u = ISUNSIGNED(p->in.type) || ISUNSIGNED(q->in.type);	if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);	if( p->tn.rval != NONAME && q->tn.rval != NONAME ) return(0);	if( q->tn.rval != NONAME && o!=PLUS ) return(0);	if( p->tn.rval != NONAME && o!=PLUS && o!=MINUS ) return(0);	switch( o ){	case PLUS:		p->tn.lval += val;		if( p->tn.rval == NONAME ){			p->tn.rval = q->tn.rval;			p->in.type = q->in.type;			}		break;	case MINUS:		p->tn.lval -= val;		break;	case MUL:		p->tn.lval *= val;		break;	case DIV:		if( val == 0 )			uerror( "division by 0" );		else if (u)			p->tn.lval /= (unsigned)val;		else			p->tn.lval /= val;		break;	case MOD:		if( val == 0 )			uerror( "division by 0" );		else if (u)			p->tn.lval %= (unsigned)val;		else			p->tn.lval %= val;		break;	case AND:		p->tn.lval &= val;		break;	case OR:		p->tn.lval |= val;		break;	case ER:		p->tn.lval ^=  val;		break;	case LS:		i = val;		if (u)			p->tn.lval = (unsigned)p->tn.lval << i;		else			p->tn.lval = p->tn.lval << i;		break;	case RS:		i = val;		if (u)			p->tn.lval = (unsigned)p->tn.lval >> i;		else			p->tn.lval = p->tn.lval >> i;		break;	case UNARY MINUS:		p->tn.lval = - p->tn.lval;		break;	case COMPL:		p->tn.lval = ~p->tn.lval;		break;	case NOT:		p->tn.lval = !p->tn.lval;		break;	case LT:		p->tn.lval = p->tn.lval < val;		break;	case LE:		p->tn.lval = p->tn.lval <= val;		break;	case GT:		p->tn.lval = p->tn.lval > val;		break;	case GE:		p->tn.lval = p->tn.lval >= val;		break;	case ULT:		p->tn.lval = (p->tn.lval-val)<0;		break;	case ULE:		p->tn.lval = (p->tn.lval-val)<=0;		break;	case UGE:		p->tn.lval = (p->tn.lval-val)>=0;		break;	case UGT:		p->tn.lval = (p->tn.lval-val)>0;		break;	case EQ:		p->tn.lval = p->tn.lval == val;		break;	case NE:		p->tn.lval = p->tn.lval != val;		break;	default:		return(0);		}	return(1);	}chkpun(p) register NODE *p; {	/* checks p for the existance of a pun */	/* this is called when the op of p is ASSIGN, RETURN, CAST, COLON, or relational */	/* one case is when enumerations are used: this applies only to lint */	/* in the other case, one operand is a pointer, the other integer type */	/* we check that this integer is in fact a constant zero... */	/* in the case of ASSIGN, any assignment of pointer to integer is illegal */	/* this falls out, because the LHS is never 0 */	register NODE *q;	register t1, t2;	register d1, d2;	t1  = p->in.left->in.type;	t2  = p->in.right->in.type;	if( t1==ENUMTY || t2==ENUMTY ) { /* check for enumerations */		if( logop( p->in.op ) && p->in.op != EQ && p->in.op != NE ) {			uerror( "illegal comparison of enums" );			return;			}		if( t1==ENUMTY && t2==ENUMTY && p->in.left->fn.csiz==p->in.right->fn.csiz ) return;		werror( "enumeration type clash, operator %s", opst[p->in.op] );		return;		}	if( ISPTR(t1) || ISARY(t1) ) q = p->in.right;	else q = p->in.left;	if( !ISPTR(q->in.type) && !ISARY(q->in.type) ){		if( q->in.op != ICON || q->tn.lval != 0 ){			werror( "illegal combination of pointer and integer, op %s",				opst[p->in.op] );			}		}	else {		d1 = p->in.left->fn.cdim;		d2 = p->in.right->fn.cdim;		for( ;; ){			if( t1 == t2 ) {;				if( p->in.left->fn.csiz != p->in.right->fn.csiz ) {					werror( "illegal structure pointer combination" );					}				return;				}			if( ISARY(t1) || ISPTR(t1) ){				if( !ISARY(t2) && !ISPTR(t2) ) break;				if( ISARY(t1) && ISARY(t2) && dimtab[d1] != dimtab[d2] ){					werror( "illegal array size combination" );					return;					}				if( ISARY(t1) ) ++d1;				if( ISARY(t2) ) ++d2;				}			else break;			t1 = DECREF(t1);			t2 = DECREF(t2);			}		werror( "illegal pointer combination" );		}	}NODE *stref( p ) register NODE *p; {	TWORD t;	int d, s, dsc, align;	OFFSZ off;	register struct symtab *q;	/* make p->x */	/* this is also used to reference automatic variables */	q = &stab[p->in.right->tn.rval];	p->in.right->in.op = FREE;	p->in.op = FREE;	p = pconvert( p->in.left );	/* make p look like ptr to x */	if( !ISPTR(p->in.type)){		p->in.type = PTR+UNIONTY;		}	t = INCREF( q->stype );	d = q->dimoff;	s = q->sizoff;	p = makety( p, t, d, s ); 	p->in.typattr = INCATTR(q->stypattr);	/* compute the offset to be added */	off = q->offset;	dsc = q->sclass;	if( dsc & FIELD ) {  /* normalize offset */		align = ALINT;		s = INT;		off = (off/align)*align;		}	if( off != 0 ) p = clocal( block( PLUS, p, offcon( off, t, d, s ), t, d, s ) );	p = buildtree( UNARY MUL, p, NIL );	/* if field, build field info */	if( dsc & FIELD ){		p = block( FLD, p, NIL, q->stype, 0, q->sizoff );		p->tn.rval = PKFIELD( dsc&FLDSIZ, q->offset%align );		}	return( clocal(p) );	}notlval(p) register NODE *p; {	/* return 0 if p an lvalue, 1 otherwise */	again:	switch( p->in.op ){	case FLD:		p = p->in.left;		goto again;	case UNARY MUL:		/* fix the &(a=b) bug, given that a and b are structures */		if( p->in.left->in.op == STASG ) return( 1 );		/* and the f().a bug, given that f returns a structure */		if( p->in.left->in.op == UNARY STCALL ||		    p->in.left->in.op == STCALL ) return( 1 );	case NAME:	case OREG:		if (ISARY(p->in.type) || ISFTN(p->in.type))		   return(1);	case REG:		return(0);	default:		return(1);		}	}NODE *bcon( i ){ /* make a constant node with value i */	register NODE *p;	p = block( ICON, NIL, NIL, INT, 0, INT );	p->tn.lval = i;	p->tn.rval = NONAME;	return( clocal(p) );	}NODE *bpsize(p) register NODE *p; {	return( offcon( psize(p), p->in.type, p->fn.cdim, p->fn.csiz ) );	}OFFSZpsize( p ) NODE *p; {	/* p is a node of type pointer; psize returns the	   size of the thing pointed to */	if( !ISPTR(p->in.type) ){		uerror( "pointer required");		return( SZINT );		}	/* note: no pointers to fields */	return( tsize( DECREF(p->in.type), p->fn.cdim, p->fn.csiz ) );	}NODE *convert( p, f )  register NODE *p; {	/*  convert an operand of p	    f is either CVTL or CVTR	    operand has type int, and is converted by the size of the other side	    */	register NODE *q, *r;	q = (f==CVTL)?p->in.left:p->in.right;	r = block( PMCONV,		q, bpsize(f==CVTL?p->in.right:p->in.left), INT, 0, INT );	r = clocal(r);	if( f == CVTL )		p->in.left = r;	else		p->in.right = r;	return(p);	}#ifndef econverteconvert( p ) register NODE *p; {	/* change enums to ints, or appropriate types */	register TWORD ty;	if( (ty=BTYPE(p->in.type)) == ENUMTY || ty == MOETY ) {		if( dimtab[ p->fn.csiz ] == SZCHAR ) ty = CHAR;		else if( dimtab[ p->fn.csiz ] == SZINT ) ty = INT;		else if( dimtab[ p->fn.csiz ] == SZSHORT ) ty = SHORT;		else ty = LONG;		ty = ctype( ty );		p->fn.csiz = ty;		MODTYPE(p->in.type,ty);		if( p->in.op == ICON && ty != LONG )			p->in.type = p->fn.csiz = INT;		}	}#endifNODE *pconvert( p ) register NODE *p; {	/* if p should be changed into a pointer, do so */	if( ISARY( p->in.type) ){		p->in.type = DECREF( p->in.type );		++p->fn.cdim;		return( buildtree( UNARY AND, p, NIL ) );		}	if( ISFTN( p->in.type) )		return( buildtree( UNARY AND, p, NIL ) );	return( p );	}NODE *oconvert(p) register NODE *p; {	/* convert the result itself: used for pointer and unsigned */	switch(p->in.op) {	case LE:	case LT:	case GE:	case GT:		if( ISUNSIGNED(p->in.left->in.type) || ISUNSIGNED(p->in.right->in.type) )  p->in.op += (ULE-LE);	case EQ:	case NE:		return( p );	case MINUS:		return(  clocal( block( PVCONV,			p, bpsize(p->in.left), INT, 0, INT ) ) );		}	cerror( "illegal oconvert: %d", p->in.op );	return(p);	}NODE *ptmatch(p)  register NODE *p; {	/* makes the operands of p agree; they are	   either pointers or integers, by this time */	/* with MINUS, the sizes must be the same */	/* with COLON, the types must be the same */ 	TWORD ta, t1, t2, t;	int o, d2, d, s2, s;	o = p->in.op;	t = t1 = p->in.left->in.type;	t2 = p->in.right->in.type; 	ta = p->in.left->in.typattr;	d = p->in.left->fn.cdim;	d2 = p->in.right->fn.cdim;	s = p->in.left->fn.csiz;	s2 = p->in.right->fn.csiz;	switch( o ){	case ASSIGN:	case RETURN:	case CAST:		{  break; }	case MINUS:		{  if( psize(p->in.left) != psize(p->in.right) ){			uerror( "illegal pointer subtraction");			}		   break;		   }	case COLON:		{  if( t1 != t2 ) uerror( "illegal types in :");		   break;		   }	default:  /* must work harder: relationals or comparisons */		if( !ISPTR(t1) ){			t = t2;			d = d2;			s = s2;			break;			}		if( !ISPTR(t2) ){			break;			}		/* both are pointers */		if( talign(t2,s2) < talign(t,s) ){			t = t2;			s = s2;			}		break;		}	p->in.left = makety( p->in.left, t, d, s );	p->in.right = makety( p->in.right, t, d, s );	if( o!=MINUS && !logop(o) ){		p->in.type = t;		p->fn.cdim = d;		p->fn.csiz = s;		} 	if (o == CAST) p->in.right->in.typattr = ta;	return(clocal(p));	}int tdebug = 0;NODE *tymatch(p)  register NODE *p; {	/* satisfy the types of various arithmetic binary ops */	/* rules are:		if assignment, op, type of LHS		if any float or doubles, make double		if any longs, make long		otherwise, make int		if either operand is unsigned, the result is...	*/	register TWORD t1, t2, t, tu;	register o, u;	o = p->in.op;	t1 = p->in.left->in.type;	t2 = p->in.right->in.type;	if( (t1==UNDEF || t2==UNDEF) && o!=CAST )		uerror("void type illegal in expression");	u = 0;	if( ISUNSIGNED(t1) ){		u = 1;		t1 = DEUNSIGN(t1);		}	if( ISUNSIGNED(t2) ){		u = 1;		t2 = DEUNSIGN(t2);		}	if( ( t1 == CHAR || t1 == SHORT ) && o!= RETURN ) t1 = INT;	if( t2 == CHAR || t2 == SHORT ) t2 = INT;	/* vdp009 - if floating point is not to be promoted 	 * up to double (fflag) we check for that here 	 */ 	if ((fflag) && (t1==DOUBLE || t2==DOUBLE)) 		t = DOUBLE; 	else if ((fflag) && (t1==FLOAT || t2==FLOAT)) 		t = FLOAT;	else if( t1==DOUBLE || t1==FLOAT || t2==DOUBLE || t2==FLOAT )		 t = DOUBLE;	else if( t1==LONG || t2==LONG ) 		t = LONG;	else t = INT;	if( asgop(o) ){		/*		 *  We use the right hand side to determine which operand		 *  must be converted.  This fixes the problem of

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -