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

📄 com.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "cc.h"int compar(Node*, int);voidcomplex(Node *n){	if(n == Z)		return;	nearln = n->lineno;	if(debug['t'])		if(n->op != OCONST)			prtree(n, "pre complex");	if(tcom(n))		return;	if(debug['t'])		if(n->op != OCONST)			prtree(n, "t complex");	ccom(n);	if(debug['t'])		if(n->op != OCONST)			prtree(n, "c complex");	acom(n);	if(debug['t'])		if(n->op != OCONST)			prtree(n, "a complex");	xcom(n);	if(debug['t'])		if(n->op != OCONST)			prtree(n, "x complex");}/* * evaluate types * evaluate lvalues (addable == 1) */enum{	ADDROF	= 1<<0,	CASTOF	= 1<<1,	ADDROP	= 1<<2,};inttcom(Node *n){	return tcomo(n, ADDROF);}inttcomo(Node *n, int f){	Node *l, *r;	Type *t;	int o;	if(n == Z) {		diag(Z, "Z in tcom");		errorexit();	}	n->addable = 0;	l = n->left;	r = n->right;	switch(n->op) {	default:		diag(n, "unknown op in type complex: %O", n->op);		goto bad;	case ODOTDOT:		/*		 * tcom has already been called on this subtree		 */		*n = *n->left;		if(n->type == T)			goto bad;		break;	case OCAST:		if(n->type == T)			break;		if(n->type->width == types[TLONG]->width) {			if(tcomo(l, ADDROF|CASTOF))				goto bad;		} else			if(tcom(l))				goto bad;		if(isfunct(n))			break;		if(tcompat(n, l->type, n->type, tcast))			goto bad;		break;	case ORETURN:		if(l == Z) {			if(n->type->etype != TVOID)				warn(n, "null return of a typed function");			break;		}		if(tcom(l))			goto bad;		typeext(n->type, l);		if(tcompat(n, n->type, l->type, tasign))			break;		constas(n, n->type, l->type);		if(!sametype(n->type, l->type)) {			l = new1(OCAST, l, Z);			l->type = n->type;			n->left = l;		}		break;	case OASI:	/* same as as, but no test for const */		n->op = OAS;		o = tcom(l);		if(o | tcom(r))			goto bad;		typeext(l->type, r);		if(tlvalue(l) || tcompat(n, l->type, r->type, tasign))			goto bad;		if(!sametype(l->type, r->type)) {			r = new1(OCAST, r, Z);			r->type = l->type;			n->right = r;		}		n->type = l->type;		break;	case OAS:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tlvalue(l))			goto bad;		if(isfunct(n))			break;		typeext(l->type, r);		if(tcompat(n, l->type, r->type, tasign))			goto bad;		constas(n, l->type, r->type);		if(!sametype(l->type, r->type)) {			r = new1(OCAST, r, Z);			r->type = l->type;			n->right = r;		}		n->type = l->type;		break;	case OASADD:	case OASSUB:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tlvalue(l))			goto bad;		if(isfunct(n))			break;		typeext1(l->type, r);		if(tcompat(n, l->type, r->type, tasadd))			goto bad;		constas(n, l->type, r->type);		t = l->type;		arith(n, 0);		while(n->left->op == OCAST)			n->left = n->left->left;		if(!sametype(t, n->type) && !mixedasop(t, n->type)) {			r = new1(OCAST, n->right, Z);			r->type = t;			n->right = r;			n->type = t;		}		break;	case OASMUL:	case OASLMUL:	case OASDIV:	case OASLDIV:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tlvalue(l))			goto bad;		if(isfunct(n))			break;		typeext1(l->type, r);		if(tcompat(n, l->type, r->type, tmul))			goto bad;		constas(n, l->type, r->type);		t = l->type;		arith(n, 0);		while(n->left->op == OCAST)			n->left = n->left->left;		if(!sametype(t, n->type) && !mixedasop(t, n->type)) {			r = new1(OCAST, n->right, Z);			r->type = t;			n->right = r;			n->type = t;		}		if(typeu[n->type->etype]) {			if(n->op == OASDIV)				n->op = OASLDIV;			if(n->op == OASMUL)				n->op = OASLMUL;		}		break;	case OASLSHR:	case OASASHR:	case OASASHL:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tlvalue(l))			goto bad;		if(isfunct(n))			break;		if(tcompat(n, l->type, r->type, tand))			goto bad;		n->type = l->type;		if(typeu[n->type->etype]) {			if(n->op == OASASHR)				n->op = OASLSHR;		}		break;	case OASMOD:	case OASLMOD:	case OASOR:	case OASAND:	case OASXOR:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tlvalue(l))			goto bad;		if(isfunct(n))			break;		if(tcompat(n, l->type, r->type, tand))			goto bad;		t = l->type;		arith(n, 0);		while(n->left->op == OCAST)			n->left = n->left->left;		if(!sametype(t, n->type) && !mixedasop(t, n->type)) {			r = new1(OCAST, n->right, Z);			r->type = t;			n->right = r;			n->type = t;		}		if(typeu[n->type->etype]) {			if(n->op == OASMOD)				n->op = OASLMOD;		}		break;	case OPREINC:	case OPREDEC:	case OPOSTINC:	case OPOSTDEC:		if(tcom(l))			goto bad;		if(tlvalue(l))			goto bad;		if(isfunct(n))			break;		if(tcompat(n, l->type, types[TINT], tadd))			goto bad;		n->type = l->type;		if(n->type->etype == TIND)		if(n->type->link->width < 1)			diag(n, "inc/dec of a void pointer");		break;	case OEQ:	case ONE:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(isfunct(n))			break;		typeext(l->type, r);		typeext(r->type, l);		if(tcompat(n, l->type, r->type, trel))			goto bad;		arith(n, 0);		n->type = types[TINT];		break;	case OLT:	case OGE:	case OGT:	case OLE:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(isfunct(n))			break;		typeext1(l->type, r);		typeext1(r->type, l);		if(tcompat(n, l->type, r->type, trel))			goto bad;		arith(n, 0);		if(typeu[n->type->etype])			n->op = logrel[relindex(n->op)];		n->type = types[TINT];		break;	case OCOND:		o = tcom(l);		o |= tcom(r->left);		if(o | tcom(r->right))			goto bad;		if(r->right->type->etype == TIND && vconst(r->left) == 0) {			r->left->type = r->right->type;			r->left->vconst = 0;		}		if(r->left->type->etype == TIND && vconst(r->right) == 0) {			r->right->type = r->left->type;			r->right->vconst = 0;		}		if(sametype(r->right->type, r->left->type)) {			r->type = r->right->type;			n->type = r->type;			break;		}		if(tcompat(r, r->left->type, r->right->type, trel))			goto bad;		arith(r, 0);		n->type = r->type;		break;	case OADD:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(isfunct(n))			break;		if(tcompat(n, l->type, r->type, tadd))			goto bad;		arith(n, 1);		break;	case OSUB:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(isfunct(n))			break;		if(tcompat(n, l->type, r->type, tsub))			goto bad;		arith(n, 1);		break;	case OMUL:	case OLMUL:	case ODIV:	case OLDIV:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(isfunct(n))			break;		if(tcompat(n, l->type, r->type, tmul))			goto bad;		arith(n, 1);		if(typeu[n->type->etype]) {			if(n->op == ODIV)				n->op = OLDIV;			if(n->op == OMUL)				n->op = OLMUL;		}		break;	case OLSHR:	case OASHL:	case OASHR:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(isfunct(n))			break;		if(tcompat(n, l->type, r->type, tand))			goto bad;		n->right = Z;		arith(n, 1);		n->right = new1(OCAST, r, Z);		n->right->type = types[TINT];		if(typeu[n->type->etype])			if(n->op == OASHR)				n->op = OLSHR;		break;	case OAND:	case OOR:	case OXOR:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(isfunct(n))			break;		if(tcompat(n, l->type, r->type, tand))			goto bad;		arith(n, 1);		break;	case OMOD:	case OLMOD:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(isfunct(n))			break;		if(tcompat(n, l->type, r->type, tand))			goto bad;		arith(n, 1);		if(typeu[n->type->etype])			n->op = OLMOD;		break;	case OPOS:		if(tcom(l))			goto bad;		if(isfunct(n))			break;		r = l;		l = new(OCONST, Z, Z);		l->vconst = 0;		l->type = types[TINT];		n->op = OADD;		n->right = r;		n->left = l;		if(tcom(l))			goto bad;		if(tcompat(n, l->type, r->type, tsub))			goto bad;		arith(n, 1);		break;	case ONEG:		if(tcom(l))			goto bad;		if(isfunct(n))			break;		if(!machcap(n)) {			r = l;			l = new(OCONST, Z, Z);			l->vconst = 0;			l->type = types[TINT];			n->op = OSUB;			n->right = r;			n->left = l;			if(tcom(l))				goto bad;			if(tcompat(n, l->type, r->type, tsub))				goto bad;		}		arith(n, 1);		break;	case OCOM:		if(tcom(l))			goto bad;		if(isfunct(n))			break;		if(!machcap(n)) {			r = l;			l = new(OCONST, Z, Z);			l->vconst = -1;			l->type = types[TINT];			n->op = OXOR;			n->right = r;			n->left = l;			if(tcom(l))				goto bad;			if(tcompat(n, l->type, r->type, tand))				goto bad;		}		arith(n, 1);		break;	case ONOT:		if(tcom(l))			goto bad;		if(isfunct(n))			break;		if(tcompat(n, T, l->type, tnot))			goto bad;		n->type = types[TINT];		break;	case OANDAND:	case OOROR:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tcompat(n, T, l->type, tnot) |		   tcompat(n, T, r->type, tnot))			goto bad;		n->type = types[TINT];		break;	case OCOMMA:		o = tcom(l);		if(o | tcom(r))			goto bad;		n->type = r->type;		break;	case OSIGN:	/* extension signof(type) returns a hash */		if(l != Z) {			if(l->op != OSTRING && l->op != OLSTRING)				if(tcomo(l, 0))					goto bad;			if(l->op == OBIT) {				diag(n, "signof bitfield");				goto bad;			}			n->type = l->type;		}		if(n->type == T)			goto bad;		if(n->type->width < 0) {			diag(n, "signof undefined type");			goto bad;		}		n->op = OCONST;		n->left = Z;		n->right = Z;		n->vconst = convvtox(signature(n->type), TULONG);		n->type = types[TULONG];		break;	case OSIZE:		if(l != Z) {			if(l->op != OSTRING && l->op != OLSTRING)				if(tcomo(l, 0))					goto bad;			if(l->op == OBIT) {				diag(n, "sizeof bitfield");				goto bad;			}			n->type = l->type;		}		if(n->type == T)			goto bad;		if(n->type->width <= 0) {			diag(n, "sizeof undefined type");			goto bad;		}		if(n->type->etype == TFUNC) {			diag(n, "sizeof function");			goto bad;		}		n->op = OCONST;		n->left = Z;		n->right = Z;		n->vconst = convvtox(n->type->width, TINT);		n->type = types[TINT];		break;	case OFUNC:		o = tcomo(l, 0);		if(o)			goto bad;		if(l->type->etype == TIND && l->type->link->etype == TFUNC) {			l = new1(OIND, l, Z);			l->type = l->left->type->link;			n->left = l;		}		if(tcompat(n, T, l->type, tfunct))			goto bad;		if(o | tcoma(l, r, l->type->down, 1))			goto bad;		n->type = l->type->link;		if(!debug['B'])			if(l->type->down == T || l->type->down->etype == TOLD) {				nerrors--;				diag(n, "function args not checked: %F", l);			}		dpcheck(n);		break;	case ONAME:		if(n->type == T) {			diag(n, "name not declared: %F", n);			goto bad;		}		if(n->type->etype == TENUM) {			n->op = OCONST;			n->type = n->sym->tenum;			if(!typefd[n->type->etype])				n->vconst = n->sym->vconst;			else				n->fconst = n->sym->fconst;			break;		}		n->addable = 1;		if(n->class == CEXREG) {			n->op = OREGISTER;			n->reg = n->sym->offset;			n->xoffset = 0;			break;		}		break;	case OLSTRING:		if(n->type->link != types[TUSHORT]) {			o = outstring(0, 0);			while(o & 3) {				outlstring(L"", sizeof(ushort));				o = outlstring(0, 0);			}		}		n->op = ONAME;		n->xoffset = outlstring(n->rstring, n->type->width);		n->addable = 1;		break;	case OSTRING:		if(n->type->link != types[TCHAR]) {			o = outstring(0, 0);			while(o & 3) {				outstring("", 1);				o = outstring(0, 0);			}		}		n->op = ONAME;		n->xoffset = outstring(n->cstring, n->type->width);		n->addable = 1;		break;	case OCONST:		break;	case ODOT:		if(tcom(l))			goto bad;		if(tcompat(n, T, l->type, tdot))			goto bad;		if(tcomd(n))			goto bad;		break;	case OADDR:		if(tcomo(l, ADDROP))			goto bad;		if(tlvalue(l))			goto bad;		if(l->type->nbits) {			diag(n, "address of a bit field");			goto bad;		}		if(l->op == OREGISTER) {			diag(n, "address of a register");			goto bad;		}		n->type = typ(TIND, l->type);		n->type->width = types[TIND]->width;		break;	case OIND:		if(tcom(l))			goto bad;

⌨️ 快捷键说明

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