trees.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,611 行 · 第 1/3 页

C
1,611
字号
#ifndef	lintstatic char *sccsid ="@(#)trees.c	1.1 (decvax!reilly) 4/27/84";#endif/************************************************************************ * *			Modification History * *	Stephen Reilly, 13-Feb-84 * 002- Fix a coding bug from ( 001 ).  The problem was I thought asgop *	only was true for assign type operations.  Not true the RETURN *	CAST are considered assign typea which causes conversion problems. * *	Stephen Reilly, 20-Jan-84 * 001- Fix the problem with ( int op= real ). The bug was that the *	real was converted to the int rather than the int being  *	converted to real.   * ***********************************************************************//************************************************************************ *									* *			Copyright (c) 1984 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************/# include "mfile1"	    /* corrections when in violation of lint *//*	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;extern ddebug;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();# ifndef BUG1	if( bdebug ) printf( "buildtree( %s, %o, %o )\n", opst[o], l, r );# endif	opty = optype(o);	/* check for constants */	if( opty == UTYPE && l->in.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->in.op==FCON ){		l->fpn.dval = -l->fpn.dval;		return(l);		}	else if( o==QUEST && l->in.op==ICON ) {		l->in.op = FREE;		r->in.op = FREE;		if( l->tn.lval ){			tfree( r->in.right );			return( r->in.left );			}		else {			tfree( r->in.left );			return( r->in.right );			}		}	else if( (o==ANDAND || o==OROR) && (l->in.op==ICON||r->in.op==ICON) ) goto ccwarn;	else if( opty == BITYPE && l->in.op == ICON && r->in.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->in.op = FREE;				return(l);				}			break;			}		}	else if( opty == BITYPE && (l->in.op==FCON||l->in.op==ICON) &&		(r->in.op==FCON||r->in.op==ICON) ){		switch(o){		case PLUS:		case MINUS:		case MUL:		case DIV:			if( l->in.op == ICON ){				l->fpn.dval = l->tn.lval;				}			if( r->in.op == ICON ){				r->fpn.dval = r->tn.lval;				}			l->in.op = FCON;			l->in.type = l->fn.csiz = DOUBLE;			r->in.op = FREE;			switch(o){			case PLUS:				l->fpn.dval += r->fpn.dval;				return(l);			case MINUS:				l->fpn.dval -= r->fpn.dval;				return(l);			case MUL:				l->fpn.dval *= r->fpn.dval;				return(l);			case DIV:				if( r->fpn.dval == 0 ) uerror( "division by 0." );				else l->fpn.dval /= r->fpn.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->in.left) ) {			uerror( "illegal lhs of assignment operator" );			}		}	if( actions & NCVTR ){		p->in.left = pconvert( p->in.left );		}	else if( !(actions & NCVT ) ){		switch( opty ){		case BITYPE:			p->in.right = pconvert( p->in.right );		case UTYPE:			p->in.left = pconvert( p->in.left );			}		}	if( (actions&PUN) && (o!=CAST||cflag) ){		chkpun(p);		}	if( actions & (TYPL|TYPR) ){		q = (actions&TYPL) ? p->in.left : p->in.right;		p->in.type = q->in.type;		p->fn.cdim = q->fn.cdim;		p->fn.csiz = q->fn.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->in.left;		r = p->in.right;		switch(o){		case NAME:			sp = &stab[idname];			if( sp->stype == UNDEF ){#ifndef FLEXNAMES				uerror( "%.8s undefined", sp->sname );#else				uerror( "%s undefined", sp->sname );#endif				/* make p look reasonable */				p->in.type = p->fn.cdim = p->fn.csiz = INT;				p->tn.rval = idname;				p->tn.lval = 0;				defid( p, SNULL );				break;				}			p->in.type = sp->stype;			p->fn.cdim = sp->dimoff;			p->fn.csiz = sp->sizoff;			p->tn.lval = 0;			p->tn.rval = idname;			/* special case: MOETY is really an ICON... */			if( p->in.type == MOETY ){				p->tn.rval = NONAME;				p->tn.lval = sp->offset;				p->fn.cdim = 0;				p->in.type = ENUMTY;				p->in.op = ICON;				}			break;		case ICON:			p->in.type = INT;			p->fn.cdim = 0;			p->fn.csiz = INT;			break;		case STRING:			p->in.op = NAME;			p->in.type = CHAR+ARY;			p->tn.lval = 0;			p->tn.rval = NOLAB;			p->fn.cdim = curdim;			p->fn.csiz = CHAR;			break;		case FCON:			p->tn.lval = 0;			p->tn.rval = 0;			p->in.type = DOUBLE;			p->fn.cdim = 0;			p->fn.csiz = DOUBLE;			break;		case STREF:			/* p->x turned into *(p+offset) */			/* rhs must be a name; check correctness */			i = r->tn.rval;			if( i<0 || ((sp= &stab[i])->sclass != MOS && sp->sclass != MOU && !(sp->sclass&FIELD)) ){				uerror( "member of structure or union required" );				}else			/* if this name is non-unique, find right one */			if( stab[i].sflags & SNONUNIQ &&				(l->in.type==PTR+STRTY || l->in.type == PTR+UNIONTY) &&				(l->fn.csiz +1) >= 0 ){				/* nonunique name && structure defined */				char * memnam, * tabnam;				register k;				int j;				int memi;				j=dimtab[l->fn.csiz+1];				for( ; (memi=dimtab[j]) >= 0; ++j ){					tabnam = stab[memi].sname;					memnam = stab[i].sname;# ifndef BUG1					if( ddebug>1 ){#ifndef FLEXNAMES						printf("member %.8s==%.8s?\n",#else						printf("member %s==%s?\n",#endif							memnam, tabnam);						}# endif					if( stab[memi].sflags & SNONUNIQ ){#ifndef FLEXNAMES						for( k=0; k<NCHNAM; ++k ){							if(*memnam++!=*tabnam)								goto next;							if(!*tabnam++) break;							}#else						if (memnam != tabnam)							goto next;#endif						r->tn.rval = i = memi;						break;						}					next: continue;					}				if( memi < 0 )#ifndef FLEXNAMES					uerror("illegal member use: %.8s",#else					uerror("illegal member use: %s",#endif						stab[i].sname);				}			else {				register j;				if( l->in.type != PTR+STRTY && l->in.type != PTR+UNIONTY ){					if( stab[i].sflags & SNONUNIQ ){						uerror( "nonunique name demands struct/union or struct/union pointer" );						}					else werror( "struct/union or struct/union pointer required" );					}				else if( (j=l->fn.csiz+1)<0 ) cerror( "undefined structure or union" );				else if( !chkstr( i, dimtab[j], DECREF(l->in.type) ) ){#ifndef FLEXNAMES					werror( "illegal member use: %.8s", stab[i].sname );#else					werror( "illegal member use: %s", stab[i].sname );#endif					}				}			p = stref( p );			break;		case UNARY MUL:			if( l->in.op == UNARY AND ){				p->in.op = l->in.op = FREE;				p = l->in.left;				}			if( !ISPTR(l->in.type))uerror("illegal indirection");			p->in.type = DECREF(l->in.type);			p->fn.cdim = l->fn.cdim;			p->fn.csiz = l->fn.csiz;			break;		case UNARY AND:			switch( l->in.op ){			case UNARY MUL:				p->in.op = l->in.op = FREE;				p = l->in.left;			case NAME:				p->in.type = INCREF( l->in.type );				p->fn.cdim = l->fn.cdim;				p->fn.csiz = l->fn.csiz;				break;			case COMOP:				lr = buildtree( UNARY AND, l->in.right, NIL );				p->in.op = l->in.op = FREE;				p = buildtree( COMOP, l->in.left, lr );				break;			case QUEST:				lr = buildtree( UNARY AND, l->in.right->in.right, NIL );				ll = buildtree( UNARY AND, l->in.right->in.left, NIL );				p->in.op = l->in.op = l->in.right->in.op = FREE;				p = buildtree( QUEST, l->in.left, buildtree( COLON, ll, lr ) );				break;# ifdef ADDROREG			case OREG:				/* OREG was built in clocal()				 * for an auto or formal parameter				 * now its address is being taken				 * local code must unwind it				 * back to PLUS/MINUS REG ICON				 * according to local conventions				 */				{				extern NODE * addroreg();				p->in.op = FREE;				p = addroreg( l );				}				break;# endif			default:				uerror( "unacceptable operand of &" );				break;				}			break;		case LS:		case RS:		case ASG LS:		case ASG RS:			if(tsize(p->in.right->in.type, p->in.right->fn.cdim, p->in.right->fn.csiz) > SZINT)				p->in.right = makety(p->in.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->fn.csiz != r->fn.csiz ) uerror( "assignment of different structures" );				r = buildtree( UNARY AND, r, NIL );				t = r->in.type;				d = r->fn.cdim;				s = r->fn.csiz;				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);	}NODE *strargs( p ) register NODE *p;  { /* rewrite structure flavored arguments */	if( p->in.op == CM ){

⌨️ 快捷键说明

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