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

📄 trees.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
		 *  (int op= real) where the real is getting converted where		 *  it should not. The ASSIGN is unchanged by this fix.  Only		 *  the op= is effected.		 */		if ( (	      (dope[o]&ASGOPFLG) && 		/* vdp014*/		      o != CAST && o != RETURN) && 		     ( (t == DOUBLE || t==FLOAT) ) )		/* vdp009 slr002 slr001 */		    {		    tu = t;					/* slr001 */  		    }		else						/* slr001 */		    {			    tu = p->in.left->in.type;			/* slr001 */		    }		t = t1;					/* slr001 */	    	}	else {		tu = (u && UNSIGNABLE(t))?ENUNSIGN(t):t;		}	/* because expressions have values that are at least as wide	   as INT or UNSIGNED, the only conversions needed	   are those involving FLOAT/DOUBLE, and those	   from LONG to INT and ULONG to UNSIGNED */	if( t != t1 ) p->in.left = makety( p->in.left, tu, 0, (int)tu );	if( t != t2 || o==CAST ) p->in.right = makety( p->in.right, tu, 0, (int)tu );	if( asgop(o) ){		/*		 *   The mode of the operation is based on the right		 *   side  if (int op= real )		 */		if ( ( (dope[o]&ASGOPFLG) && o != CAST && o != RETURN) &&		        (tu == DOUBLE || tu == FLOAT) ) 	/* vdp009 slr002 */		    {		    p->in.type = p->in.right->in.type;		/* slr002 */		    p->fn.cdim = p->in.right->fn.cdim;		/* slr002 */		    p->fn.csiz = p->in.right->fn.csiz;		/* slr002 */		    }		else		    {		    p->in.type = p->in.left->in.type;		/* slr002 */		    p->fn.cdim = p->in.left->fn.cdim;		/* slr002 */		    p->fn.csiz = p->in.left->fn.csiz;		/* slr002 */		    }		}	else if( !logop(o) ){		p->in.type = tu;		p->fn.cdim = 0;		p->fn.csiz = t;		}# ifndef BUG1	if( tdebug ) printf( "tymatch(%o): %o %s %o => %o\n",p,t1,opst[o],t2,tu );# endif	return(p);	}NODE *makety( p, t, d, s ) register NODE *p; TWORD t; {	/* make p into type t by inserting a conversion */	if ((p->in.type == ENUMTY) && (p->in.op == ICON)){		/* 		 * Go ahead and convert to an integer type (CHAR, SHORT, etc).		 * and then see if we can do any further conversion at compile		 * time.		 */		econvert(p);	}	if( t == p->in.type ){		p->fn.cdim = d;		p->fn.csiz = s;		return( p );		}	if( t & TMASK ){		/* non-simple type */		return( block( PCONV, p, NIL, t, d, s ) );		}	/* vdp009 Separate Floating constant from Double */ 	if( p->in.op == ICON ){		if( t==DOUBLE ){			p->in.op = DCON;			if( ISUNSIGNED(p->in.type) ){				p->dpn.dval = /* (unsigned CONSZ) */ p->tn.lval;				}			else {				p->dpn.dval = p->tn.lval;				}			p->in.type = p->fn.csiz = t;			return( clocal(p) );		}		if (t==FLOAT) {			p->in.op = FCON; 			if ( ISUNSIGNED(p->in.type) ) {				p->fpn.fval = /* (unsigned CONSZ) */ p->tn.lval;				}			else {				p->fpn.fval = p->tn.lval ;			     }			p->in.type = p->fn.csiz = t; 			return (clocal(p) ); 		}		/* dlb015		 * Insert a node to do a scalar conversion, and call clocal		 * to let it perform the conversion/cast of the integer 		 * constant at compile time if possible.		 */		return( clocal(block( SCONV, p, NIL, t, d, s ) ) );	} else if (p->in.op == FCON && t == DOUBLE ) {		double db; 				p->in.op = DCON;		db = p->fpn.fval;		p->dpn.dval = db; 		p->in.type = p->fn.csiz = t; 		return (clocal(p)); 	} else if (p->in.op == DCON && t == FLOAT ) {		if (fflag) {					/*vdp014*/		float fl; 		p->in.op = FCON;		fl = p->dpn.dval; 		if (fl != p->dpn.dval)			werror("float conversion loses precision");				p->fpn.fval=fl;		p->in.type = p->fn.csiz = t; 		return (clocal(p));		}	}		/* dlb015	 * Insert a node to indicate that a scalar conversion/cast will need	 * to be done at some point.  However, clocal can't be called now to	 * do the conversion, since that might lose needed information.	 */	return( block( SCONV, p, NIL, t, d, s ) );	}NODE *block( o, l, r, t, d, s ) register NODE *l, *r; TWORD t; {	register NODE *p;	p = talloc();	p->in.op = o;	p->in.left = l;	p->in.right = r;	p->in.type = t;	p->fn.cdim = d;	p->fn.csiz = s;	if (l != NIL) {	    p->in.typattr = l->in.typattr;	} else {	    p->in.typattr = UNDEF;	}	return(p);	}icons(p) register NODE *p; {	/* if p is an integer constant, return its value */	int val;	if( p->in.op != ICON ){		uerror( "constant expected");		val = 1;		}	else {		val = p->tn.lval;		if( val != p->tn.lval ) uerror( "constant too big for cross-compiler" );		}	tfree( p );	return(val);	}/* 	the intent of this table is to examine the	operators, and to check them for	correctness.	The table is searched for the op and the	modified type (where this is one of the	types INT (includes char and short), LONG,	DOUBLE (includes FLOAT), and POINTER	The default action is to make the node type integer	The actions taken include:		PUN	  check for puns		CVTL	  convert the left operand		CVTR	  convert the right operand		TYPL	  the type is determined by the left operand		TYPR	  the type is determined by the right operand		TYMATCH	  force type of left and right to match, by inserting conversions		PTMATCH	  like TYMATCH, but for pointers		LVAL	  left operand must be lval		CVTO	  convert the op		NCVT	  do not convert the operands		OTHER	  handled by code		NCVTR	  convert the left operand, not the right...	*/# define MINT 01  /* integer */# define MDBI 02   /* integer or double */# define MSTR 04  /* structure */# define MPTR 010  /* pointer */# define MPTI 020  /* pointer or integer */# define MENU 040 /* enumeration variable or member */# define MVOID 0100000 /* void type */opact( p )  NODE *p; {	register mt12, mt1, mt2, o;	mt1 = mt2 = mt12 = 0;	switch( optype(o=p->in.op) ){	case BITYPE:		mt2 = moditype( p->in.right->in.type );	case UTYPE:		mt1 = moditype( p->in.left->in.type );		}	if( ((mt1 | mt2) & MVOID) &&	    o != COMOP &&	    !(o == CAST && (mt1 & MVOID)) ){		/* if lhs of RETURN is void, grammar will complain */		if( o != RETURN )			uerror( "value of void expression used" );		return( NCVT );		}	mt1 &= ~MVOID;	mt2 &= ~MVOID;	mt12 = mt1 & mt2;	switch( o ){	case NAME :	case STRING :	case ICON :	case FCON :	case DCON : 		/*vdp009*/ 	case CALL :	case UNARY CALL:	case UNARY MUL:		{  return( OTHER ); }	case UNARY MINUS:		if( mt1 & MDBI ) return( TYPL );		break;	case COMPL:		if( mt1 & MINT ) return( TYPL );		break;	case UNARY AND:		{  return( NCVT+OTHER ); }	case INIT:	case CM:		return( 0 );	case NOT: 	case CBRANCH:	case ANDAND:	case OROR:		/*RAP004			Don't allow expressions involving structures or unions.		*/		if (o==NOT || o==CBRANCH){			/*Catch void type RAP005 */			if (mt1 == 0){				uerror("void or undef used in value required context");				return(NCVT);				}			if (mt1 != MSTR)				return(0);			}		else {		       /* RAP005 */		       if (mt1==0 || mt2 ==0){				uerror("void or undef used in value required context");				return(NCVT);				}		       if ( mt1 != MSTR && mt2 != MSTR)				return( 0 );		     }		uerror("illegal use of union or structure in conditional expression");		return( NCVT);	case MUL:	case DIV:		if( mt12 & MDBI ) return( TYMATCH );		/* jpm: spr 873 */		if ( (mt1 & MPTI) && (mt2 & MENU)) return( TYMATCH );		if ( (mt2 & MPTI) && (mt1 & MENU)) return( TYMATCH );		break;	case MOD:	case AND:	case OR:	case ER:		if( mt12 & MINT ) return( TYMATCH );		break;	case LS:	case RS:		if( mt12 & MINT ) return( TYMATCH+OTHER );		break;	case EQ:	case NE:	case LT:	case LE:	case GT:	case GE:		if( (mt1&MENU)||(mt2&MENU) ) return( PTMATCH+PUN+NCVT );		if( mt12 & MDBI ) return( TYMATCH+CVTO );		else if( mt12 & MPTR ) return( PTMATCH+PUN );		else if( mt12 & MPTI ) return( PTMATCH+PUN );		else break;	case QUEST:	case COMOP:		if (o==QUEST && mt1 == MSTR){ /*RAP004*/			uerror("illegal use of union or structure in conditional expression");			return( NCVT);			}		if( mt2&MENU ) return( TYPR+NCVTR );		return( TYPR );	case STREF:		return( NCVTR+OTHER );	case FORCE:		return( TYPL );	case COLON:		if( mt12 & MENU ) return( NCVT+PUN+PTMATCH );		else if( mt12 & MDBI ) return( TYMATCH );		else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN );		else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN );		else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN );		else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER );		break;	case ASSIGN:	case RETURN:		if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER );	case CAST:		if(o==CAST && mt1==0)return(TYPL+TYMATCH);		if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );		else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN );		else if(( mt2 == 0 ) && 	/* void (*func)() ? */			(p->in.right->in.op == CALL || 			 p->in.right->in.op == UNARY CALL)) break;		else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN );		else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );		break;	case ASG LS:	case ASG RS:		if( mt12 & MINT ) return( TYPL+LVAL+OTHER );		break;	case ASG MUL:	case ASG DIV:		if( mt12 & MDBI ) return( LVAL+TYMATCH );		break;	case ASG MOD:	case ASG AND:	case ASG OR:	case ASG ER:		if( mt12 & MINT ) return( LVAL+TYMATCH );		break;	case ASG PLUS:	case ASG MINUS:	case INCR:	case DECR:		if( mt12 & MDBI ) return( TYMATCH+LVAL );		else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+LVAL+CVTR );		break;	case MINUS:		if( mt12 & MPTR ) return( CVTO+PTMATCH+PUN );		if( mt2 & MPTR ) break;	case PLUS:		if( mt12 & MDBI ) return( TYMATCH );/* jpm: Fix spr 873; MINT|MENU Allow enums to index an array per K&R */		else if( (mt1&MPTR) && (mt2&(MINT|MENU)) ) return( TYPL+CVTR );		else if( (mt1&(MINT|MENU)) && (mt2&MPTR) ) return( TYPR+CVTL );		}	uerror( "operands of %s have incompatible types", opst[o] );	return( NCVT );	}moditype( ty ) TWORD ty; {	switch(ty){	case TVOID:		return( MPTR );	case UNDEF:		return( MVOID );	case ENUMTY:	case MOETY:		return( MENU );	case STRTY:	case UNIONTY:		return( MSTR );	case CHAR:	case SHORT:	case UCHAR:	case USHORT:		return( MINT|MPTI|MDBI );	case UNSIGNED:	case ULONG:	case INT:	case LONG:		return( MINT|MDBI|MPTI );	case FLOAT:	case DOUBLE:		return( MDBI );	default:		return( MPTR|MPTI );		}	}NODE *doszof( p )  register NODE *p; {	/* do sizeof p */	int i;	/* whatever is the meaning of this if it is a bitfield? */	i = tsize( p->in.type, p->fn.cdim, p->fn.csiz )/SZCHAR;	tfree(p);	if( i <= 0 ) werror( "sizeof returns 0" );	return( bcon( i ) );	}# ifndef BUG2eprint( p, down, a, b ) register NODE *p; int *a, *b; {	register ty;	*a = *b = down+1;	while( down > 1 ){		printf( "\t" );		down -= 2;		}	if( down ) printf( "    " );	ty = optype( p->in.op );	printf("%o) %s, ", p, opst[p->in.op] );	if( ty == LTYPE ){		printf( CONFMT, p->tn.lval );		printf( ", %d, ", p->tn.rval );		}	tprint( p->in.type );	printf( ", %d, %d\n", p->fn.cdim, p->fn.csiz );	}# endifprtdcon( p ) register NODE *p; {	int i;	int o = p->in.op; 		/* print floating point constant, make a distingtion between 	 * single precision and double precision floating point vdp009	 */ 	if( o == FCON || o ==DCON ){		locctr( DATA );		defalign( o == DCON ? ALDOUBLE : ALFLOAT );		deflab( i = getlab() );		if (o == FCON)			fincode( p->fpn.fval, SZFLOAT ); 		else 			fincode( p->dpn.dval, SZDOUBLE ); 		p->tn.lval = 0;		p->tn.rval = -i;		p->in.type = (o == DCON ? DOUBLE : FLOAT);		p->in.op = NAME;		}	}int edebug = 0;ecomp( p ) register NODE *p; {# ifndef BUG2	if( edebug ) fwalk( p, eprint, 0 );# endif	if( !reached ){		werror( "statement not reached" );		reached = 1;		}	p = optim(p);	walkf( p, prtdcon );	locctr( PROG );	ecode( p );	tfree(p);	}# ifdef STDPRTREE# ifndef ONEPASSprtree(p) register NODE *p; {	register struct symtab *q;	register ty;# ifdef MYPRTREE	MYPRTREE(p);  /* local action can be taken here; then return... */#endif	ty = optype(p->in.op);	printf( "%d\t", p->in.op );	if( ty == LTYPE ) {		printf( CONFMT, p->tn.lval );		printf( "\t" );		}	if( ty != BITYPE ) {		if( p->in.op == NAME || p->in.op == ICON ) printf( "0\t" );		else printf( "%d\t", p->tn.rval );		}	printf( "%o\t", p->in.type );	/* handle special cases */	switch( p->in.op ){	case NAME:	case ICON:		/* print external name */		if( p->tn.rval == NONAME ) printf( "\n" );		else if( p->tn.rval >= 0 ){			q = &stab[p->tn.rval];			printf(  "%s\n", exname(q->sname) );			}		else { /* label */			printf( LABFMT, -p->tn.rval );			}		break;	case STARG:	case STASG:	case STCALL:	case UNARY STCALL:		/* print out size */		/* use lhs size, in order to avoid hassles with the structure `.' operator */		/* note: p->in.left not a field... */		printf( CONFMT, (CONSZ) tsize( STRTY, p->in.left->fn.cdim, p->in.left->fn.csiz ) );		printf( "\t%d\t\n", talign( STRTY, p->in.left->fn.csiz ) );		break;	default:		printf(  "\n" );		}	if( ty != LTYPE ) prtree( p->in.left );	if( ty == BITYPE ) prtree( p->in.right );	}# elsep2tree(p) register NODE *p; {	register ty;# ifdef MYP2TREE	MYP2TREE(p);  /* local action can be taken here; then return... */# endif	ty = optype(p->in.op);	switch( p->in.op ){	case NAME:	case ICON:#ifndef FLEXNAMES		if( p->tn.rval == NONAME ) p->in.name[0] = '\0';#else		if( p->tn.rval == NONAME ) p->in.name = "";#endif		else if( p->tn.rval >= 0 ){ /* copy name from exname */			register char *cp;			register i;			cp = exname( stab[p->tn.rval].sname );#ifndef FLEXNAMES			for( i=0; i<NCHNAM; ++i ) p->in.name[i] = *cp++;#else			p->in.name = tstr(cp);#endif			}#ifndef FLEXNAMES		else sprintf( p->in.name, LABFMT, -p->tn.rval );#else		else {			char temp[32];			sprintf( temp, LABFMT, -p->tn.rval );			p->in.name = tstr(temp);		}#endif		break;	case STARG:	case STASG:	case STCALL:	case UNARY STCALL:		/* set up size parameters */		p->stn.stsize = (tsize(STRTY,p->in.left->fn.cdim,p->in.left->fn.csiz)+SZCHAR-1)/SZCHAR;		p->stn.stalign = talign(STRTY,p->in.left->fn.csiz)/SZCHAR;		break;	case REG:		rbusy( p->tn.rval, p->in.type );	default:#ifndef FLEXNAMES		p->in.name[0] = '\0';#else		p->in.name = "";#endif		}	p->in.rall = NOPREF;	if( ty != LTYPE ) p2tree( p->in.left );	if( ty == BITYPE ) p2tree( p->in.right );	}# endif# endif

⌨️ 快捷键说明

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