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

📄 expr.c

📁 c 语言编译器 源代码- c compiler
💻 C
📖 第 1 页 / 共 3 页
字号:
/* @(#) expr.c 1.6 1/27/86 17:48:51 */ /*ident	"@(#)cfront:src/expr.c	1.6" *//***************************************************************************	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.expr.c:	type check expressions************************************************************************/#include "cfront.h"#include "size.h"int const_save;Pexpr expr.address(){	if (base==DEREF && e2==0) return e1;	/* &* */	if (base == CM) {		e2 = e2->address();		return this;	}	register Pexpr ee = new expr(G_ADDROF,0,this);	ee->tp = new ptr(PTR,tp,0);	if (base == NAME) Pname(this)->take_addr();	return ee;}Pexpr expr.contents(){	if (base==ADDROF || base==G_ADDROF) return e2;		/* *& */	register Pexpr ee = new expr(DEREF,this,0);	if (tp) ee->tp = Pptr(tp)->typ;		/* tp==0 ??? */	return ee;}Pexpr table.find_name(register Pname n, bit f, Pexpr/* args*/)/*	find the true name for "n", implicitly define if undefined	if "n" was called f==1 and "args" were its argument list	if n was qualified r->n or o.n  f==2*/{	Pname q = n->n_qualifier;	register Pname qn = 0;	register Pname nn;	Pclass cl;	/* class specified by q */	if (n->n_table) {		nn = n;		n = 0;		goto xx;	}	if (q) {		Ptable tbl;//error('d',"qq %n %n",q,n);		if (q == sta_name)			tbl = gtbl;		else {			Ptype t = Pclass(q->tp);			if (t == 0) error('i',"Qr%n'sT missing",q);			if (q->base == TNAME) {				if (t->base != COBJ) {					error("badT%k forQr%n",t->base,q);					goto nq;				}				t = Pbase(t)->b_name->tp;			}			if (t->base != CLASS) {				error("badQr%n(%k)",q,t->base);				goto nq;			}			cl = Pclass(t);			tbl = cl->memtbl;		}		qn = tbl->look(n->string,0);//error('d',"qn == %d",qn);		if (qn == 0) {			n->n_qualifier = 0;			nn = 0;			goto def;		}		if (q == sta_name) {	/* explicitly global */			qn->use();			delete n;			return qn;		}		/* else check visibility */	}nq:	if (cc->tot) {	{	for (Ptable tbl = this;;) {	// loop necessary to get past						// local re-definitions			nn = tbl->lookc(n->string,0);//error('d',"cc->tot:%n nn=%n sto%k sco%k tbl=%d",n,nn,nn->n_stclass,nn->n_scope,tbl);			if (nn == 0) goto qq;	/* try for friend */			switch (nn->n_scope) {			case 0:			case PUBLIC:				if (nn->n_stclass == ENUM) break;				if (nn->tp->base == OVERLOAD) break;				if (Ebase				&& cc->cot->clbase				&& Ebase!=cc->cot->clbase->tp				&& !Ebase->has_friend(cc->nof))					error("%n is from a privateBC",n);				if (Epriv				&& Epriv!=cc->cot				&& !Epriv->has_friend(cc->nof))					error("%n is private",n);			}			if (qn==0 || qn==nn) break;			if ((tbl=tbl->next) == 0) {	/* qn/cl test necessary? */				if (/* (qn->n_stclass==STATIC					|| qn->tp->base==FCT					|| qn->tp->base==OVERLOAD)				&&  */ (	qn->n_scope==PUBLIC					|| cl->has_friend(cc->nof)) ) {					/*qn->use();					delete n;					return qn;					*/					nn = qn;					break;				}				else {					error("QdN%n not in scope",n);					goto def;				}			}		}	}	xx://error('d',"xx: nn=%n qn=%n n=%n f=%d",nn,qn,n,f);		if (nn == 0) goto def;		nn->use();		if (f == 2) {			if (qn && nn->n_stclass==0)				switch (nn->n_scope) {				case 0:				case PUBLIC:	/* suppress virtual */					switch (qn->tp->base) {					case FCT:					case OVERLOAD:						*n = *qn;						n->n_qualifier = q;						return n;					}				}			if (nn->n_table == gtbl) error("MF%n not found",n);			if (n) delete n;			return nn;		}		switch (nn->n_scope) {		case 0:		case PUBLIC://error('d',"st %d th %d",nn->n_stclass,cc->c_this);			if (nn->n_stclass == 0) {				if (qn)	{	/* suppress virtual */					switch (qn->tp->base) {					case FCT:					case OVERLOAD:						*n = *qn;						n->n_qualifier = q;						/*return n; */						nn = n;						n = 0;					}				}				if (cc->c_this == 0) {					switch (nn->n_oper) {					case CTOR:					case DTOR:						break;					default:						/* in static member initializer */						error("%n cannot be used here",nn);						return nn;					}				}				Pref r = new ref(REF,cc->c_this,nn);				cc->c_this->use();				r->tp = nn->tp;				if (n) delete n;				return r;			}		default:			if (n) delete n;			return nn;		}	}qq://error('d',"qq: n%n qn%d",n,qn);	if (qn) {		// check for p->base::mem :			// nasty where derived::mem is public			// and base::mem is private		// NOT DONE	/* static member? */		if (qn->n_scope==0  && !cl->has_friend(cc->nof) ) {			error("%n is private",qn);			if (n) delete n;			return qn;		}		switch (qn->n_stclass) {		case STATIC:			break;		default:			switch (qn->tp->base) {			case FCT:			case OVERLOAD:	/* suppress virtual */				if (f == 1) error("O missing for%n",qn);				*n = *qn;				n->n_qualifier = q;				return n;			default:				if (f != 2) error("O missing for%n",qn);			}		}		if (n) delete n;		return qn;	}	if ( nn = lookc(n->string,0) ) {		switch (nn->n_scope) {		case 0:		case PUBLIC:			if (nn->n_stclass == ENUM) break;			if (nn->tp->base == OVERLOAD) break;			if (Ebase && !Ebase->has_friend(cc->nof) )				error("%n is from privateBC",n);			if (Epriv && !Epriv->has_friend(cc->nof) )				error("%n is private",n);		}	}	if (nn) {//error('d',"found %n",nn);		if (f==2 && nn->n_table==gtbl) error("MF%n not found",n);		nn->use();		if (n) delete n;		return nn;	}def:	/* implicit declaration *///error('d',"implicit f %d",f);	n->n_qualifier = 0;	if (f == 1) {	/* function */		if (n->tp) error('i',"find_name(fct_type?)");		n->tp = new fct(defa_type,0,0);		n->n_sto = EXTERN;	/*	if (fct_void) {			n->tp = new fct(defa_type,0,0);		}		else {			Pexpr e;			Pname at = 0;			Pname att;						for (e=args; e; e=e->e2) {				Pname ar = new name;				if (e->base != ELIST) error('i',"badA %k",e->base);				e->e1 = e->e1->typ(this);				ar->tp = e->e1->base==STRING ? Pchar_type : e->e1->tp;				switch (ar->tp->base) {				case ZTYPE:					ar->tp = defa_type;					break;				case FIELD:					ar->tp = int_type;					break;				case ANY:				default:					PERM(ar->tp);				}				if (at)					att->n_list = ar;				else					at = ar;				att = ar;			}			n->tp = new fct(defa_type,at,1);		}	*/	}	else {		n->tp = any_type;		if (this != any_tbl)			if (cc->not			&&  (cc->cot->defined&(DEFINED|SIMPLIFIED)) == 0)				error("C%n isU",cc->not);			else				error("%n isU",n);	}	nn = n->dcl(gtbl,EXTERN);	nn->n_list = 0;	nn->use();	nn->use();	/* twice to cope with "undef = 1;" */	if (n) delete n;	if (f==1)		if (fct_void) {			if  (no_of_undcl++ == 0) undcl = nn;		}		else			error('w',"undeclaredF%n called",nn);	return nn;}Pexpr expr.typ(Ptable tbl)/*	find the type of "this" and place it in tp;	return the typechecked version of the expression:	"tbl" provides the scope for the names in "this"*/{if (this == 0) error('i',"0->expr.typ");	Pname n;	Ptype t = 0;	Ptype t1, t2;	TOK b = base;	TOK r1, r2;#define nppromote(b)	t=np_promote(b,r1,r2,t1,t2,1)#define npcheck(b)	(void)np_promote(b,r1,r2,t1,t2,0)	if (tbl->base != TABLE) error('i',"expr.typ(%d)",tbl->base);//if (b == NAME) error('d',"name %d %d %s",this,string,string?string:"?");	if (tp) {/*error('d',"expr.typ %d (checked) tbl=%d",this,tbl);*/		if (b == NAME) Pname(this)->use();		return this;	}//error('d',"expr.typ %d%k e1 %d%k e2 %d%k tbl %d\n",this,base,e1,e1?e1->base:0,e2,e2?e2->base:0,tbl);	switch (b) {		/* is it a basic type */	case DUMMY:		error("emptyE");		tp = any_type;		return this;	case ZERO:		tp = zero_type;		return this;	case IVAL:		tp = int_type;		return this;	case FVAL:		tp = float_type;		return this;	case ICON:		/*	is it long?			explicit long?			decimal larger than largest signed int			octal or hexadecimal larger than largest unsigned int		 */	{	int ll = strlen(string);		switch (string[ll-1]) {		case 'l':		case 'L':		lng:			tp = long_type;			goto save;		}		if  (string[0] == '0') {	/* assume 8 bits in byte */			switch (string[1]) {			case 'x':			case 'X':				if (SZ_INT+SZ_INT < ll-2) goto lng;				goto nrm;			default:				if (BI_IN_BYTE*SZ_INT < (ll-1)*3) goto lng;				goto nrm;			}		}		else {			if (ll</*sizeof(LARGEST_INT)-1*/10) {		nrm:				tp = int_type;				goto save;			}			if (ll>10) goto lng;			char* p = string;			char* q = LARGEST_INT;			do if (*p++>*q++) goto lng; while (*p);		}		goto nrm;	}	case CCON:		tp = char_type;		goto save;	case FCON:		tp = double_type;		goto save;	case STRING:			// type of "as\tdf" is char[6]					// c_strlen counts the terminating '\0'	{	int ll = c_strlen(string);		Pvec v = new vec(char_type,0);		v->size = ll;		tp = v;		goto save;	}	save:/*error('d',"%s const_save %d",string,const_save);*/		if (const_save) {			int ll = c_strlen(string);			char* p = new char[ll];			strcpy(p,string);			string = p;		}		return this;	case THIS:		delete this;		if (cc->tot) {			cc->c_this->use();			return cc->c_this;		}		error("this used in nonC context");		n = new name("this");		n->tp = any_type;		return tbl->insert(n,0); 	case NAME:/*error('d',"name %s",string);*/	{	Pexpr ee = tbl->find_name((Pname)this,0,0);		if (ee->tp->base == RPTR) return ee->contents();		return ee;	}	case SIZEOF:		t = tp2;		if (t) {			t->dcl(tbl);			if (e1 && e1!=dummy) {				e1 = e1->typ(tbl);				DEL(e1);				e1 = dummy;			}		}		else {			e1 = e1->typ(tbl);			tp2 = e1->tp;		}		tp = int_type;		return this;	case CAST:	{			Ptype tt = t = tp2;		tt->dcl(tbl);	zaq:				/* is the cast legal? *///error('d',"tt %d %d",tt,tt?tt->base:0);		switch (tt->base) {		case TYPE:			tt = Pbase(tt)->b_name->tp;	goto zaq;		case RPTR:	// necessary?		case PTR:			if (Pptr(tt)->rdo) error("*const in cast");			tt = Pptr(tt)->typ;			goto zaq;		case VEC:			tt = Pvec(tt)->typ;			goto zaq;		case FCT:			tt = Pfct(tt)->returns;			goto zaq;		default:				if (Pbase(tt)->b_const) error("const in cast");		}		/* now check cast against value, INCOMPLETE *///error('d',"cast e1 %d %k",e1,e1->base);		tt = t;		if (e1 == dummy) {			error("expression missing for cast");			tp = any_type;			return this;		}		e1 = e1->typ(tbl);		Ptype etp = e1->tp;		while (etp->base == TYPE) etp = Pbase(etp)->b_name->tp;				if (etp->base == COBJ) {			int i = can_coerce(tt,etp);//error('d',"cast%t->%t -- %d%n",tt,etp,i,Ncoerce);			if (i==1 && Ncoerce) {				Pname cn = Pbase(etp)->b_name;				Pclass cl = Pclass(cn->tp);				Pref r = new ref(DOT,e1,Ncoerce);				Pexpr rr = r->typ(tbl);				Pexpr c = new expr(G_CALL,rr,0);				c->fct_name = Ncoerce;				c->tp = tt;				*this = *Pexpr(c);

⌨️ 快捷键说明

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