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

📄 reader.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
		order( p2, INTBREG|INTAREG );		goto again;	case ASSIGN:		if( setasg( p ) ) goto again;		goto nomat;	case BITYPE:		if( setbin( p ) ) goto again;		/* try to replace binary ops by =ops */		switch(o){		case PLUS:		case MINUS:		case MUL:		case DIV:		case MOD:		case AND:		case OR:		case ER:		case LS:		case RS:			p->op = ASG o;			goto again;			}		goto nomat;		}	cleanup:	/* if it is not yet in the right state, put it there */	if( cook & FOREFF ){		reclaim( p, RNULL, 0 );		return;		}	if( p->op==FREE ) return;	if( tshape( p, cook ) ) return;	if( (m=match(p,cook) ) == MDONE ) return;	/* we are in bad shape, try one last chance */	if( lastchance( p, cook ) ) goto again;	goto nomat;	}int callflag;int fregs;store( p ) register NODE *p; {	/* find a subtree of p which should be stored */	register o, ty;	o = p->op;	ty = optype(o);	if( ty == LTYPE ) return;	switch( o ){	case UNARY CALL:	case UNARY FORTCALL:	case UNARY STCALL:		++callflag;		break;	case UNARY MUL:		if( asgop(p->left->op) ) stoasg( p->left, UNARY MUL );		break;	case CALL:	case FORTCALL:	case STCALL:		store( p->left );		stoarg( p->right, o );		++callflag;		return;	case COMOP:		markcall( p->right );		if( p->right->su > fregs ) SETSTO( p, INTEMP );		store( p->left );		return;	case ANDAND:	case OROR:	case QUEST:		markcall( p->right );		if( p->right->su > fregs ) SETSTO( p, INTEMP );	case CBRANCH:   /* to prevent complicated expressions on the LHS from being stored */	case NOT:		constore( p->left );		return;		}	if( ty == UTYPE ){		store( p->left );		return;		}	if( asgop( p->right->op ) ) stoasg( p->right, o );	if( p->su>fregs ){ /* must store */		mkadrs( p );  /* set up stotree and stocook to subtree				 that must be stored */		}	store( p->right );	store( p->left );	}constore( p ) register NODE *p; {	/* store conditional expressions */	/* the point is, avoid storing expressions in conditional	   conditional context, since the evaluation order is predetermined */	switch( p->op ) {	case ANDAND:	case OROR:	case QUEST:		markcall( p->right );	case NOT:		constore( p->left );		return;		}	store( p );	}markcall( p ) register NODE *p; {  /* mark off calls below the current node */	again:	switch( p->op ){	case UNARY CALL:	case UNARY STCALL:	case UNARY FORTCALL:	case CALL:	case STCALL:	case FORTCALL:		++callflag;		return;		}	switch( optype( p->op ) ){	case BITYPE:		markcall( p->right );	case UTYPE:		p = p->left;		/* eliminate recursion (aren't I clever...) */		goto again;	case LTYPE:		return;		}	}stoarg( p, calltype ) register NODE *p; {	/* arrange to store the args */	if( p->op == CM ){		stoarg( p->left, calltype );		p = p->right ;		}	if( calltype == CALL ){		STOARG(p);		}	else if( calltype == STCALL ){		STOSTARG(p);		}	else {		STOFARG(p);		}	callflag = 0;	store(p);# ifndef NESTCALLS	if( callflag ){ /* prevent two calls from being active at once  */		SETSTO(p,INTEMP);		store(p); /* do again to preserve bottom up nature....  */		}#endif	}int negrel[] = { NE, EQ, GT, GE, LT, LE, UGT, UGE, ULT, ULE } ;  /* negatives of relationals */cbranch( p, true, false ) NODE *p; {	/* evaluate p for truth value, and branch to true or false	/* accordingly: label <0 means fall through */	register o, lab, flab, tlab;	lab = -1;	switch( o=p->op ){	case ULE:	case ULT:	case UGE:	case UGT:	case EQ:	case NE:	case LE:	case LT:	case GE:	case GT:		if( true < 0 ){			o = p->op = negrel[ o-EQ ];			true = false;			false = -1;			}#ifndef NOOPT		if( p->right->op == ICON && p->right->lval == 0 && p->right->name[0] == '\0' ){			switch( o ){			case UGT:			case ULE:				o = p->op = (o==UGT)?NE:EQ;			case EQ:			case NE:			case LE:			case LT:			case GE:			case GT:				if( logop(p->left->op) ){					/* strange situation: e.g., (a!=0) == 0 */					/* must prevent reference to p->left->lable, so get 0/1 */					/* we could optimize, but why bother */					codgen( p->left, INAREG|INBREG );					}				codgen( p->left, FORCC );				cbgen( o, true, 'I' );				break;			case UGE:				cbgen( 0, true, 'I' );  /* unconditional branch */			case ULT:				;   /* do nothing for LT */				}			}		else#endif			{			p->label = true;			codgen( p, FORCC );			}		if( false>=0 ) cbgen( 0, false, 'I' );		reclaim( p, RNULL, 0 );		return;	case ANDAND:		lab = false<0 ? getlab() : false ;		cbranch( p->left, -1, lab );		cbranch( p->right, true, false );		if( false < 0 ) deflab( lab );		p->op = FREE;		return;	case OROR:		lab = true<0 ? getlab() : true;		cbranch( p->left, lab, -1 );		cbranch( p->right, true, false );		if( true < 0 ) deflab( lab );		p->op = FREE;		return;	case NOT:		cbranch( p->left, false, true );		p->op = FREE;		break;	case COMOP:		codgen( p->left, FOREFF );		p->op = FREE;		cbranch( p->right, true, false );		return;	case QUEST:		flab = false<0 ? getlab() : false;		tlab = true<0 ? getlab() : true;		cbranch( p->left, -1, lab = getlab() );		cbranch( p->right->left, tlab, flab );		deflab( lab );		cbranch( p->right->right, true, false );		if( true < 0 ) deflab( tlab);		if( false < 0 ) deflab( flab );		p->right->op = FREE;		p->op = FREE;		return;	case ICON:		if( p->type != FLOAT && p->type != DOUBLE ){			if( p->lval || p->name[0] ){				/* addresses of C objects are never 0 */				if( true>=0 ) cbgen( 0, true, 'I' );				}			else if( false>=0 ) cbgen( 0, false, 'I' );			p->op = FREE;			return;			}		/* fall through to default with other strange constants */	default:		/* get condition codes */		codgen( p, FORCC );		if( true >= 0 ) cbgen( NE, true, 'I' );		if( false >= 0 ) cbgen( true >= 0 ? 0 : EQ, false, 'I' );		reclaim( p, RNULL, 0 );		return;		}	}rcount(){ /* count recursions */	if( ++nrecur > NRECUR ){		cerror( "expression causes compiler loop: try simplifying" );		}	}eprint( p, down, a, b ) NODE *p; int *a, *b; {	*a = *b = down+1;	while( down >= 2 ){		printf( "\t" );		down -= 2;		}	if( down-- ) printf( "    " );	printf( "%o) %s", p, opst[p->op] );	switch( p->op ) { /* special cases */	case REG:		printf( " %s", rnames[p->rval] );		break;	case ICON:	case NAME:	case OREG:		printf( " " );		adrput( p );		break;	case STCALL:	case UNARY STCALL:	case STARG:	case STASG:		printf( " size=%d", p->stsize );		printf( " align=%d", p->stalign );		break;		}	printf( ", " );	tprint( p->type );	printf( ", " );	if( p->rall == NOPREF ) printf( "NOPREF" );	else {		if( p->rall & MUSTDO ) printf( "MUSTDO " );		else printf( "PREF " );		printf( "%s", rnames[p->rall&~MUSTDO]);		}	printf( ", SU= %d\n", p->su );	}# ifndef NOMAINNODE *eread(){	/* call eread recursively to get subtrees, if any */	register NODE *p;	register i, c;	register char *pc;	register j;	i = rdin( 10 );	p = talloc();	p->op = i;	i = optype(i);	if( i == LTYPE ) p->lval = rdin( 10 );	if( i != BITYPE ) p->rval = rdin( 10 );	p->type = rdin(8 );	p->rall = NOPREF;  /* register allocation information */	if( p->op == STASG || p->op == STARG || p->op == STCALL || p->op == UNARY STCALL ){		p->stsize = (rdin( 10 ) + (SZCHAR-1) )/SZCHAR;		p->stalign = rdin(10) / SZCHAR;		if( getchar() != '\n' ) cerror( "illegal \n" );		}	else {   /* usual case */		if( p->op == REG ) rbusy( p->rval, p->type );  /* non usually, but sometimes justified */		for( pc=p->name,j=0; ( c = getchar() ) != '\n'; ++j ){			if( j < NCHNAM ) *pc++ = c;			}		if( j < NCHNAM ) *pc = '\0';		}	/* now, recursively read descendents, if any */	if( i != LTYPE ) p->left = eread();	if( i == BITYPE ) p->right = eread();	return( p );	}CONSZrdin( base ){	register sign, c;	CONSZ val;	sign = 1;	val = 0;	while( (c=getchar()) > 0 ) {		if( c == '-' ){			if( val != 0 ) cerror( "illegal -");			sign = -sign;			continue;			}		if( c == '\t' ) break;		if( c>='0' && c<='9' ) {			val *= base;			if( sign > 0 )				val += c-'0';			else				val -= c-'0';			continue;			}		cerror( "illegal character `%c' on intermediate file", c );		break;		}	if( c <= 0 ) {		cerror( "unexpected EOF");		}	return( val );	}# endif#ifndef FIELDOPS	/* do this if there is no special hardware support for fields */ffld( p, down, down1, down2 ) NODE *p; int *down1, *down2; {	 /* look for fields that are not in an lvalue context, and rewrite them... */	register NODE *shp;	register s, o, v, ty;	*down1 =  asgop( p->op );	*down2 = 0;	if( !down && p->op == FLD ){ /* rewrite the node */		if( !rewfld(p) ) return;		ty = (szty(p->type) == 2)? LONG: INT;		v = p->rval;		s = UPKFSZ(v);# ifdef RTOLBYTES		o = UPKFOFF(v);  /* amount to shift */# else		o = szty(p->type)*SZINT - s - UPKFOFF(v);  /* amount to shift */#endif		/* make & mask part */		p->left->type = ty;		p->op = AND;		p->right = talloc();		p->right->op = ICON;		p->right->rall = NOPREF;		p->right->type = ty;		p->right->lval = 1;		p->right->rval = 0;		p->right->name[0] = '\0';		p->right->lval <<= s;		p->right->lval--;		/* now, if a shift is needed, do it */		if( o != 0 ){			shp = talloc();			shp->op = RS;			shp->rall = NOPREF;			shp->type = ty;			shp->left = p->left;			shp->right = talloc();			shp->right->op = ICON;			shp->right->rall = NOPREF;			shp->right->type = ty;			shp->right->rval = 0;			shp->right->lval = o;  /* amount to shift */			shp->right->name[0] = '\0';			p->left = shp;			/* whew! */			}		}	}#endiforeg2( p ) register NODE *p; {	/* look for situations where we can turn * into OREG */	NODE *q;	register i;	register r;	register char *cp;	register NODE *ql, *qr;	CONSZ temp;	if( p->op == UNARY MUL ){		q = p->left;		if( q->op == REG ){			temp = q->lval;			r = q->rval;			cp = q->name;			goto ormake;			}		if( q->op != PLUS && q->op != MINUS ) return;		ql = q->left;		qr = q->right;#ifdef R2REGS		/* look for doubly indexed expressions */		if( q->op==PLUS && qr->op==REG && ql->op==REG &&				(szty(ql->type)==1||szty(qr->type)==1) ) {			temp = 0;			cp = ql->name;			if( *cp ){				if( *qr->name ) return;				}			else {				cp = qr->name;				}			if( szty(qr->type)>1) r = R2PACK(qr->rval,ql->rval);			else r = R2PACK(ql->rval,qr->rval);			goto ormake;			}		if( (q->op==PLUS||q->op==MINUS) && qr->op==ICON && ql->op==PLUS &&				ql->left->op==REG &&				ql->right->op==REG ){			temp = qr->lval;			cp = qr->name;			if( q->op == MINUS ){				if( *cp ) return;				temp = -temp;				}			if( *cp ){				if( *ql->name ) return;				}			else {				cp = ql->name;				}			r = R2PACK(ql->left->rval,ql->right->rval);			goto ormake;			}#endif		if( (q->op==PLUS || q->op==MINUS) && qr->op == ICON &&				ql->op==REG && szty(qr->type)==1) {			temp = qr->lval;			if( q->op == MINUS ) temp = -temp;			r = ql->rval;			temp += ql->lval;			cp = qr->name;			if( *cp && ( q->op == MINUS || *ql->name ) ) return;			if( !*cp ) cp = ql->name;			ormake:			if( notoff( p->type, r, temp, cp ) ) return;			p->op = OREG;			p->rval = r;			p->lval = temp;			for( i=0; i<NCHNAM; ++i )				p->name[i] = *cp++;			tfree(q);			return;			}		}	}canon(p) NODE *p; {	/* put p in canonical form */	int oreg2(), sucomp();#ifndef FIELDOPS	int ffld();	fwalk( p, ffld, 0 ); /* look for field operators */# endif	walkf( p, oreg2 );  /* look for and create OREG nodes */#ifdef MYCANON	MYCANON(p);  /* your own canonicalization routine(s) */#endif	walkf( p, sucomp );  /* do the Sethi-Ullman computation */	}

⌨️ 快捷键说明

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