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

📄 trees.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
	p->lval = i;	p->rval = NONAME;	return( clocal(p) );	}NODE *bpsize(p) register NODE *p; {	return( offcon( psize(p), p->type, p->cdim, p->csiz ) );	}OFFSZpsize( p ) NODE *p; {	/* p is a node of type pointer; psize returns the	   size of the thing pointed to */	if( !ISPTR(p->type) ){		uerror( "pointer required");		return( SZINT );		}	/* note: no pointers to fields */	return( tsize( DECREF(p->type), p->cdim, p->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->left:p->right;	r = block( PMCONV,		q, bpsize(f==CVTL?p->right:p->left), INT, 0, INT );	r = clocal(r);	if( f == CVTL )		p->left = r;	else		p->right = r;	return(p);	}econvert( p ) register NODE *p; {	/* change enums to ints, or appropriate types */	register TWORD ty;	if( (ty=BTYPE(p->type)) == ENUMTY || ty == MOETY ) {		if( dimtab[ p->csiz ] == SZCHAR ) ty = CHAR;		else if( dimtab[ p->csiz ] == SZINT ) ty = INT;		else if( dimtab[ p->csiz ] == SZSHORT ) ty = SHORT;		else ty = LONG;		ty = ctype( ty );		p->csiz = ty;		MODTYPE(p->type,ty);		if( p->op == ICON && ty != LONG ) p->type = p->csiz = INT;		}	}NODE *pconvert( p ) register NODE *p; {	/* if p should be changed into a pointer, do so */	if( ISARY( p->type) ){		p->type = DECREF( p->type );		++p->cdim;		return( buildtree( UNARY AND, p, NIL ) );		}	if( ISFTN( p->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->op) {	case LE:	case LT:	case GE:	case GT:		if( ISUNSIGNED(p->left->type) || ISUNSIGNED(p->right->type) )  p->op += (ULE-LE);	case EQ:	case NE:		return( p );	case MINUS:		return(  clocal( block( PVCONV,			p, bpsize(p->left), INT, 0, INT ) ) );		}	cerror( "illegal oconvert: %d", p->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 t1, t2, t;	int o, d2, d, s2, s;	o = p->op;	t = t1 = p->left->type;	t2 = p->right->type;	d = p->left->cdim;	d2 = p->right->cdim;	s = p->left->csiz;	s2 = p->right->csiz;	switch( o ){	case ASSIGN:	case RETURN:	case CAST:		{  break; }	case MINUS:		{  if( psize(p->left) != psize(p->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->left = makety( p->left, t, d, s );	p->right = makety( p->right, t, d, s );	if( o!=MINUS && !logop(o) ){		p->type = t;		p->cdim = d;		p->csiz = s;		}	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->op;	t1 = p->left->type;	t2 = p->right->type;	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;	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) ){		tu = p->left->type;		t = t1;		}	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->left = makety( p->left, tu, 0, (int)tu );	if( t != t2 || o==CAST ) p->right = makety( p->right, tu, 0, (int)tu );	if( asgop(o) ){		p->type = p->left->type;		p->cdim = p->left->cdim;		p->csiz = p->left->csiz;		}	else if( !logop(o) ){		p->type = tu;		p->cdim = 0;		p->csiz = t;		}	if( tdebug ) printf( "tymatch(%o): %o %s %o => %o\n",p,t1,opst[o],t2,tu );	return(p);	}NODE *makety( p, t, d, s ) register NODE *p; TWORD t; {	/* make p into type t by inserting a conversion */	if( p->type == ENUMTY && p->op == ICON ) econvert(p);	if( t == p->type ){		p->cdim = d;		p->csiz = s;		return( p );		}	if( t & TMASK ){		/* non-simple type */		return( block( PCONV, p, NIL, t, d, s ) );		}	if( p->op == ICON ){		if( t==DOUBLE||t==FLOAT ){			p->op = FCON;			if( ISUNSIGNED(p->type) ){				p->dval = /* (unsigned CONSZ) */ p->lval;				}			else {				p->dval = p->lval;				}			p->type = p->csiz = t;			return( clocal(p) );			}		}	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->op = o;	p->left = l;	p->right = r;	p->type = t;	p->cdim = d;	p->csiz = s;	return(p);	}icons(p) register NODE *p; {	/* if p is an integer constant, return its value */	int val;	if( p->op != ICON ){		uerror( "constant expected");		val = 1;		}	else {		val = p->lval;		if( val != p->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 */opact( p )  NODE *p; {	register mt12, mt1, mt2, o;	mt12 = 0;	switch( optype(o=p->op) ){	case BITYPE:		mt12=mt2 = moditype( p->right->type );	case UTYPE:		mt12 &= (mt1 = moditype( p->left->type ));		}	switch( o ){	case NAME :	case STRING :	case ICON :	case FCON :	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:	case NOT:	case CBRANCH:	case ANDAND:	case OROR:		return( 0 );	case MUL:	case DIV:		if( mt12 & MDBI ) 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( TYPL+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( mt2&MENU ) return( TYPR+NCVTR );		return( TYPR );	case STREF:		return( NCVT+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( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );		else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN );		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 );		else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+CVTR );		else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+CVTL );		}	uerror( "operands of %s have incompatible types", opst[o] );	return( NCVT );	}moditype( ty ) TWORD ty; {	switch( ty ){	case ENUMTY:	case MOETY:		return( MENU );	case STRTY:	case UNIONTY:		return( MSTR );	case CHAR:	case SHORT:	case UCHAR:	case USHORT:		return( MINT|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->type, p->cdim, p->csiz )/SZCHAR;	tfree(p);	if( i <= 0 ) werror( "sizeof returns 0" );	return( bcon( i ) );	}eprint( 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->op );	printf("%o) %s, ", p, opst[p->op] );	if( ty == LTYPE ){		printf( CONFMT, p->lval );		printf( ", %d, ", p->rval );		}	tprint( p->type );	printf( ", %d, %d\n", p->cdim, p->csiz );	}prtdcon( p ) register NODE *p; {	int i;	if( p->op == FCON ){		locctr( DATA );		defalign( ALDOUBLE );		deflab( i = getlab() );		fincode( p->dval, SZDOUBLE );		p->lval = 0;		p->rval = -i;		p->type = DOUBLE;		p->op = NAME;		}	}int edebug = 0;ecomp( p ) register NODE *p; {	if( edebug ) fwalk( p, eprint, 0 );	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->op);	printf( "%d\t", p->op );	if( ty == LTYPE ) {		printf( CONFMT, p->lval );		printf( "\t" );		}	if( ty != BITYPE ) {		if( p->op == NAME || p->op == ICON ) printf( "0\t" );		else printf( "%d\t", p->rval );		}	printf( "%o\t", p->type );	/* handle special cases */	switch( p->op ){	case NAME:	case ICON:		/* print external name */		if( p->rval == NONAME ) printf( "\n" );		else if( p->rval >= 0 ){			q = &stab[p->rval];			printf(  "%s\n", exname(q->sname) );			}		else { /* label */			printf( LABFMT, -p->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->left not a field... */		printf( CONFMT, (CONSZ) tsize( STRTY, p->left->cdim, p->left->csiz ) );		printf( "\t%d\t\n", talign( STRTY, p->left->csiz ) );		break;	default:		printf(  "\n" );		}	if( ty != LTYPE ) prtree( p->left );	if( ty == BITYPE ) prtree( p->right );	}# elsep2tree(p) register NODE *p; {	register ty;# ifdef MYP2TREE	MYP2TREE(p);  /* local action can be taken here; then return... */# endif	ty = optype(p->op);	switch( p->op ){	case NAME:	case ICON:		if( p->rval == NONAME ) p->name[0] = '\0';		else if( p->rval >= 0 ){ /* copy name from exname */			register char *cp;			register i;			cp = exname( stab[p->rval].sname );			for( i=0; i<NCHNAM; ++i ) p->name[i] = *cp++;			}		else sprintf( p->name, LABFMT, -p->rval );		break;	case STARG:	case STASG:	case STCALL:	case UNARY STCALL:		/* set up size parameters */		p->stsize = (tsize(STRTY,p->left->cdim,p->left->csiz)+SZCHAR-1)/SZCHAR;		p->stalign = talign(STRTY,p->left->csiz)/SZCHAR;		break;	case REG:		rbusy( p->rval, p->type );	default:		p->name[0] = '\0';		}	p->rall = NOPREF;	if( ty != LTYPE ) p2tree( p->left );	if( ty == BITYPE ) p2tree( p->right );	}# endif# endif

⌨️ 快捷键说明

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