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

📄 print.c

📁 c 语言编译器 源代码- c compiler
💻 C
📖 第 1 页 / 共 3 页
字号:
/* @(#) print.c 1.7 1/27/86 17:49:19 */ /*ident	"@(#)cfront:src/print.c	1.7" *//**************************************************************************	C++ source for cfront, the C++ compiler front-end	written in the computer science research center of Bell Labs	Copyright (c) 1984 AT&T, Inc. All Rights Reserved	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.print.c:	print the output of simpl, typ, or syn in a form suitable for cc input****************************************************************************/#include "cfront.h"extern FILE* out_file;/*	print the declaration tree*/bit print_mode = 0;extern int ntok; int ntok = 0;int forced_sm = 0;bit Cast = 0;Pin curr_icall;int MAIN = 0;	// fudge to get _main() called by main()void puttok(TOK t)/*	print the output representation of "t"*/{	char * s;	if (t<=0 || MAXTOK<=t) error("illegal token %d",t);	s = keys[t];	if (s == 0) error("V representation token %d",t);	putst(s);	if (12<ntok++) {		forced_sm = 1;		ntok = 0;	/*	putch('\n');*/		last_line.putline();	}	else if (t == SM) {		forced_sm = 1;		ntok = 0;		putch('\n');		last_line.line++;	}}#define MX	20#define NTBUF	10class dcl_buf {	/*		buffer for assembling declaration (or cast)		left contains CONST_PTR	=> *CONST			     CONST_RPTR => &CONST				PTR	=> *				RPTR	=> &				LP	=> (		right contains	RP	=> )				VEC	=> [ rnode ]				FCT	=> ( rnode )				FIELD	=> : rnode	*/	Pbase b;	Pname n;	TOK left[MX], right[MX];	Pnode  rnode[MX];	int li, ri;public:	void	init(Pname nn)		{ b=0; n=nn; li=ri=0; };	void	base(Pbase bb)		{ b = bb; };	void	front(TOK t)		{ left[++li] = t; };	void	back(TOK t, Pnode nod)	{ right[++ri] = t; rnode[ri] = nod; };	void	paran() 		{ front(LP); back(RP,0); };	void	put();} *tbufvec[NTBUF] = {0}, *tbuf = 0;int freetbuf = 0;void dcl_buf.put(){	int i;	if (MX<=li || MX<=ri) error('i',"T buffer overflow");	if (b == 0) error('i',"noBT%s",Cast?" in cast":"");	if (n && n->n_sto) puttok(n->n_sto);	b->dcl_print();		for( ; li; li--) 		switch (left[li]) {		case LP:			puttok(LP);			break;		case CONST_PTR:			puttok(MUL);			if (print_mode != SIMPL) puttok(CONST);			break;		case CONST_RPTR:			if (print_mode == SIMPL)				puttok(MUL);			else				puttok(ADDROF);			if (print_mode != SIMPL) puttok(CONST);			break;		case PTR:			puttok(MUL);			break;		case RPTR:			if (print_mode == SIMPL)				puttok(MUL);			else				puttok(ADDROF);		}	if (n) n->print();	for(i=1; i<=ri; i++)		switch (right[i]) {		case RP:			puttok(RP);			break;		case VEC:			puttok(LB);			{	Pvec v = (Pvec) rnode[i];				Pexpr d = v->dim;				int s = v->size;				if (d) d->print();				if (s) fprintf(out_file,"%d",s);			}			puttok(RB);			break;		case FCT:			{	Pfct f = (Pfct) rnode[i];				f->dcl_print();			}			break;		case FIELD:			{	Pbase f = (Pbase) rnode[i];				Pexpr d = (Pexpr)f->b_name;				int s = f->b_bits;				puttok(COLON);				if (d) d->print();				if (s) fprintf(out_file,"%d",s);			}			break;		}}#define eprint(e) if (e) Eprint(e)void Eprint(Pexpr e){	switch (e->base) {	case DUMMY:		break;	case NAME:	case ID:	case ZERO:	case ICON:	case CCON:	case FCON:	case STRING:	case IVAL:	case TEXT:	case CM:	case ELIST:	case COLON:	case ILIST:	case DOT:	case REF:	case THIS:	case CALL:	case G_CALL:	case ICALL:	case ANAME:		e->print();		break;	default:		puttok(LP);		e->print();		puttok(RP);		break;	}}void name.dcl_print(TOK list)/*	Print the declaration for a name (list==0) or a name list (list!=0):		For each name		(1) print storage class		(2) print base type		(3) print the name with its declarators	Avoid (illegal) repetition of basetypes which are class or enum declarations	(A name list may contain names with different base types)	list == SM :	terminator SM	list == 0:	single declaration with terminator SM	list == CM :	separator CM*/{	Pname n;	if (this == 0) error("0->name.dcl_print()");	for (n=this; n; n=n->n_list) {		Ptype t = n->tp;		int sm = 0;		if (t == 0) error('i',"name.dcl_print(%n)T missing",n);		if (print_mode==SIMPL && n->n_stclass==ENUM) continue;			if (n->n_stclass == STATIC) n->where.putline();		switch (t->base) {		case CLASS:		{	Pclass cl = (Pclass)t;			if (n->base == TNAME) break;			cl->dcl_print(n);			sm = 1;			break;		}		case ENUM:			Penum(t)->dcl_print(n);			sm = 1;			break;		case FCT:		{	Pfct f = (Pfct) t;			if (n->base == TNAME) puttok(TYPEDEF);			if (debug==0 && f->f_inline) {				if (print_mode==SIMPL) {					if (f->f_virtual || n->n_addr_taken) {						TOK st = n->n_sto;						Pblock b = f->body;						f->body = 0;					/*	n->n_sto = 0;	*/						t->dcl_print(n);						n->n_sto = st;						f->body = b;					}				}				else {					if (print_mode != SIMPL)						puttok(INLINE);					else						putst("/* inline */");					t->dcl_print(n);				}			}			else {				if (n->n_table==gtbl && strcmp(n->string,"main")==0) {					MAIN = 1;					gtbl->look("main",0)->use();					t->dcl_print(n);					MAIN = 0;				}				else					t->dcl_print(n);			}			break;		}		case OVERLOAD:		{	Pgen g = (Pgen) t;			Plist gl;			fprintf(out_file,"\t/* overload %s: */\n",g->string);			for (gl=g->fct_list; gl; gl=gl->l) {				Pname nn = gl->f;				nn->dcl_print(0);				sm = 1;			}			break;		}		case ASM:			fprintf(out_file,"asm(\"%s\")\n",(char*)Pbase(t)->b_name);			break;		case INT:		case CHAR:		case LONG:		case SHORT: // do not allocate space for constants unless necessary			if (print_mode==SIMPL			&& Pbase(t)->b_const			&& n->n_sto!=EXTERN	// extern const one;						// const one = 1;						// allocates storage			&& (n->n_scope==EXTERN	// FUDGE const one = 1;						// is treated as static						// need loader support				|| n->n_scope==STATIC				|| n->n_scope==FCT)			) {								if (n->n_evaluated) {					sm = 1;	/* no ; */					break;				}			}		default:		{	Pexpr i = n->n_initializer;			if (n->base == TNAME) puttok(TYPEDEF);//error('d',"%s: init %d %d tbl %d %d sto %d sc %d scope %d\n",n->string?n->string:"",i,i?i->base:0,n->n_table,gtbl,n->n_sto,n->n_stclass,n->n_scope);			if (i) {				if (n->n_sto==EXTERN && n->n_stclass==STATIC) {					n->n_initializer = 0;					t->dcl_print(n);					puttok(SM);					n->n_initializer = i;					n->n_sto = 0;					t->dcl_print(n);					n->n_sto = EXTERN;				}				else					t->dcl_print(n);			}			else {				if (fct_void==0				&& n->n_sto==0				&& n_stclass==STATIC				&& n->n_table==gtbl) {					switch (t->base) {					case CHAR:					case SHORT:					case INT:					case LONG:					case FLOAT:					case DOUBLE:					case EOBJ:					case PTR:						// "int a;" == "int a = 0;"						n->n_initializer = i = zero;					}				}				t->dcl_print(n);			}			if (n->n_scope!=ARG) {				if (i) {					puttok(ASSIGN);					if (t!=i->tp					&& i->base!=ZERO					&& i->base!=ILIST /*&& i->tp!=Pchar_type*/) {						Ptype t1 = n->tp;					cmp://error('d',"t1%t",t1);						switch (t1->base) {						default:							i->print();							break;						case TYPE:								t1 = Pbase(t1)->b_name->tp;							goto cmp;						case VEC:							if (Pvec(t1)->typ->base==CHAR) {								i->print();								break;							}						case PTR:						case RPTR:							puttok(LP);							{	bit oc = Cast;								Cast = 1;								t->print();								Cast = oc;							}							puttok(RP);							eprint(i);						}					}					else						i->print();				}				else if (n->n_evaluated) {					puttok(ASSIGN);					if (n->tp->base != INT) {						puttok(LP);						puttok(LP);						{	bit oc = Cast;							Cast = 1;							n->tp->print();							Cast = oc;						}						fprintf(out_file,")%d)",n->n_val);					}					else						fprintf(out_file,"%d",n->n_val);				}			}		}		}		switch (list) {		case SM:			if (sm==0) puttok(SM);			break;		case 0:			if (sm==0) puttok(SM);			return;		case CM:			if (n->n_list) puttok(CM);			break;		}	}} void name.print()/*	print just the name itself*/{	if (this == 0) error('i',"0->name.print()");	if (string == 0) {		if (print_mode == ERROR) putst(" ?");		return;	}	switch (base) {	default:		error('i',"%d->name.print() base=%d",this,base);	case TNAME:		putst(string);		return;	case NAME:	case ANAME:		break;	}	switch (print_mode) {	case SIMPL:	{	Ptable tbl;		int i = n_union;		if (tp) {			switch (tp->base) {			default:				if (tbl=n_table) {					Pname tn;//fprintf(stderr,"%s: tbl %d gtbl %d\n",string,tbl,gtbl);					if (tbl == gtbl) break;					if (tn=tbl->t_name) {						if (i)							fprintf(out_file,"_%s__O%d.__C%d_",tn->string,i,i);						else							fprintf(out_file,"_%s_",tn->string);						break;					}				}//fprintf(stderr,"%s: stc %d\n",string,n_stclass);				switch (n_stclass) {				case STATIC:				case EXTERN:					if (i)						fprintf(out_file,"_O%d.__C%d_",i,i);					else if (n_sto==STATIC && tp->base!=FCT)						fprintf(out_file,"_static_");					break;				default:					if (i)						fprintf(out_file,"_auto__O%d.__C%d_",i,i);					else						fprintf(out_file,"_auto_");				}				break;			case CLASS:			case ENUM:				break;			}		}		break;	}	case ERROR:	{	Ptable tbl;		char* cs = 0;		bit f = 0;		if (tp) {			switch (tp->base) {			case OVERLOAD:			case FCT:				f = 1;			default:				if (tbl=n_table) {					if (tbl == gtbl) {						if (f == 0) putstring("::");					}					else {						if (tbl->t_name) {							cs = tbl->t_name->string;							fprintf(out_file,"%s::",cs);						}					}				}				if (n_sto==REGISTER				&& n_scope==ARG				&& strcmp(string,"this")==0) {					Ptype tt = Pptr(tp)->typ;					Pname cn = Pbase(tt)->b_name;					fprintf(out_file,"%s::",cn->string);				}				break;			case CLASS:			case ENUM:		//	case TYPE:				break;			}			switch (n_oper) {			case TYPE:				putstring("operator ");				Pfct(tp)->returns->dcl_print(0);				break;			case 0:				putstring(string);				break;			case DTOR:				puttok(COMPL);			case CTOR:				if (cs)					putstring(cs);				else {					putstring("constructor");					f = 0;				}				break;			default:				putstring("operator ");				putstring(keys[n_oper]);				break;			}			if (f) putstring("()");		}		else			if (string) putstring(string);		return;	}	default:		if (n_qualifier) {			n_qualifier->print();			puttok(DOT);		}	}	if (string) putst(string);}void type.print(){/*fprintf(stderr,"type %d %d\n",this,base); fflush(stderr);*/	switch (base) {	case PTR:	case RPTR:		Pptr(this)->dcl_print(0);		break;	case FCT:		Pfct(this)->dcl_print();		break;	case VEC:		Pvec(this)->dcl_print(0);		break;	case CLASS:	case ENUM:		if (print_mode == ERROR)			fprintf(out_file,"%s",base==CLASS?"class":"enum");		else			error('i',"%d->T.print(%k)",this,base);		break;	case TYPE:		if (Cast) {			Pbase(this)->b_name->tp->print();			break;		}	default:		Pbase(this)->dcl_print();	}}char* type.signature(register char* p)/*	take a signature suitable for argument types for overloaded	function names*/{#define SDEL	'_'	Ptype t = this;	int pp = 0;xx:	switch (t->base) {	case TYPE:	t = Pbase(t)->b_name->tp;	goto xx;	case PTR: 	*p++ = 'P';	t = Pptr(t)->typ;	pp=1;	goto xx;	case RPTR:	*p++ = 'R';	t = Pptr(t)->typ;	pp=1;	goto xx;	case VEC:	*p++ = 'V';	t = Pvec(t)->typ;	pp=1;	goto xx;	case FCT:	{	Pfct f = (Pfct)this;		Pname n;		t = (f->s_returns) ? f->s_returns : f->returns;		*p++ = 'F';		for (n=f->argtype; n; n=n->n_list) {			p = n->tp->signature(p);			*p++ = SDEL;		}		*p++ = SDEL;		if (f->nargs_known == ELLIPSIS) *p++ = 'E';		*p =0;		return p;	}	}	if ( Pbase(t)->b_unsigned ) *p++ = 'U';	switch (t->base) {	case ANY:	*p++ = 'A';	break;	case ZTYPE:	*p++ = 'Z';	break;	case VOID:	*p++ = 'V';	break;	case CHAR:	*p++ = (pp)?'C':'I';	break;	case SHORT:	*p++ = (pp)?'S':'I';	break;	case EOBJ:	case INT:	*p++ = 'I';	break;	case LONG:	*p++ = 'L';	break;	case FLOAT:	*p++ = 'F';	break;	case DOUBLE:	*p++ = 'D';	break;	case COBJ:	*p++ = 'C';			strcpy(p,Pbase(t)->b_name->string);

⌨️ 快捷键说明

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