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

📄 expr.c

📁 c 语言编译器 源代码- c compiler
💻 C
📖 第 1 页 / 共 3 页
字号:
				delete c;					return this;			}		}		switch (etp->base) {		case VOID:			if (tt->base == VOID) {				tp = t;				return this;			}			error("cast of void value");		case ANY:			tp = any_type;			return this;		}	legloop:		switch (tt->base) {		case TYPE:				tt = Pbase(tt)->b_name->tp; goto legloop;		case VOID:			switch (etp->base) {			case COBJ:				switch (e1->base) {				case VALUE:				case CALL:				case G_CALL:				{	Pname cln = etp->is_cl_obj();					Pclass cl = (Pclass)cln->tp;					if (cl->has_dtor()) error('s',"cannot castCO to void");				}				}				break;			} 			break;		case PTR:			switch (etp->base) {			case COBJ:				error("cannot castCO toP");				break;			}			break;		case RPTR:		// (x&)e: pretend e is an x			if ((e1->base==CALL || e1->base==G_CALL || e1->lval(0))			&& Pptr(tt)->typ->tsizeof()<=etp->tsizeof()) {//error('d',"%t(%t)",t,etp);				e1 = e1->address();	// *(x*)&e				tp = t;				return contents();			}			else					error(0,"cannot cast%t to%t",etp,t);			break;		case COBJ://error('d',"%n ctor %d",cn,ctor);			base = VALUE;	// (x)e => x(e): construct an x from e			e1 = new expr(ELIST,e1,0);			return typ(tbl);		case CHAR:		case INT:		case SHORT:		case LONG:		case FLOAT:		case DOUBLE:			switch (etp->base) {			case COBJ:				error("cannot castCO to%k",tt->base);				break;			}				break;				}		tp = t;		return this;	}	case VALUE:	{	Ptype tt = tp2;		Pclass cl;		Pname cn;//error('d',"value %d %d (%d %k)",tt,tt?tt->base:0,e1,e1?e1->base:0);				tt->dcl(tbl);	vv://error('d',"vv %d %d",tt,tt?tt->base:0);		switch (tt->base) {		case TYPE:			tt = Pbase(tt)->b_name->tp;			goto vv;		case EOBJ:		default:			if (e1 == 0) {				error("value missing in conversion to%t",tt);				tp = any_type;				return this;			}			base = CAST;			e1 = e1->e1;	// strip ELIST			return typ(tbl);		case CLASS:			cl = (Pclass)tt;			goto nn;		case COBJ:			cn = Pbase(tt)->b_name;			cl = Pclass(cn->tp);		nn:			if (e1 && e1->e2==0) {		/* single argument */				e1->e1 = e1->e1->typ(tbl);				Pname acn=e1->e1->tp->is_cl_obj();//error('d',"acn%n itor%d",acn,acn?cl->itor:0);				if (acn				&& acn->tp==cl				&& cl->has_itor()==0) {					if (e2) {	// x(x_obj) => e2=x_obj						base = ASSIGN;						Pexpr ee = e1->e1;						e1 = e2;						e2 = ee;						tp = tp2;						return this;					}					else		// x(x_obj) => x_obj						return e1->e1;				}			}		{	/* x(a) => obj.ctor(a); where e1==obj */			Pexpr ee;			Pexpr a = e1;			Pname ctor = cl->has_ctor();			if (ctor == 0) {				error("cannot make a%n",cn);				base = SM;				e1 = dummy;				e2 = 0;				return this;			}//error('d',"value %n.%n",e2,ctor);			int tv = 0;			if (e2 == 0) {	/*  x(a) => x temp; (temp.x(a),temp) */				Ptable otbl = tbl;				if (Cstmt) { /*	make Cstmt into a block */					if (Cstmt->memtbl == 0) Cstmt->memtbl = new table(4,tbl,0);					tbl = Cstmt->memtbl;				}				char* s = make_name('V');//error('d',"%s: %d %d",s,otbl,tbl);				Pname n = new name(s);				n->tp = tp2;				n = n->dcl(tbl,ARG); /* no init! */				n->n_scope = FCT;				n->assign();				e2 = n;				ee = new expr(CM,this,n);				tbl = otbl;				tv = 1;			}			else				ee = this;			base = G_CALL;			e1 = new ref(DOT,e2,ctor);			e2 = a;			ee = ee->typ(tbl);//error('d',"ee %t",ee->tp);			if (tv == 0) {	// deref value returned by constructor				ee = new expr(DEREF,ee,0);				ee->tp = ee->e1->tp;			}			return ee;		}		}	}	case NEW:	{	Ptype tt = tp2;		Ptype tx = tt;		bit v = 0;		bit old = new_type;		new_type = 1;/*error('d',"new%t e1 %d %d",tt,e1,e1?e1->base:0);*/		tt->dcl(tbl);		new_type = old;		if (e1) e1 = e1->typ(tbl);	ll://error('d',"tt %d %d",tt,tt?tt->base:0);		switch (tt->base) {		default:			if (e1) {				error("Ir for nonCO created using \"new\"");				e1 = 0;			}			break;		case VEC:			v = 1;			tt = Pvec(tt)->typ;			goto ll;		case TYPE:			tt = Pbase(tt)->b_name->tp;			goto ll;		case COBJ:		{	Pname cn = Pbase(tt)->b_name;			Pclass cl = (Pclass)cn->tp;						if ((cl->defined&(DEFINED|SIMPLIFIED)) == 0) {				error("new%n;%n isU",cn,cn);			}			else {				Pname ctor = cl->has_ctor();				TOK su;				if (ctor) {/*error('d',"cobj%n tp%t",ctor,ctor->tp);*/					if (v) {						Pname ic;						if (e1)							error('s',"Ir forvector ofCO created using \"new\"");						else if ((ic = cl->has_ictor())==0)							error("vector ofC%n that do not have a constructor taking noAs",cn);						else if (Pfct(ic->tp)->nargs)							error('s',"defaultAs for constructor for vector ofC%n",cn);					}					e1 = new call(ctor,e1);					e1 = e1->typ(tbl);					/*(void) e1->fct_call(tbl);*/				}				else if (su=cl->is_simple()) { /*error('d',"simple cobj%k",su);*/					if (e1) error("new%n withIr",cn);				}				else {/*error('d',"not simple and no constructor?");*/				}			}		}		}//error('d',"v==%d",v);		tp = (v) ? (Ptype)tx : (Ptype)new ptr(PTR,tx,0);		return this;	}	case DELETE:	// delete e1 OR delete[e2] e1	{	int i;		if (e1->base == ADDROF) error('w',"delete &E");		e1 = e1->typ(tbl);		i = e1->tp->num_ptr(DELETE);		if (i != P) error("nonP deleted");		if (e2) {			e2 = e2->typ(tbl);			e2->tp->integral(DELETE);		}		tp = void_type;		return this;	}	}	if (e1==0 && e2==0) error('i',"no operands for%k",b);	switch(b) {	case ILIST:	/* an ILIST is pointer to an ELIST */		e1 = e1->typ(tbl);		tp = any_type;		return this;	case ELIST:		{	Pexpr e;			Pexpr ex;			if (e1 == dummy && e2==0) {				error("emptyIrL");				tp = any_type;				return this;			}							for (e=this; e; e=ex) {				Pexpr ee = e->e1;/*error('d',"e %d %d ee %d %d",e,e?e->base:0,ee,ee?ee->base:0);*/				if (e->base != ELIST) error('i',"elist%k",e->base);				if (ex = e->e2) {	/* look ahead for end of list */					if (ee == dummy) error("EX in EL");					if (ex->e1 == dummy && ex->e2 == 0) {						/* { ... , } */						DEL(ex);						e->e2 = ex = 0;					}				}				e->e1 = ee->typ(tbl);				t = e->e1->tp;							}			tp = t;			return this;		}	case DOT:	case REF:	{		Pbase b;		Ptable atbl;		Pname nn;		char* s;		Pclass cl;		e1 = e1->typ(tbl);		t = e1->tp;		if (base == REF) {		xxx://error('d',"xxx %t",t);			switch (t->base) {			case TYPE:	t = Pbase(t)->b_name->tp;	goto xxx;			default:	error("nonP ->%n",mem);			case ANY:	atbl = any_tbl;			goto mm;			case PTR:			case VEC:	b = Pbase(Pptr(t)->typ);	break;			}		}		else {		qqq:			switch (t->base) {			case TYPE:	t = Pbase(t)->b_name->tp;	goto qqq;			default:	error("nonO .%n",mem);			case ANY:	atbl = any_tbl;			goto mm;			case COBJ:	break;			}//error('d',"dot e1 %k %d",e1->base,e1->base);			switch (e1->base) {	/* FUDGE, but cannot use lval (consts) */			case CM:				/* ( ... , x). => ( ... , &x)-> */			{	Pexpr ex = e1;			cfr:	switch (ex->e2->base) {				case NAME:					base = REF;					ex->e2 = ex->e2->address();					goto xde;				case CM:					ex = ex->e2;					goto cfr;				}			}			case CALL:			case G_CALL://error('d',"call%d, %n %d %d",e1->fct_name,e1->fct_name,Pfct(e1->fct_name->tp)->f_inline,Pfct(e1->fct_name->tp)->f_virtual);#ifdef BSD				if (e1->fct_name				&& Pfct(e1->fct_name->tp)->f_inline				&& Pfct(e1->fct_name->tp)->f_virtual==0) break;#else			//	if (e1->fct_name==0			//	|| Pfct(e1->fct_name->tp)->f_inline==0)#endif			{					/* f(). => (tmp=f(),&tmp)-> */					Ptable otbl = tbl;					if (Cstmt) { /*	make Cstmt into a block */						if (Cstmt->memtbl == 0) Cstmt->memtbl = new table(4,tbl,0);						tbl = Cstmt->memtbl;					}					char* s = make_name('T');					Pname tmp = new name(s);					tmp->tp = e1->tp;					tmp = tmp->dcl(tbl,ARG); /* no init! */					tmp->n_scope = FCT;					e1 = new expr(ASSIGN,tmp,e1);					e1->tp = tmp->tp;					Pexpr aa = tmp->address();					e1 = new expr(CM,e1,aa);					e1->tp = aa->tp;					base = REF;					tbl = otbl;				}				break;		//	case QUEST:		//		error("non-lvalue .%n",mem);		//		break;		//	case NAME:		//		Pname(e1)->take_addr();		//		Pname(e1)->use();			}		xde:			b = Pbase(t);		}	xxxx:		switch (b->base) {		case TYPE:	b = (Pbase) b->b_name->tp;	goto xxxx;		default:	error("(%t) before %k%n (%n not aM)",e1->tp,base,mem,mem);		case ANY:	atbl = any_tbl;			goto mm;		case COBJ:			if (atbl = b->b_table) goto mm;			s = b->b_name->string;	/* lookup the class name */			if (s == 0) error('i',"%kN missing",CLASS);//error('d',"lookup %s",s);			nn = tbl->look(s,CLASS);			if (nn == 0) error('i',"%k %sU",CLASS,s);			if (nn != b->b_name) b->b_name = nn;			cl = (Pclass) nn->tp;			PERM(cl);			if (cl == 0) error('i',"%k %s'sT missing",CLASS,s);			b->b_table = atbl = cl->memtbl;		mm:			if (atbl->base != TABLE) error('i',"atbl(%d)",atbl->base);			nn = (Pname)atbl->find_name(mem,2,0);//error('d',"nn%n %d %d",nn,nn->n_stclass,nn->n_scope);			switch (nn->n_stclass) {			case 0:				mem = nn;					tp = nn->tp;				return this;			case STATIC:				return nn;			}		}	}	case CALL:	/* handle undefined function names */		if (e1->base==NAME && e1->tp==0) {//error('d',"call %d %s",e1,e1->string);			e1 = tbl->find_name(Pname(e1),1,e2);		}		break;	case QUEST:		cond = cond->typ(tbl);	}	if (e1) {		e1 = e1->typ(tbl);		if (e1->tp->base == RPTR) e1 = e1->contents();		t1 = e1->tp;	}	else		t1 = 0;	if (e2) {		e2 = e2->typ(tbl);		if (e2->tp->base == RPTR) e2 = e2->contents();		t2 = e2->tp;	}	else 		t2 = 0;	TOK bb;	switch (b) {			/* filter non-overloadable operators out */	default:	bb = b; break;	case DEREF:	bb = (e2) ? DEREF : MUL; break;	case CM:	case QUEST:	case G_ADDROF:	case G_CALL:	goto not_overloaded;	}	Pname n1;	if (e1) {		Ptype tx = t1;		while (tx->base == TYPE) tx = Pbase(tx)->b_name->tp;		n1 = tx->is_cl_obj();	}	else		n1 = 0;	Pname n2;	if (e2) {		Ptype tx = t2;		while (tx->base == TYPE) tx = Pbase(tx)->b_name->tp;		n2 = tx->is_cl_obj();	}	else		n2 = 0;//error('d',"overload %k: %s %s\n", bb, n1?n1->string:"1", n2?n2->string:"2");	if (n1==0 && n2==0) goto not_overloaded;{	/* first try for non-member function:	op(e1,e2) or op(e2) or op(e1) */	Pexpr oe2 = e2;	Pexpr ee2 = (e2 && e2->base!=ELIST) ? e2 = new expr(ELIST,e2,0) : 0;	Pexpr ee1 = (e1) ? new expr(ELIST,e1,e2) : ee2;	char* obb = oper_name(bb);	Pname gname = gtbl->look(obb,0);	int go = gname ? over_call(gname,ee1) : 0;	int nc = Nover_coerce;	// first look at member functions						// then if necessary check for ambiguities	if (go) gname = Nover;//error('d',"global%n go=%d nc=%d",gname,go,nc);	if (n1) {				/* look for member of n1 */			Ptable ctbl = Pclass(n1->tp)->memtbl;		Pname mname = ctbl->look(obb,0);		if (mname == 0) goto glob;		switch (mname->n_scope) {		default:	goto glob;		case 0:		case PUBLIC:	break;		/* try e1.op(?) */		}		int mo = over_call(mname,e2);//error('d',"n1%n %d",mname,mo);		switch (mo) {		case 0:				if (go == 2) goto glob;			if (1 < Nover_coerce) goto am1;			goto glob;		case 1:	if (go == 2) goto glob;			if (go == 1) {			am1:				error("ambiguous operandTs%n%t for%k",n1,t2,b);				tp = any_type;				return this;			}			else {				Pclass cl = (Pclass)n1->tp;				if (cl->conv) error('w',"overloaded%k may be ambiguous",bb);			}			break;		case 2:			if (go == 2) error("%k defined both as%n and%n",bb,gname,Nover);		}//error('d',"%k mtbl %d ctbl %d",bb,mname->n_table,ctbl);		if (bb==ASSIGN && mname->n_table!=ctbl) {	/* inherited = */			//if (n1->tsizeof()!=mname->?)			error("assignment not defined for class%n",n1);			tp = any_type;

⌨️ 快捷键说明

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