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

📄 trees.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
# include "mfile1"/*	some special actions, used in finding the type of nodes */# define NCVT 01# define PUN 02# define TYPL 04# define TYPR 010# define TYMATCH 040# define LVAL 0100# define CVTO 0200# define CVTL 0400# define CVTR 01000# define PTMATCH 02000# define OTHER 04000# define NCVTR 010000/* node conventions:	NAME:	rval>0 is stab index for external		rval<0 is -inlabel number		lval is offset in bits	ICON:	lval has the value		rval has the STAB index, or - label number,			if a name whose address is in the constant		rval = NONAME means no name	REG:	rval is reg. identification cookie	*/int bdebug = 0;NODE *buildtree( o, l, r ) register NODE *l, *r; {	register NODE *p, *q;	register actions;	register opty;	register struct symtab *sp;	register NODE *lr, *ll;	int i;	extern int eprint();	if( bdebug ) printf( "buildtree( %s, %o, %o )\n", opst[o], l, r );	opty = optype(o);	/* check for constants */	if( opty == UTYPE && l->op == ICON ){		switch( o ){		case NOT:			if( hflag ) werror( "constant argument to NOT" );		case UNARY MINUS:		case COMPL:			if( conval( l, o, l ) ) return(l);			break;			}		}	else if( o==UNARY MINUS && l->op==FCON ){		l->dval = -l->dval;		return(l);		}	else if( o==QUEST && l->op==ICON ) {		l->op = FREE;		r->op = FREE;		if( l->lval ){			tfree( r->right );			return( r->left );			}		else {			tfree( r->left );			return( r->right );			}		}	else if( (o==ANDAND || o==OROR) && (l->op==ICON||r->op==ICON) ) goto ccwarn;	else if( opty == BITYPE && l->op == ICON && r->op == ICON ){		switch( o ){		case ULT:		case UGT:		case ULE:		case UGE:		case LT:		case GT:		case LE:		case GE:		case EQ:		case NE:		case ANDAND:		case OROR:		case CBRANCH:		ccwarn:			if( hflag ) werror( "constant in conditional context" );		case PLUS:		case MINUS:		case MUL:		case DIV:		case MOD:		case AND:		case OR:		case ER:		case LS:		case RS:			if( conval( l, o, r ) ) {				r->op = FREE;				return(l);				}			break;			}		}	else if( opty == BITYPE && (l->op==FCON||l->op==ICON) &&		(r->op==FCON||r->op==ICON) ){		switch(o){		case PLUS:		case MINUS:		case MUL:		case DIV:			if( l->op == ICON ){				l->dval = l->lval;				}			if( r->op == ICON ){				r->dval = r->lval;				}			l->op = FCON;			l->type = l->csiz = DOUBLE;			r->op = FREE;			switch(o){			case PLUS:				l->dval += r->dval;				return(l);			case MINUS:				l->dval -= r->dval;				return(l);			case MUL:				l->dval *= r->dval;				return(l);			case DIV:				if( r->dval == 0 ) uerror( "division by 0." );				else l->dval /= r->dval;				return(l);				}			}		}	/* its real; we must make a new node */	p = block( o, l, r, INT, 0, INT );	actions = opact(p);	if( actions&LVAL ){ /* check left descendent */		if( notlval(p->left) ) {			uerror( "lvalue required" );			}		}	if( actions & NCVTR ){		p->left = pconvert( p->left );		}	else if( !(actions & NCVT ) ){		switch( opty ){		case BITYPE:			p->right = pconvert( p->right );		case UTYPE:			p->left = pconvert( p->left );			}		}	if( (actions&PUN) && (o!=CAST||cflag) ){		chkpun(p);		}	if( actions & (TYPL|TYPR) ){		q = (actions&TYPL) ? p->left : p->right;		p->type = q->type;		p->cdim = q->cdim;		p->csiz = q->csiz;		}	if( actions & CVTL ) p = convert( p, CVTL );	if( actions & CVTR ) p = convert( p, CVTR );	if( actions & TYMATCH ) p = tymatch(p);	if( actions & PTMATCH ) p = ptmatch(p);	if( actions & OTHER ){		l = p->left;		r = p->right;		switch(o){		case NAME:			sp = &stab[idname];			if( sp->stype == UNDEF ){				uerror( "%.8s undefined", sp->sname );				/* make p look reasonable */				p->type = p->cdim = p->csiz = INT;				p->rval = idname;				p->lval = 0;				defid( p, SNULL );				break;				}			p->type = sp->stype;			p->cdim = sp->dimoff;			p->csiz = sp->sizoff;			p->lval = 0;			p->rval = idname;			/* special case: MOETY is really an ICON... */			if( p->type == MOETY ){				p->rval = NONAME;				p->lval = sp->offset;				p->cdim = 0;				p->type = ENUMTY;				p->op = ICON;				}			break;		case ICON:			p->type = INT;			p->cdim = 0;			p->csiz = INT;			break;		case STRING:			p->op = NAME;			p->type = CHAR+ARY;			p->lval = 0;			p->rval = NOLAB;			p->cdim = curdim;			p->csiz = CHAR;			break;		case FCON:			p->lval = 0;			p->rval = 0;			p->type = DOUBLE;			p->cdim = 0;			p->csiz = DOUBLE;			break;		case STREF:			/* p->x turned into *(p+offset) */			/* rhs must be a name; check correctness */			i = r->rval;			if( i<0 || ((sp= &stab[i])->sclass != MOS && sp->sclass != MOU && !(sp->sclass&FIELD)) ){				uerror( "member of structure or union required" );				}			else {				register j;				if( l->type != PTR+STRTY && l->type != PTR+UNIONTY ){					werror( "struct/union or struct/union pointer required" );					}				else if( (j=l->csiz+1)<0 ) cerror( "undefined structure or union" );				else if( !chkstr( i, dimtab[j], DECREF(l->type) ) ){					werror( "illegal member use: %.8s", stab[i].sname );					}				}			p = stref( p );			break;		case UNARY MUL:			if( l->op == UNARY AND ){				p->op = l->op = FREE;				p = l->left;				}			if( !ISPTR(l->type))uerror("illegal indirection");			p->type = DECREF(l->type);			p->cdim = l->cdim;			p->csiz = l->csiz;			break;		case UNARY AND:			switch( l->op ){			case UNARY MUL:				p->op = l->op = FREE;				p = l->left;			case NAME:				p->type = INCREF( l->type );				p->cdim = l->cdim;				p->csiz = l->csiz;				break;			case COMOP:				lr = buildtree( UNARY AND, l->right, NIL );				p->op = l->op = FREE;				p = buildtree( COMOP, l->left, lr );				break;			case QUEST:				lr = buildtree( UNARY AND, l->right->right, NIL );				ll = buildtree( UNARY AND, l->right->left, NIL );				p->op = l->op = l->right->op = FREE;				p = buildtree( QUEST, l->left, buildtree( COLON, ll, lr ) );				break;			default:				uerror( "unacceptable operand of &" );				break;				}			break;		case LS:		case RS:		case ASG LS:		case ASG RS:			if(tsize(p->right->type, p->right->cdim, p->right->csiz) > SZINT)				p->right = makety(p->right, INT, 0, INT );			break;		case RETURN:		case ASSIGN:		case CAST:			/* structure assignment */			/* take the addresses of the two sides; then make an			/* operator using STASG and			/* the addresses of left and right */			{				register TWORD t;				register d, s;				if( l->csiz != r->csiz ) uerror( "assignment of different structures" );				r = buildtree( UNARY AND, r, NIL );				t = r->type;				d = r->cdim;				s = r->csiz;				l = block( STASG, l, r, t, d, s );				if( o == RETURN ){					p->op = FREE;					p = l;					break;					}				p->op = UNARY MUL;				p->left = l;				p->right = NIL;				break;				}		case COLON:			/* structure colon */			if( l->csiz != r->csiz ) uerror( "type clash in conditional" );			break;		case CALL:			p->right = r = strargs( p->right );		case UNARY CALL:			if( !ISPTR(l->type)) uerror("illegal function");			p->type = DECREF(l->type);			if( !ISFTN(p->type)) uerror("illegal function");			p->type = DECREF( p->type );			p->cdim = l->cdim;			p->csiz = l->csiz;			if( l->op == UNARY AND && l->left->op == NAME &&				l->left->rval >= 0 && l->left->rval != NONAME &&				( (i=stab[l->left->rval].sclass) == FORTRAN || i==UFORTRAN ) ){				p->op += (FORTCALL-CALL);				}			if( p->type == STRTY || p->type == UNIONTY ){				/* function returning structure */				/*  make function really return ptr to str., with * */				p->op += STCALL-CALL;				p->type = INCREF( p->type );				p = buildtree( UNARY MUL, p, NIL );				}			break;		default:			cerror( "other code %d", o );			}		}	if( actions & CVTO ) p = oconvert(p);	p = clocal(p);	if( bdebug ) fwalk( p, eprint, 0 );	return(p);	}NODE *strargs( p ) register NODE *p;  { /* rewrite structure flavored arguments */	if( p->op == CM ){		p->left = strargs( p->left );		p->right = strargs( p->right );		return( p );		}	if( p->type == STRTY || p->type == UNIONTY ){		p = block( STARG, p, NIL, p->type, p->cdim, p->csiz );		p->left = buildtree( UNARY AND, p->left, NIL );		p = clocal(p);		}	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;	if( ddebug > 1 ) printf( "chkstr( %.8s(%d), %d )\n", stab[i].sname, i, j );	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( chkstr( i, dimtab[stab[kk].sizoff+1], stab[kk].stype ) ) 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->lval;	u = ISUNSIGNED(p->type) || ISUNSIGNED(q->type);	if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);	if( p->rval != NONAME && q->rval != NONAME ) return(0);	if( q->rval != NONAME && o!=PLUS ) return(0);	if( p->rval != NONAME && o!=PLUS && o!=MINUS ) return(0);	switch( o ){	case PLUS:		p->lval += val;		if( p->rval == NONAME ){			p->rval = q->rval;			p->type = q->type;			}		break;	case MINUS:		p->lval -= val;		break;	case MUL:		p->lval *= val;		break;	case DIV:		if( val == 0 ) uerror( "division by 0" );		else p->lval /= val;		break;	case MOD:		if( val == 0 ) uerror( "division by 0" );		else p->lval %= val;		break;	case AND:		p->lval &= val;		break;	case OR:		p->lval |= val;		break;	case ER:		p->lval ^=  val;		break;	case LS:		i = val;		p->lval = p->lval << i;		break;	case RS:		i = val;		p->lval = p->lval >> i;		break;	case UNARY MINUS:		p->lval = - p->lval;		break;	case COMPL:		p->lval = ~p->lval;		break;	case NOT:		p->lval = !p->lval;		break;	case LT:		p->lval = p->lval < val;		break;	case LE:		p->lval = p->lval <= val;		break;	case GT:		p->lval = p->lval > val;		break;	case GE:		p->lval = p->lval >= val;		break;	case ULT:		p->lval = (p->lval-val)<0;		break;	case ULE:		p->lval = (p->lval-val)<=0;		break;	case UGE:		p->lval = (p->lval-val)>=0;		break;	case UGT:		p->lval = (p->lval-val)>0;		break;	case EQ:		p->lval = p->lval == val;		break;	case NE:		p->lval = p->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->left->type;	t2 = p->right->type;	if( t1==ENUMTY || t2==ENUMTY ) { /* check for enumerations */		if( logop( p->op ) && p->op != EQ && p->op != NE ) {			uerror( "illegal comparison of enums" );			return;			}		if( t1==ENUMTY && t2==ENUMTY && p->left->csiz==p->right->csiz ) return;		werror( "enumeration type clash, operator %s", opst[p->op] );		return;		}	if( ISPTR(t1) || ISARY(t1) ) q = p->right;	else q = p->left;	if( !ISPTR(q->type) && !ISARY(q->type) ){		if( q->op != ICON || q->lval != 0 ){			werror( "illegal combination of pointer and integer");			}		}	else {		d1 = p->left->cdim;		d2 = p->right->cdim;		for( ;; ){			if( t1 == t2 ) {;				if( p->left->csiz != p->right->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;	OFFSZ off;	register struct symtab *q;	/* make p->x */	/* this is also used to reference automatic variables */	q = &stab[p->right->rval];	p->right->op = FREE;	p->op = FREE;	p = pconvert( p->left );	/* make p look like ptr to x */	if( !ISPTR(p->type)){		p->type = PTR+UNIONTY;		}	t = INCREF( q->stype );	d = q->dimoff;	s = q->sizoff;	p = makety( p, t, d, s );	/* compute the offset to be added */	off = q->offset;	dsc = q->sclass;	if( dsc & FIELD ){ /* make fields look like ints */		off = (off/ALINT)*ALINT;		s = INT;		}	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->rval = PKFIELD( dsc&FLDSIZ, q->offset%ALINT );		}	return( clocal(p) );	}notlval(p) register NODE *p; {	/* return 0 if p an lvalue, 1 otherwise */	again:	switch( p->op ){	case FLD:		p = p->left;		goto again;	case NAME:	case OREG:	case UNARY MUL:		if( ISARY(p->type) || ISFTN(p->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 );

⌨️ 快捷键说明

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