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

📄 reader.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
# include "mfile2"/*	some storage declarations */# ifndef ONEPASSNODE node[TREESZ];char filename[100] = "";  /* the name of the file */int ftnno;  /* number of current function */int lineno;# else# define NOMAIN#endifint nrecur;int lflag;int edebug = 0;int xdebug = 0;int udebug = 0;OFFSZ tmpoff;  /* offset for first temporary, in bits for current block */OFFSZ maxoff;  /* maximum temporary offset over all blocks in current ftn, in bits */int maxtreg;NODE *stotree;int stocook;OFFSZ baseoff = 0;OFFSZ maxtemp = 0;p2init( argc, argv ) char *argv[];{	/* set the values of the pass 2 arguments */	register int c;	register char *cp;	register files;	allo0();  /* free all regs */	files = 0;	for( c=1; c<argc; ++c ){		if( *(cp=argv[c]) == '-' ){			while( *++cp ){				switch( *cp ){				case 'X':  /* pass1 flags */					while( *++cp ) { /* VOID */ }					--cp;					break;				case 'l':  /* linenos */					++lflag;					break;				case 'e':  /* expressions */					++edebug;					break;				case 'o':  /* orders */					++odebug;					break;				case 'r':  /* register allocation */					++rdebug;					break;				case 'a':  /* rallo */					++radebug;					break;				case 't':  /* ttype calls */					++tdebug;					break;				case 's':  /* shapes */					++sdebug;					break;				case 'u':  /* Sethi-Ullman testing (machine dependent) */					++udebug;					break;				case 'x':  /* general machine-dependent debugging flag */					++xdebug;					break;				default:					cerror( "bad option: %c", *cp );					}				}			}		else files = 1;  /* assumed to be a filename */		}	mkdope();	setrew();	return( files );	}# ifndef NOMAINmainp2( argc, argv ) char *argv[]; {	register files;	register temp;	register c;	register char *cp;	register NODE *p;	files = p2init( argc, argv );	tinit();	reread:	if( files ){		while( files < argc && argv[files][0] == '-' ) {			++files;			}		if( files > argc ) return( nerrors );		freopen( argv[files], "r", stdin );		}	while( (c=getchar()) > 0 ) switch( c ){	case ')':		/* copy line unchanged */		while( (c=getchar()) > 0 ){			PUTCHAR(c);			if( c == '\n' ) break;			}		continue;	case '[':		/* beginning of a block */		temp = rdin(10);  /* ftnno */		tmpoff = baseoff = rdin(10); /* autooff for block gives max offset of autos in block */		maxtreg = rdin(10);		if( getchar() != '\n' ) cerror( "intermediate file format error");		if( temp != ftnno ){ /* beginning of function */			maxoff = baseoff;			ftnno = temp;			maxtemp = 0;			}		else {			if( baseoff > maxoff ) maxoff = baseoff;			/* maxoff at end of ftn is max of autos and temps			   over all blocks in the function */			}		setregs();		continue;	case ']':  /* end of block */		SETOFF( maxoff, ALSTACK );		eobl2();		while( (c=getchar()) != '\n' ){			if( c <= 0 ) cerror( "intermediate file format eof" );			}		continue;	case '.':		/* compile code for an expression */		lineno = rdin( 10 );		for( cp=filename; (*cp=getchar()) != '\n'; ++cp ) ; /* VOID, reads filename */		*cp = '\0';		if( lflag ) lineid( lineno, filename );		tmpoff = baseoff;  /* expression at top level reuses temps */		p = eread();		if( edebug ) fwalk( p, eprint, 0 );# ifdef MYREADER		MYREADER(p);  /* do your own laundering of the input */# endif		nrecur = 0;		delay( p );  /* expression statement  throws out results */		reclaim( p, RNULL, 0 );		allchk();		tcheck();		continue;	default:		cerror( "intermediate file format error" );		}	/* EOF */	if( files ) goto reread;	return(nerrors);	}# endif# ifdef ONEPASSp2compile( p ) NODE *p; {	if( lflag ) lineid( lineno, filename );	tmpoff = baseoff;  /* expression at top level reuses temps */	/* generate code for the tree p */	if( edebug ) fwalk( p, eprint, 0 );# ifdef MYREADER	MYREADER(p);  /* do your own laundering of the input */# endif	nrecur = 0;	delay( p );  /* do the code generation */	reclaim( p, RNULL, 0 );	allchk();	/* can't do tcheck here; some stuff (e.g., attributes) may be around from first pass */	/* first pass will do it... */	}p2bbeg( aoff, myreg ) {	static int myftn = -1;	tmpoff = baseoff = aoff;	maxtreg = myreg;	if( myftn != ftnno ){ /* beginning of function */		maxoff = baseoff;		myftn = ftnno;		maxtemp = 0;		}	else {		if( baseoff > maxoff ) maxoff = baseoff;		/* maxoff at end of ftn is max of autos and temps over all blocks */		}	setregs();	}p2bend(){	SETOFF( maxoff, ALSTACK );	eobl2();	}# endifNODE *deltrees[DELAYS];int deli;delay( p ) register NODE *p; {	/* look in all legal places for COMOP's and ++ and -- ops to delay */	/* note; don't delay ++ and -- within calls or things like	/* getchar (in their macro forms) will start behaving strangely */	register i;	/* look for visible COMOPS, and rewrite repeatedly */	while( delay1( p ) ) { /* VOID */ }	/* look for visible, delayable ++ and -- */	deli = 0;	delay2( p );	codgen( p, FOREFF );  /* do what is left */	for( i = 0; i<deli; ++i ) codgen( deltrees[i], FOREFF );  /* do the rest */	}delay1( p ) register NODE *p; {  /* look for COMOPS */	register o, ty;	o = p->op;	ty = optype( o );	if( ty == LTYPE ) return( 0 );	else if( ty == UTYPE ) return( delay1( p->left ) );	switch( o ){	case QUEST:	case ANDAND:	case OROR:		/* don't look on RHS */		return( delay1(p->left ) );	case COMOP:  /* the meat of the routine */		delay( p->left );  /* completely evaluate the LHS */		/* rewrite the COMOP */		{ register NODE *q;			q = p->right;			ncopy( p, p->right );			q->op = FREE;			}		return( 1 );		}	return( delay1(p->left) || delay1(p->right ) );	}delay2( p ) register NODE *p; {	/* look for delayable ++ and -- operators */	register o, ty;	o = p->op;	ty = optype( o );	switch( o ){	case NOT:	case QUEST:	case ANDAND:	case OROR:	case CALL:	case UNARY CALL:	case STCALL:	case UNARY STCALL:	case FORTCALL:	case UNARY FORTCALL:	case COMOP:	case CBRANCH:		/* for the moment, don7t delay past a conditional context, or		/* inside of a call */		return;	case INCR:	case DECR:		if( deltest( p ) ){			if( deli < DELAYS ){				register NODE *q;				deltrees[deli++] = tcopy(p);				q = p->left;				p->right->op = FREE;  /* zap constant */				ncopy( p, q );				q->op = FREE;				return;				}			}		}	if( ty == BITYPE ) delay2( p->right );	if( ty != LTYPE ) delay2( p->left );	}codgen( p, cookie ) NODE *p; {	/* generate the code for p;	   order may call codgen recursively */	/* cookie is used to describe the context */	for(;;){		canon(p);  /* creats OREG from * if possible and does sucomp */		stotree = NIL;		if( edebug ){			printf( "store called on:\n" );			fwalk( p, eprint, 0 );			}		store(p);		if( stotree==NIL ) break;		/* because it's minimal, can do w.o. stores */		order( stotree, stocook );		}	order( p, cookie );	}char *cnames[] = {	"SANY",	"SAREG",	"STAREG",	"SBREG",	"STBREG",	"SCC",	"SNAME",	"SCON",	"SFLD",	"SOREG",	"STARNM",	"STARREG",	"INTEMP",	"FORARG",	"SWADD",	0,	};prcook( cookie ){	/* print a nice-looking description of cookie */	int i, flag;	if( cookie & SPECIAL ){		if( cookie == SZERO ) printf( "SZERO" );		else if( cookie == SONE ) printf( "SONE" );		else if( cookie == SMONE ) printf( "SMONE" );		else printf( "SPECIAL+%d", cookie & ~SPECIAL );		return;		}	flag = 0;	for( i=0; cnames[i]; ++i ){		if( cookie & (1<<i) ){			if( flag ) printf( "|" );			++flag;			printf( cnames[i] );			}		}	}int odebug = 0;order(p,cook) NODE *p; {	register o, ty, m;	int m1;	int cookie;	NODE *p1, *p2;	/* by this time, p should be able to be generated without stores;	   the only question is how */	again:	cookie = cook;	rcount();	canon(p);	rallo( p, p->rall );	if( odebug ){		printf( "order( %o, ", p );		prcook( cookie );		printf( " )\n" );		fwalk( p, eprint, 0 );		}	o = p->op;	ty = optype(o);	/* first of all, for most ops, see if it is in the table */	/* look for ops */	switch( m = p->op ){	default:		/* look for op in table */		for(;;){			if( (m = match( p, cookie ) ) == MDONE ) goto cleanup;			else if( m == MNOPE ){				if( !(cookie = nextcook( p, cookie ) ) ) goto nomat;				continue;				}			else break;			}		break;	case COMOP:	case FORCE:	case CBRANCH:	case QUEST:	case ANDAND:	case OROR:	case NOT:	case UNARY CALL:	case CALL:	case UNARY STCALL:	case STCALL:	case UNARY FORTCALL:	case FORTCALL:		/* don't even go near the table... */		;		}	/* get here to do rewriting if no match or	   fall through from above for hard ops */	p1 = p->left;	if( ty == BITYPE ) p2 = p->right;	else p2 = NIL;		if( odebug ){		printf( "order( %o, ", p );		prcook( cook );		printf( " ), cookie " );		prcook( cookie );		printf( ", rewrite %s\n", opst[m] );		}	switch( m ){	default:		nomat:		cerror( "no table entry for op %s", opst[p->op] );	case COMOP:		codgen( p1, FOREFF );		p2->rall = p->rall;		codgen( p2, cookie );		ncopy( p, p2 );		p2->op = FREE;		goto cleanup;	case FORCE:		/* recurse, letting the work be done by rallo */		p = p->left;		cook = INTAREG|INTBREG;		goto again;	case CBRANCH:		o = p2->lval;		cbranch( p1, -1, o );		p2->op = FREE;		p->op = FREE;		return;	case QUEST:		cbranch( p1, -1, m=getlab() );		p2->left->rall = p->rall;		codgen( p2->left, INTAREG|INTBREG );		/* force right to compute result into same reg used by left */		p2->right->rall = p2->left->rval|MUSTDO;		reclaim( p2->left, RNULL, 0 );		cbgen( 0, m1 = getlab(), 'I' );		deflab( m );		codgen( p2->right, INTAREG|INTBREG );		deflab( m1 );		p->op = REG;  /* set up node describing result */		p->lval = 0;		p->rval = p2->right->rval;		p->type = p2->right->type;		tfree( p2->right );		p2->op = FREE;		goto cleanup;	case ANDAND:	case OROR:	case NOT:  /* logical operators */		/* if here, must be a logical operator for 0-1 value */		cbranch( p, -1, m=getlab() );		p->op = CCODES;		p->label = m;		order( p, INTAREG );		goto cleanup;	case FLD:	/* fields of funny type */		if ( p1->op == UNARY MUL ){			offstar( p1->left );			goto again;			}	case UNARY MINUS:		order( p1, INBREG|INAREG );		goto again;	case NAME:		/* all leaves end up here ... */		if( o == REG ) goto nomat;		order( p, INTAREG|INTBREG );		goto again;	case INIT:		uerror( "illegal initialization" );		return;	case UNARY FORTCALL:		p->right = NIL;	case FORTCALL:		o = p->op = UNARY FORTCALL;		if( genfcall( p, cookie ) ) goto nomat;		goto cleanup;	case UNARY CALL:		p->right = NIL;	case CALL:		o = p->op = UNARY CALL;		if( gencall( p, cookie ) ) goto nomat;		goto cleanup;	case UNARY STCALL:		p->right = NIL;	case STCALL:		o = p->op = UNARY STCALL;		if( genscall( p, cookie ) ) goto nomat;		goto cleanup;		/* if arguments are passed in register, care must be taken that reclaim		/* not throw away the register which now has the result... */	case UNARY MUL:		if( cook == FOREFF ){			/* do nothing */			order( p->left, FOREFF );			p->op = FREE;			return;			}		offstar( p->left );		goto again;	case INCR:  /* INCR and DECR */		if( setincr(p) ) goto again;		/* x++ becomes (x += 1) -1; */		if( cook & FOREFF ){  /* result not needed so inc or dec and be done with it */			/* x++ => x += 1 */			p->op = (p->op==INCR)?ASG PLUS:ASG MINUS;			goto again;			}		p1 = tcopy(p);		reclaim( p->left, RNULL, 0 );		p->left = p1;		p1->op = (p->op==INCR)?ASG PLUS:ASG MINUS;		p->op = (p->op==INCR)?MINUS:PLUS;		goto again;	case STASG:		if( setstr( p ) ) goto again;		goto nomat;	case ASG PLUS:  /* and other assignment ops */		if( setasop(p) ) goto again;		/* there are assumed to be no side effects in LHS */		p2 = tcopy(p);		p->op = ASSIGN;		reclaim( p->right, RNULL, 0 );		p->right = p2;		canon(p);		rallo( p, p->rall );		if( odebug ) fwalk( p, eprint, 0 );		order( p2->left, INTBREG|INTAREG );

⌨️ 快捷键说明

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