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

📄 sub.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
#include	"cc.h"Node*new(int t, Node *l, Node *r){	Node *n;	n = alloc(sizeof(*n));	n->op = t;	n->left = l;	n->right = r;	if(l && t != OGOTO)		n->lineno = l->lineno;	else if(r)		n->lineno = r->lineno;	else		n->lineno = lineno;	newflag = 1;	return n;}Node*new1(int o, Node *l, Node *r){	Node *n;	n = new(o, l, r);	n->lineno = nearln;	return n;}voidprtree(Node *n, char *s){	print(" == %s ==\n", s);	prtree1(n, 0, 0);	print("\n");}voidprtree1(Node *n, int d, int f){	int i;	if(f)	for(i=0; i<d; i++)		print("   ");	if(n == Z) {		print("Z\n");		return;	}	if(n->op == OLIST) {		prtree1(n->left, d, 0);		prtree1(n->right, d, 1);		return;	}	d++;	print("%O", n->op);	i = 3;	switch(n->op)	{	case ONAME:		print(" \"%F\"", n);		print(" %ld", n->xoffset);		i = 0;		break;	case OINDREG:		print(" %ld(R%d)", n->xoffset, n->reg);		i = 0;		break;	case OREGISTER:		if(n->xoffset)			print(" %ld+R%d", n->xoffset, n->reg);		else			print(" R%d", n->reg);		i = 0;		break;	case OSTRING:		print(" \"%s\"", n->cstring);		i = 0;		break;	case OLSTRING:		print(" \"%S\"", n->rstring);		i = 0;		break;	case ODOT:	case OELEM:		print(" \"%F\"", n);		break;	case OCONST:		if(typefd[n->type->etype])			print(" \"%.8e\"", n->fconst);		else			print(" \"%lld\"", n->vconst);		i = 0;		break;	}	if(n->addable != 0)		print(" <%d>", n->addable);	if(n->type != T)		print(" %T", n->type);	if(n->complex != 0)		print(" (%d)", n->complex);	print(" %L\n", n->lineno);	if(i & 2)		prtree1(n->left, d, 1);	if(i & 1)		prtree1(n->right, d, 1);}Type*typ(int et, Type *d){	Type *t;	t = alloc(sizeof(*t));	t->etype = et;	t->link = d;	t->down = T;	t->sym = S;	t->width = ewidth[et];	t->offset = 0;	t->shift = 0;	t->nbits = 0;	t->garb = 0;	return t;}Type*copytyp(Type *t){	Type *nt;	nt = typ(TXXX, T);	*nt = *t;	return nt;}Type*garbt(Type *t, long b){	Type *t1;	if(b & BGARB) {		t1 = copytyp(t);		t1->garb = simpleg(b);		return t1;	}	return t;}intsimpleg(long b){	b &= BGARB;	switch(b) {	case BCONSTNT:		return GCONSTNT;	case BVOLATILE:		return GVOLATILE;	case BVOLATILE|BCONSTNT:		return GCONSTNT|GVOLATILE;	}	return GXXX;}intsimplec(long b){	b &= BCLASS;	switch(b) {	case 0:	case BREGISTER:		return CXXX;	case BAUTO:	case BAUTO|BREGISTER:		return CAUTO;	case BEXTERN:		return CEXTERN;	case BEXTERN|BREGISTER:		return CEXREG;	case BSTATIC:		return CSTATIC;	case BTYPEDEF:		return CTYPEDEF;	case BTYPESTR:		return CTYPESTR;	}	diag(Z, "illegal combination of classes %Q", b);	return CXXX;}Type*simplet(long b){	b &= ~BCLASS & ~BGARB;	switch(b) {	case BCHAR:	case BCHAR|BSIGNED:		return types[TCHAR];	case BCHAR|BUNSIGNED:		return types[TUCHAR];	case BSHORT:	case BSHORT|BINT:	case BSHORT|BSIGNED:	case BSHORT|BINT|BSIGNED:		return types[TSHORT];	case BUNSIGNED|BSHORT:	case BUNSIGNED|BSHORT|BINT:		return types[TUSHORT];	case 0:	case BINT:	case BINT|BSIGNED:	case BSIGNED:		return types[TINT];	case BUNSIGNED:	case BUNSIGNED|BINT:		return types[TUINT];	case BLONG:	case BLONG|BINT:	case BLONG|BSIGNED:	case BLONG|BINT|BSIGNED:		return types[TLONG];	case BUNSIGNED|BLONG:	case BUNSIGNED|BLONG|BINT:		return types[TULONG];	case BVLONG|BLONG:	case BVLONG|BLONG|BINT:	case BVLONG|BLONG|BSIGNED:	case BVLONG|BLONG|BINT|BSIGNED:		return types[TVLONG];	case BVLONG|BLONG|BUNSIGNED:	case BVLONG|BLONG|BINT|BUNSIGNED:		return types[TUVLONG];	case BFLOAT:		return types[TFLOAT];	case BDOUBLE:	case BDOUBLE|BLONG:	case BFLOAT|BLONG:		return types[TDOUBLE];	case BVOID:		return types[TVOID];	}	diag(Z, "illegal combination of types %Q", b);	return types[TINT];}intstcompat(Node *n, Type *t1, Type *t2, long ttab[]){	int i;	ulong b;	i = 0;	if(t2 != T)		i = t2->etype;	b = 1L << i;	i = 0;	if(t1 != T)		i = t1->etype;	if(b & ttab[i]) {		if(ttab == tasign)			if(b == BSTRUCT || b == BUNION)				if(!sametype(t1, t2))					return 1;		if(n->op != OCAST)		 	if(b == BIND && i == TIND)				if(!sametype(t1, t2))					return 1;		return 0;	}	return 1;}inttcompat(Node *n, Type *t1, Type *t2, long ttab[]){	if(stcompat(n, t1, t2, ttab)) {		if(t1 == T)			diag(n, "incompatible type: \"%T\" for op \"%O\"",				t2, n->op);		else			diag(n, "incompatible types: \"%T\" and \"%T\" for op \"%O\"",				t1, t2, n->op);		return 1;	}	return 0;}voidmakedot(Node *n, Type *t, long o){	Node *n1, *n2;	if(t->nbits) {		n1 = new(OXXX, Z, Z);		*n1 = *n;		n->op = OBIT;		n->left = n1;		n->right = Z;		n->type = t;		n->addable = n1->left->addable;		n = n1;	}	n->addable = n->left->addable;	if(n->addable == 0) {		n1 = new1(OCONST, Z, Z);		n1->vconst = o;		n1->type = types[TLONG];		n->right = n1;		n->type = t;		return;	}	n->left->type = t;	if(o == 0) {		*n = *n->left;		return;	}	n->type = t;	n1 = new1(OCONST, Z, Z);	n1->vconst = o;	t = typ(TIND, t);	t->width = types[TIND]->width;	n1->type = t;	n2 = new1(OADDR, n->left, Z);	n2->type = t;	n1 = new1(OADD, n1, n2);	n1->type = t;	n->op = OIND;	n->left = n1;	n->right = Z;}Type*dotsearch(Sym *s, Type *t, Node *n, long *off){	Type *t1, *xt, *rt;	xt = T;	/*	 * look it up by name	 */	for(t1 = t; t1 != T; t1 = t1->down)		if(t1->sym == s) {			if(xt != T)				goto ambig;			xt = t1;		}	/*	 * look it up by type	 */	if(s->class == CTYPEDEF || s->class == CTYPESTR)		for(t1 = t; t1 != T; t1 = t1->down)			if(t1->sym == S && typesu[t1->etype])				if(sametype(s->type, t1)) {					if(xt != T)						goto ambig;					xt = t1;				}	if(xt != T) {		*off = xt->offset;		return xt;	}	/*	 * look it up in unnamed substructures	 */	for(t1 = t; t1 != T; t1 = t1->down)		if(t1->sym == S && typesu[t1->etype]){			rt = dotsearch(s, t1->link, n, off);			if(rt != T) {				if(xt != T)					goto ambig;				xt = rt;				*off += t1->offset;			}		}	return xt;ambig:	diag(n, "ambiguous structure element: %s", s->name);	return xt;}longdotoffset(Type *st, Type *lt, Node *n){	Type *t;	Sym *g;	long o, o1;	o = -1;	/*	 * first try matching at the top level	 * for matching tag names	 */	g = st->tag;	if(g != S)		for(t=lt->link; t!=T; t=t->down)			if(t->sym == S)				if(g == t->tag) {					if(o >= 0)						goto ambig;					o = t->offset;				}	if(o >= 0)		return o;	/*	 * second try matching at the top level	 * for similar types	 */	for(t=lt->link; t!=T; t=t->down)		if(t->sym == S)			if(sametype(st, t)) {				if(o >= 0)					goto ambig;				o = t->offset;			}	if(o >= 0)		return o;	/*	 * last try matching sub-levels	 */	for(t=lt->link; t!=T; t=t->down)		if(t->sym == S)		if(typesu[t->etype]) {			o1 = dotoffset(st, t, n);			if(o1 >= 0) {				if(o >= 0)					goto ambig;				o = o1 + t->offset;			}		}	return o;ambig:	diag(n, "ambiguous unnamed structure element");	return o;}/* * look into tree for floating point constant expressions */intallfloat(Node *n, int flag){	if(n != Z) {		if(n->type->etype != TDOUBLE)			return 1;		switch(n->op) {		case OCONST:			if(flag)				n->type = types[TFLOAT];			return 1;		case OADD:	/* no need to get more exotic than this */		case OSUB:		case OMUL:		case ODIV:			if(!allfloat(n->right, flag))				break;		case OCAST:			if(!allfloat(n->left, flag))				break;			if(flag)				n->type = types[TFLOAT];			return 1;		}	}	return 0;}voidconstas(Node *n, Type *il, Type *ir){	Type *l, *r;	l = il;	r = ir;	if(l == T)		return;	if(l->garb & GCONSTNT) {		warn(n, "assignment to a constant type (%T)", il);		return;	}	if(r == T)		return;	for(;;) {		if(l->etype != TIND || r->etype != TIND)			break;		l = l->link;		r = r->link;		if(l == T || r == T)			break;		if(r->garb & GCONSTNT)			if(!(l->garb & GCONSTNT)) {				warn(n, "assignment of a constant pointer type (%T)", ir);				break;			}	}}voidtypeext1(Type *st, Node *l){	if(st->etype == TFLOAT && allfloat(l, 0))		allfloat(l, 1);}voidtypeext(Type *st, Node *l){	Type *lt;	Node *n1, *n2;	long o;	lt = l->type;	if(lt == T)		return;	if(st->etype == TIND && vconst(l) == 0) {		l->type = st;		l->vconst = 0;		return;	}	typeext1(st, l);	/*	 * extension of C	 * if assign of struct containing unnamed sub-struct	 * to type of sub-struct, insert the DOT.	 * if assign of *struct containing unnamed substruct	 * to type of *sub-struct, insert the add-offset	 */	if(typesu[st->etype] && typesu[lt->etype]) {		o = dotoffset(st, lt, l);		if(o >= 0) {			n1 = new1(OXXX, Z, Z);			*n1 = *l;			l->op = ODOT;			l->left = n1;			l->right = Z;			makedot(l, st, o);		}		return;	}	if(st->etype == TIND && typesu[st->link->etype])	if(lt->etype == TIND && typesu[lt->link->etype]) {		o = dotoffset(st->link, lt->link, l);		if(o >= 0) {			l->type = st;			if(o == 0)				return;			n1 = new1(OXXX, Z, Z);			*n1 = *l;			n2 = new1(OCONST, Z, Z);			n2->vconst = o;			n2->type = st;			l->op = OADD;			l->left = n1;			l->right = n2;		}		return;	}}/* * a cast that generates no code * (same size move) */intnocast(Type *t1, Type *t2){	int i, b;	if(t1->nbits)		return 0;	i = 0;	if(t2 != T)		i = t2->etype;	b = 1<<i;	i = 0;	if(t1 != T)		i = t1->etype;	if(b & ncast[i])		return 1;	return 0;}/* * a cast that has a noop semantic * (small to large, convert) */intnilcast(Type *t1, Type *t2){	int et1, et2;	if(t1 == T)		return 0;	if(t1->nbits)		return 0;	if(t2 == T)		return 0;	et1 = t1->etype;	et2 = t2->etype;	if(et1 == et2)		return 1;	if(typefd[et1] && typefd[et2]) {		if(ewidth[et1] < ewidth[et2])			return 1;		return 0;	}	if(typechlp[et1] && typechlp[et2]) {		if(ewidth[et1] < ewidth[et2])			return 1;		return 0;	}	return 0;}/* * "the usual arithmetic conversions are performed" */voidarith(Node *n, int f){	Type *t1, *t2;	int i, j, k;	Node *n1;	long w;	t1 = n->left->type;	if(n->right == Z)		t2 = t1;	else		t2 = n->right->type;	i = TXXX;	if(t1 != T)		i = t1->etype;	j = TXXX;	if(t2 != T)		j = t2->etype;	k = tab[i][j];

⌨️ 快捷键说明

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