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

📄 expr.c

📁 c 语言编译器 源代码- c compiler
💻 C
📖 第 1 页 / 共 3 页
字号:
			return this;		}//error('d',"Nover %n %k",Nover,Nover->tp->base);		base = G_CALL;			/* e1.op(e2) or e1.op() */		e1 = new ref(DOT,e1,Nover);		if (ee1) delete ee1;		return typ(tbl);	}		if (n2 && e1==0) {			/* look for unary operator */		Ptable ctbl = Pclass(n2->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 e2.op() */		}				int mo = over_call(mname,0);/*error('d',"n2%n %d",mname,mo);*/		switch (mo) {		case 0:					if (1 < Nover_coerce) goto am2;			goto glob;		case 1:	if (go == 2) goto glob;			if (go == 1) {			am2:				error("ambiguous operandT%n for%k",n2,b);				tp = any_type;				return this;			}			break;		case 2:			if (go == 2) error("%k defined both as%n and%n",bb,gname,Nover);		}		base = G_CALL;			/* e2.op() */		e1 = new ref(DOT,oe2,Nover);		e2 = 0;		if (ee2) delete ee2;		if (ee1 && ee1!=ee2) delete ee1;		return typ(tbl);			}	glob://error('d',"glob %d",nc);	if (1 < nc) {		error("ambiguous operandTs%t%t for%k",t1,t2,b);		tp = any_type;		return this;	}	if (go) {		if (go == 1) {	/* conversion necessary => binary */			if (n1) {				Pclass cl = (Pclass)n1->tp;				if (cl->conv) error('w',"overloaded%k may be ambiguous",bb);//error('d',"go n1");			}			else if (n2) {				Pclass cl = (Pclass)n2->tp;				if (cl->conv) error('w',"overloaded%k may be ambiguous",bb);//error('d',"bb%k go n2 %n",bb,gname);			}		}		base = G_CALL;			/* op(e1,e2) or op(e1) or op(e2) */		e1 = gname;		e2 = ee1;		return typ(tbl);	}	if (ee2) delete ee2;	if (ee1 && ee1!=ee2) delete ee1;	e2 = oe2;//error('d',"bb%k",bb);	switch(bb) {	case ASSIGN:	case ADDROF:		break;	case CALL:	case DEREF:		if (n1 == 0) break;	default:	/* look for conversions to basic types */	{	int found = 0;		if (n1) {			int val = 0;			Pclass cl = (Pclass)n1->tp;			for ( Pname on = cl->conv; on; on=on->n_list) {//error('d',"oper_coerce n1%n %t",on,(on)?Pfct(on->tp)->returns:0);				Pfct f = (Pfct)on->tp;				if (bb==ANDAND || bb==OROR) {					e1 = check_cond(e1,bb,tbl);					goto not_overloaded;				}				if (n2 				|| (t2 && f->returns->check(t2,ASSIGN)==0)				|| (t2 && t2->check(f->returns,ASSIGN)==0)) {					Ncoerce = on;					val++;				}			}			switch (val) {			case 0:				break;			case 1:			{	Pref r = new ref(DOT,e1,Ncoerce);				Pexpr rr = e1->typ(tbl);				e1 = new expr(G_CALL,rr,0);				found = 1;				break;			}			default:				error('s',"ambiguous coercion of%n to basicT",n1);			}		}		if (n2) {			int val = 0;			Pclass cl = (Pclass)n2->tp;			for ( Pname on = cl->conv; on; on=on->n_list) {//error('d',"oper_coerce n2%n %t",on,(on)?on->tp:0);				Pfct f = (Pfct)on->tp;				if (bb==ANDAND || bb==OROR || bb==NOT) {					e2 = check_cond(e2,bb,tbl);					goto not_overloaded;				}				if (n1 				|| (t1 && f->returns->check(t1,ASSIGN)==0)				|| (t1 && t1->check(f->returns,ASSIGN)==0)) {					Ncoerce = on;					val++;				}			}			switch (val) {			case 0:				break;			case 1:			{	Pref r = new ref(DOT,e2,Ncoerce);				Pexpr rr = r->typ(tbl);				e2 = new expr(G_CALL,rr,0);				found++;				break;			}			default:				error('s',"ambiguous coercion of%n to basicT",n2);			}		}		if (found) {		/*	if (found == 2) error('w',"coercions of operands of%k may be ambiguous",b);*/			return typ(tbl);		}		if (t1 && t2)			error("bad operandTs%t%t for%k",t1,t2,b);		else			error("bad operandT%t for%k",t1?t1:t2,b);		tp = any_type;		return this;	}	}}not_overloaded:	t = (t1==0) ? t2 : (t2==0) ? t1 : 0;/*fprintf(stderr,"%s: e1 %d %d e2 %d %d\n",oper_name(b),e1,e1?e1->base:0,e2,e2?e2->base:0);*/	switch (b) {		/* are the operands of legal types */	case G_CALL:	case CALL:		tp = fct_call(tbl);	/* two calls of use() for e1's names */		if (tp->base == RPTR) return contents();		return this;	case DEREF://error('d',"deref %t",t?t:t1);		if (e1 == dummy) error("O missing before []\n");		if (t) {	/*	*t	*/			t->vec_type();			tp = t->deref();		}		else {					// e1[e2] that is *(e1+e2)			if (t1->vec_type()) {		// e1[e2]				t2->integral(b);				tp = t1->deref();			}			else if (t2->vec_type()) {	// really e2[e1]				t1->integral(b);				tp = t2->deref();			}			else {				error("[] applied to nonPT:%t[%t]",t1,t2);				tp = any_type;			}		}		if (tp->base == RPTR) return contents();		return this;	case G_ADDROF:	case ADDROF:			if (e2->lval(b) == 0) {			tp = any_type;			return this;		}		tp = t->addrof();			/* look for &p->member_function */		switch (e2->base) {		case DOT:		case REF:		{	Pname m = e2->mem;			Pfct f = (Pfct)m->tp;			if (f->base==FCT && (f->f_virtual==0 || m->n_qualifier)) {				DEL(e2);				e2 = m;			}		}		}		return this;	case UMINUS:		t->numeric(b);		tp = t;		return this;	case UPLUS:		t->num_ptr(b);		error('s',"unary + (ignored)");		tp = t;		base = PLUS;		e1 = zero;		return this;	case NOT:		e2 = check_cond(e2,NOT,tbl);		tp = int_type;		return this;	case COMPL:		t->integral(b);		tp = t;		return this;	case INCR:	case DECR:		if (e1) e1->lval(b);		if (e2) e2->lval(b);		r1 = t->num_ptr(b);		tp = t;		return this;		}	if (e1==dummy || e2==dummy || e1==0 || e2==0) error("operand missing for%k",b);	switch (b) {	case MUL:	case DIV:		r1 = t1->numeric(b);		r2 = t2->numeric(b);		nppromote(b);		break;	case MOD:		r1 = t1->integral(b);		r2 = t2->integral(b);		nppromote(b);		break;	case PLUS:		r2 = t2->num_ptr(b);		r1 = t1->num_ptr(b);		if (r1==P && r2==P) error("P +P");		nppromote(b);		tp = t;		break;	case MINUS:		r2 = t2->num_ptr(b);		r1 = t1->num_ptr(b);		if (r2==P && r1!=P && r1!=A) error("P - nonP");		nppromote(b);		tp = t;		break;	case LS:	case RS:	case AND:	case OR:	case ER:		switch (e1->base) {		case LT:		case LE:		case GT:		case GE:		case EQ:		case NE:			error('w',"%kE as operand for%k",e1->base,b);		}		switch (e2->base) {		case LT:		case LE:		case GT:		case GE:		case EQ:		case NE:			error('w',"%kE as operand for%k",e2->base,b);		}		r1 = t1->integral(b);		r2 = t2->integral(b);		nppromote(b);		break;	case LT:	case LE:	case GT:	case GE:	case EQ:	case NE:		r1 = t1->num_ptr(b);		r2 = t2->num_ptr(b);		npcheck(b);		t = int_type;		break;	case ANDAND:	case OROR:		e1 = check_cond(e1,b,tbl);		e2 = check_cond(e2,b,tbl);//		if (st2 != st3) error('s',"needs temporaryV to evaluateE after \"%k\" (please use ifS)",b);		t = int_type;		break;	case QUEST:		{		Pname c1, c2;		cond = check_cond(cond,b,tbl);//		if (st1 != st2) error('s',"needs temporaryV to evaluateE after \"?\" (please use ifS)");//		if (st2 != st3) error('s',"needs temporaryV to evaluateE after \":\" (please use ifS)");		// still doesn't do complete checking for possible conversions...		if (t1==t2		|| (	(c1=t1->is_cl_obj())			&& (c2=t2->is_cl_obj())			&& (c1->tp==c2->tp)		))			t = t1;		else {			r1 = t1->num_ptr(b);			r2 = t2->num_ptr(b);//error('d',"r1 %d r2 %d",r1,r2);			if (r1==FCT && r2==FCT) {	// fudge				if (t1->check(t2,ASSIGN)) error("badTs in ?:E: %t and %t",t1,t2);				t = t1;			}			else				nppromote(b);//error('d',"t: %d %t   t1: %d %t   t2: %d %t",t,t,t1,t1,t2,t2);			if (t!=t1 && t->check(t1,0)) {				e1 = new texpr(CAST,t,e1);				e1->tp = t;			}			if (t!=t2 && t->check(t2,0)) {				e2 = new texpr(CAST,t,e2);				e2->tp = t;			}					}		}		break;	case ASPLUS:		r1 = t1->num_ptr(b);		r2 = t2->num_ptr(b);		if (r1==P && r2==P) error("P +=P");		nppromote(b);		goto ass;	case ASMINUS:		r1 = t1->num_ptr(b);		r2 = t2->num_ptr(b);		if (r2==P && r1!=P && r1!=A) error("P -= nonP");		nppromote(b);		goto ass;	case ASMUL:	case ASDIV:		r1 = t1->numeric(b);		r2 = t1->numeric(b);		nppromote(b);		goto ass;	case ASMOD:		r1 = t1->integral(b);		r2 = t2->integral(b);		nppromote(b);		goto ass;	case ASAND:	case ASOR:	case ASER:	case ASLS:	case ASRS:		r1 = t1->integral(b);		r2 = t2->integral(b);		npcheck(b);		t = int_type;		goto ass;	ass:		as_type = t;	/* the type of the rhs */		t2 = t;	case ASSIGN:		if (e1->lval(b) == 0) {			tp = any_type;			return this;		}	lkj:		switch (t1->base) {		case INT:		case CHAR:		case SHORT:			if (e2->base==ICON && e2->tp==long_type)				error('w',"long constant assigned to%k",t1->base);		case LONG:			if (b==ASSIGN			&& Pbase(t1)->b_unsigned			&& e2->base==UMINUS			&& e2->e2->base==ICON)				error('w',"negative assigned to unsigned");			break;		case TYPE:			t1 = Pbase(t1)->b_name->tp;			goto lkj;		case COBJ:		{	Pname c1 = t1->is_cl_obj();			if (c1) {				Pname c2 = t2->is_cl_obj();//error('d',"%t=%t %d %d",t1,t2,c1,c2);				if (c1 != c2) {					e2 = new expr(ELIST,e2,0);					e2 = new texpr(VALUE,t1,e2);					e2->e2 = e1;					e2 = e2->typ(tbl);					*this = *e2;					tp = t1;					return this;				}				else {	// check for bitwise copy					Pclass cl = Pclass(c1->tp);//error('d',"bit %d",cl->bit_ass);					if (cl->bit_ass == 0)						error('s',"bitwise copy: %s has a member with operator=()",cl->string);					else if (cl->itor && cl->has_dtor())						error('w',"bitwise copy: %s has destructor and %s(%s&) but not assignment",cl->string,cl->string,cl->string);					}			}			break;		}		case PTR:/*error('d',"ptr %d %d",t1,t1?t1->base:0);*/		{	Pfct ef = Pfct(Pptr(t1)->typ);			if (ef->base == FCT) {				Pfct f;				Pname n = 0;				switch (e2->base) {				case NAME:					f = (Pfct)e2->tp;					n = Pname(e2);					switch (f->base) {					case FCT:					case OVERLOAD:						e2 = new expr(G_ADDROF,0,e2);						e2->tp = f;					}					goto ad;				case DOT:				case REF:/*error('d',"dot %d %d",e2->mem->tp,e2->mem->tp?e2->mem->tp->base:0);*/					f = (Pfct)e2->mem->tp;					switch (f->base) {					case FCT:					case OVERLOAD:						n = Pname(e2->mem);						e2 = new expr(G_ADDROF,0,e2);						e2 = e2->typ(tbl);					}					goto ad;				case ADDROF:				case G_ADDROF:					f = (Pfct)e2->e2->tp;				ad:					if (f->base == OVERLOAD) {						Pgen g = (Pgen)f;						n = g->find(ef);						if (n == 0) {							error("cannot deduceT for &overloaded %s()",g->string);							tp = any_type;						}						else							tp = t1;						e2->e2 = n;						n->lval(ADDROF);						return this;					}					if (n) n->lval(ADDROF);				}			}			break;		}		}		{	Pname cn;			int i;			if ((cn=t2->is_cl_obj())			&& (i=can_coerce(t1,t2))			&& Ncoerce) {				if (1 < i) error("%d possible conversions for assignment",i);//error('d',"%t =%t",t1,t2);				Pclass cl = (Pclass)cn->tp;				Pref r = new ref(DOT,e2,Ncoerce);				Pexpr rr = r->typ(tbl);				Pexpr c = new expr(G_CALL,rr,0);				c->fct_name = Ncoerce;				c->tp = t1;				e2 = c;					tp = t1;					return this;			}		}//error('d',"check(%t,%t)",e1->tp,t2);		if (e1->tp->check(t2,ASSIGN)) error("bad assignmentT:%t =%t",e1->tp,t2);				t = e1->tp;				/* the type of the lhs */		break;	case CM:		t = t2;		break;	default:		error('i',"unknown operator%k",b);	}	tp = t;	return this;}

⌨️ 快捷键说明

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