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

📄 norm.c

📁 c 语言编译器 源代码- c compiler
💻 C
📖 第 1 页 / 共 2 页
字号:
		PERM(on->tp);/*fprintf(stderr,"tname %s -> n (%d %d) n->tp (%d %d)\n",string,tn,tn->base,tn->tp,tn->tp->base); fflush(stderr);*/		return tn;	}	default:		error('i',"tname(%s %d %k)",string,this,base);	} }Pname name.normalize(Pbase b, Pblock bl, bit cast)/*	if (bl) : a function definition (check that it really is a type	if (cast) : no name string	for each name on the name list	invert the declarator list(s) and attatch basetype	watch out for class object initializers	convert		struct s { int a; } a;	into		struct s { int a; }; struct s a;*/{	Pname n;	Pname nn;	TOK stc = b->b_sto;	bit tpdf = b->b_typedef;	bit inli = b->b_inline;	bit virt = b->b_virtual;	Pfct f;	Pname nx;	if (b == 0) error('i',"%d->N.normalize(0)",this);	if (this == 0) error('i',"0->N.normalize(%k)",base);	if (inli && stc==EXTERN)  {		error("both extern and inline");		inli = 0;	}//fprintf(stderr,"name.norm(%d %s) tp (%d %d)\n",this,string,tp,tp->base);	if (stc==FRIEND && tp==0) {			/*	friend x;				must be handled during syntax analysis to cope with					class x { friend y; y* p; };				"y" is not local to "x":					class x { friend y; ... }; y* p;				is legal			*/		if (b->base) error(0,"T specified for friend");		if (n_list) {			error("L of friends");			n_list = 0;		}		Pname nx = tname(CLASS);		modified_tn = modified_tn->l;	/* global */		n_sto = FRIEND;		tp = nx->tp;		return this;	}	if (tp	&& n_oper==TNAME	&& tp->base==FCT) {	/* HORRIBLE FUDGE: fix the bad grammar */		Pfct f = (Pfct)tp;		Pfct f2 = (Pfct)f->returns;		if (f2 && f2->base==FCT) {			Pexpr e = f2->argtype;//error('d',"%s: mis-analyzedP toF",string);			if  (e->base == ELIST) {				//	get the real name, fix its type				if (e->e2 || e->e1->base!=DEREF) goto zse1;				Pname rn = (Pname)e->e1->e1;				if (rn->base!=NAME) goto zse1;				f->returns = new ptr(PTR,0);				b = new basetype(TYPE,ktbl->look(string,0));				n_oper = 0;				string = rn->string;				base = NAME;//error('d',"realN %n b==%t",rn,b);			}		}	}zse1:	if (cast) string = "";	b = b->check(this);	switch (b->base) {	//	separate class definitions				//	from object and function type declarations	case COBJ:		nn = b->b_name;//fprintf(stderr,"COBJ (%d %s) -> (%d %d body=%d)\n",nn,nn->string,nn->tp,nn->tp->base,Pclass(nn->tp)->c_body);		if (Pclass(nn->tp)->c_body==2) {	/* first occurrence */			if (tp && tp->base==FCT) {				error('s',&this->where,"%k%n defined as returnT for%n (did you forget a ';' after '}' ?)",Pclass(nn->tp)->csu,nn,this);				nn = this;				break;			}			nn->n_list = this;			Pclass(nn->tp)->c_body = 1;	/* other occurences */		}		else			nn = this;		break;	case EOBJ:		nn = b->b_name;		if (Penum(nn->tp)->e_body==2) {			if (tp && tp->base==FCT) {				error('s',"enum%n defined as returnT for%n (did you forget a ';'?)",nn,this);				nn = this;				break;			}			nn->n_list = this;			Penum(nn->tp)->e_body = 1;		}		else			nn = this;		break;	default:		nn = this;	}	for (n=this; n; n=nx) {		Ptype t = n->tp;		nx = n->n_list;		n->n_sto = stc;/*		if (t		&& n_oper==TNAME		&& t->base==FCT) {	// HORRIBLE FUDGE: fix the bad grammar			Pfct f = (Pfct)t;			Pfct f2 = (Pfct)f->returns;			if (f2 && f2->base==FCT) {				Pexpr e = f2->argtype;				if  (e->base == ELIST) {					// get the real name, fix its type					if (e->e2 || e->e1->base!=DEREF) goto zse;					Pname rn = (Pname)e->e1->e1;					if (rn->base!=NAME) goto zse;					f->returns = new ptr(PTR,0);					b = new basetype(TYPE,ktbl->look(n->string,0));					n->n_oper = 0;					n->string = rn->string;					n->base = NAME;				}			}		}zse:*/		if (n->base == TNAME) error('i',"redefinition ofTN%n",n);		if (t == 0) {			if (bl == 0)				n->tp = t = b;			else {				error("body of nonF%n",n);				t = new fct(defa_type,0,0);			}		}		switch (t->base) {		case PTR:		case RPTR:			n->tp = Pptr(t)->normalize(b);			break;		case VEC:			n->tp = Pvec(t)->normalize(b);			break;		case FCT:			n->tp = Pfct(t)->normalize(b);			break;		case FIELD:			if (n->string == 0) n->string = make_name('F');			n->tp = t;			Pbase tb = b;		flatten://error('d',"flatten %d %d %d",tb->base,b->b_unsigned,b->b_const);			switch (tb->base) {			case TYPE:   /* chase typedefs */				tb = (Pbase)tb->b_name->tp;				goto flatten;			case INT:				Pbase(t)->b_fieldtype = (b->b_unsigned) ? uint_type : int_type;				goto iii;			case CHAR:				Pbase(t)->b_fieldtype = (b->b_unsigned) ? uchar_type : char_type;				goto iii;			case SHORT:				Pbase(t)->b_fieldtype = (b->b_unsigned) ? ushort_type : short_type;				goto iii;			iii:				Pbase(t)->b_unsigned = b->b_unsigned;				Pbase(t)->b_const = b->b_const;				break;			default:				error("non-int field");				n->tp = defa_type;			}			break;		}		f = (Pfct) n->tp;		if (f->base != FCT) {			if (bl) {				error("body for nonF%n",n);				n->tp = f = new fct(defa_type,0,0);				continue;			}			if (inli) error("inline nonF%n",n);			if (virt) error("virtual nonF%n",n);							if (tpdf) {				if (n->n_initializer) {					error("Ir for typedefN%n",n);					n->n_initializer = 0;				}				n->tdef();			}			continue;		}		f->f_inline = inli;		f->f_virtual = virt;			if (tpdf) {			if (f->body = bl) error("typedef%n { ... }",n);			n->tdef();			continue;		}				if (f->body = bl) continue;		/*			Check function declarations.			Look for class object instansiations			The real ambiguity:		; class x fo();				is interpreted as an extern function				declaration NOT a class object with an				empty initializer		*/		{	Pname cn = f->returns->is_cl_obj();			bit clob = (cn || cl_obj_vec);//error('d',"%n: fr%t cn%n",n,f->returns,cn);			if (f->argtype) { /* check argument/initializer list */				Pname nn;				for (nn=f->argtype; nn; nn=nn->n_list) {					if (nn->base != NAME) {						if (!clob) {							error("ATX for%n",n);							goto zzz;						}						goto is_obj;					}/*					if (nn->string) {						error("AN%n inD of%n",nn,n);						nn->string = 0;					}*/					if (nn->tp) goto ok;				}				if (!clob) {					error("FALX");					goto zzz;				}		is_obj://fprintf(stderr,"is_obj: %d %s tp = %d %d\n",this,string,f->returns,f->returns->base); fflush(stderr);				/* it was an initializer: expand to constructor */				n->tp = f->returns;				if (f->argtype->base != ELIST) f->argtype = (Pname)new expr(ELIST,(Pexpr)f->argtype,0);				n->n_initializer = new texpr(VALUE,cn->tp,(Pexpr)f->argtype);				goto ok;			zzz:				if (f->argtype) {					DEL(f->argtype);					f->argtype = 0;					f->nargs = 0;					f->nargs_known = !fct_void;				}			}			else {	/* T a(); => function declaration *//*				if (clob) {					DEL(n->tp);					n->tp = f->returns;				}*/			}		ok:			;		}	}	return nn;}Ptype vec.normalize(Ptype vecof)/**/{	Ptype t = typ;	if (this == 0) error('i',"0->vec.normalize()");	typ = vecof;	if (t == 0) return this;xx:	switch (t->base) {	case TYPE:	t = Pbase(t)->b_name->tp;	goto xx;	case PTR:	case RPTR:	return Pptr(t)->normalize(this);	case VEC:	return Pvec(t)->normalize(this);	case FCT:	return Pfct(t)->normalize(this);	default:	error('i',"bad vectorT(%d)",t->base);	}}Ptype ptr.normalize(Ptype ptrto){	Ptype t = typ;	if (this == 0) error('i',"0->ptr.normalize()");	typ = ptrto;	if (t == 0) {		Pbase b = (Pbase) ptrto;		if (Pfctvec_type		&& rdo==0		&& b->b_unsigned==0		&& b->b_const==0		&& base==PTR) {			switch (b->base) {			case INT:				delete this;				return Pint_type;			case CHAR:				delete this;				return Pchar_type;			case VOID:				delete this;				return Pvoid_type;			case TYPE:				break;			}		}		if (base==RPTR && b->base==VOID) error("void& is not a validT");		return this;	}xx:	switch (t->base) {	case TYPE:	t = Pbase(t)->b_name->tp; goto xx;	case PTR:	case RPTR:	return Pptr(t)->normalize(this);	case VEC:	return Pvec(t)->normalize(this);	case FCT:	return Pfct(t)->normalize(this);	default:	error('i',"badPT(%d)",t->base);	}}Ptype fct.normalize(Ptype ret)/*	normalize return type*/{	register Ptype t = returns;	if (this==0 || ret==0) error('i',"%d->fct.normalize(%d)",this,ret);	returns = ret;	if (t == 0) return this;	if (argtype) {		if (argtype->base != NAME) {			error('i',"syntax: ANX");			argtype = 0;			nargs = 0;			nargs_known = 0;		}/*		else {			Pname n;			for (n=argtype; n; n=n->n_list) {				if (n->string) {					error("N inATL");					n->string = 0;				}			}		}*/			}xx:	switch (t->base) {	case PTR:	case RPTR:	return Pptr(t)->normalize(this);	case VEC:	return Pvec(t)->normalize(this);	case FCT:	return Pfct(t)->normalize(this);	case TYPE:	t = Pbase(t)->b_name->tp;	goto xx;	default:	error('i',"badFT:%k",t->base);	}}	void fct.argdcl(Pname dcl, Pname fn)/*	sort out the argument types for old syntax:			f(a,b) int a; char b; { ... }	beware of			f(a) struct s { int a; }; struct s a;*/{	Pname n;/*fprintf(stderr,"%d argtype %d %d dcl %d %d\n",this, argtype, argtype?argtype->base:0, dcl, dcl?dcl->base:0); fflush(stderr);*/	switch (base) {	case FCT:	break;	case ANY:	return;	default:	error('i',"argdcl(%d)",base);	}	if (argtype) {		switch (argtype->base) {		case NAME:			if (dcl) error("badF definition syntax");			for (n=argtype; n; n=n->n_list) {				if (n->string == 0) n->string = make_name('A');			}			return;		case ELIST:	// expression list:	f(a,b,c) int a; ... { ... }				// scan the elist and build a NAME list		{	Pexpr e;			Pname nn;			Pname tail = 0;			n = 0;			if (old_fct_accepted == 0) error('w',&fn->where,"old style definition of%n",fn);			for (e=Pexpr(argtype); e; e=e->e2) {				Pexpr id = e->e1;				if (id->base != NAME) {					error("NX inAL");					argtype = 0;					dcl = 0;					break;				}				nn = new name(id->string);				if (n)					tail = tail->n_list = nn;				else					tail = n = nn;			}			argtype = n;			break;		}		default:			error("ALX(%d)",argtype->base);			argtype = 0;			dcl = 0;		}	}	else {		nargs_known = !fct_void;		nargs = 0;		if (dcl) error("ADL forF withoutAs");		return;	}	nargs_known = 0;	if (dcl) {		Pname d;		Pname dx;		/*	for each  argument name see if its type is specified			in the declaration list otherwise give it the default type		*/		for (n=argtype; n; n=n->n_list) {			char* s = n->string;			if (s == 0) {				error("AN missing inF definition");				n->string = s = make_name('A');			}			else if (n->tp) error("twoTs forA %s",n->string);			for (d=dcl; d; d=d->n_list) {				if (strcmp(s,d->string) == 0) {					if (d->tp->base == VOID) {						error("voidA%n",d);						d->tp = any_type;					}					n->tp = d->tp;					n->n_sto = d->n_sto;					d->tp = 0;	/* now merged into argtype */					goto xx;				}			}			n->tp = defa_type;		xx:;			if (n->tp == 0) error('i',"noT for %s",n->string);		}			/*	now scan the declaration list for "unused declarations"			and delete it		*/		for (d=dcl; d; d=dx) {			dx = d->n_list;			if (d->tp) {	/* not merged with argtype list */				/*if (d->base == TNAME)  ??? */				switch (d->tp->base) {				case CLASS:				case ENUM:					/* WARNING: this will reverse the order of					   class and enum declarations					*/					d->n_list = argtype;					argtype = d;					break;				default:					 error("%n inADL not inAL",d);				}			}		}	}	/* add default argument types if necessary */	for (n=argtype; n; n=n->n_list) {		if (n->tp == 0) n->tp = defa_type;		nargs++;	}}Pname cl_obj_vec;	/* set if is_cl_obj() found a vector of class objects */Pname eobj;		/* set if is_cl_obj() found an enum */Pname type.is_cl_obj()/*	returns this->b_name if this is a class object	returns 0 and sets cl_obj_vec to this->b_name		if this is a vector of class objects	returns 0 and sets eobj to this->b_name		if this is an enum object	else returns 0*/{	bit v = 0;	register Ptype t = this;	eobj = 0;	cl_obj_vec = 0;xx:	switch (t->base) {	case TYPE:		t = Pbase(t)->b_name->tp;		goto xx;	case COBJ:		if (v) {			cl_obj_vec = Pbase(t)->b_name;			return 0;		}		else			return Pbase(t)->b_name;	case VEC:		t = Pvec(t)->typ;		v=1;		goto xx;	case EOBJ:		eobj = Pbase(t)->b_name;	default:			return 0;	}}

⌨️ 快捷键说明

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