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

📄 stmt.c

📁 lcc,一个可变目标c语言编译器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	tail = codelist;	codelist = head->prev;	codelist->next = head->prev = NULL;	if (sw.ncases > 0)		swgen(&sw);	branch(lab);	head->next->prev = codelist;	codelist->next = head->next;	codelist = tail;}static void caselabel(Swtch swp, long val, int lab) {	int k;	if (swp->ncases >= swp->size)		{		long   *vals = swp->values;		Symbol *labs = swp->labels;		swp->size *= 2;		swp->values = newarray(swp->size, sizeof *swp->values, FUNC);		swp->labels = newarray(swp->size, sizeof *swp->labels, FUNC);		for (k = 0; k < swp->ncases; k++) {			swp->values[k] = vals[k];			swp->labels[k] = labs[k];		}		}	k = swp->ncases;	for ( ; k > 0 && swp->values[k-1] >= val; k--) {		swp->values[k] = swp->values[k-1];		swp->labels[k] = swp->labels[k-1];	}	if (k < swp->ncases && swp->values[k] == val)		error("duplicate case label `%d'\n", val);	swp->values[k] = val;	swp->labels[k] = findlabel(lab);	++swp->ncases;	if (Aflag >= 2 && swp->ncases == 258)		warning("more than 257 cases in a switch\n");}void swgen(Swtch swp) {	int *buckets, k, n;	long *v = swp->values;	buckets = newarray(swp->ncases + 1,		sizeof *buckets, FUNC);	for (n = k = 0; k < swp->ncases; k++, n++) {		buckets[n] = k;		while (n > 0 && den(n-1, k) >= density)			n--;	}	buckets[n] = swp->ncases;	swcode(swp, buckets, 0, n - 1);}void swcode(Swtch swp, int b[], int lb, int ub) {	int hilab, lolab, l, u, k = (lb + ub)/2;	long *v = swp->values;	if (k > lb && k < ub) {		lolab = genlabel(1);		hilab = genlabel(1);	} else if (k > lb) {		lolab = genlabel(1);		hilab = swp->deflab->u.l.label;	} else if (k < ub) {		lolab = swp->deflab->u.l.label;		hilab = genlabel(1);	} else		lolab = hilab = swp->deflab->u.l.label;	l = b[k];	u = b[k+1] - 1;	if (u - l + 1 <= 3)		{			int i;			for (i = l; i <= u; i++)				cmp(EQ, swp->sym, v[i], swp->labels[i]->u.l.label);			if (k > lb && k < ub)				cmp(GT, swp->sym, v[u], hilab);			else if (k > lb)				cmp(GT, swp->sym, v[u], hilab);			else if (k < ub)				cmp(LT, swp->sym, v[l], lolab);			else				assert(lolab == hilab),				branch(lolab);			walk(NULL, 0, 0);		}	else {		Tree e;		Type ty = signedint(swp->sym->type);		Symbol table = genident(STATIC,			array(voidptype, u - l + 1, 0), GLOBAL);		(*IR->defsymbol)(table);		if (!isunsigned(swp->sym->type) || v[l] != 0)			cmp(LT, swp->sym, v[l], lolab);		cmp(GT, swp->sym, v[u], hilab);		e = (*optree['-'])(SUB, cast(idtree(swp->sym), ty), cnsttree(ty, v[l]));		if (e->type->size < unsignedptr->size)			e = cast(e, unsignedlong);		walk(tree(JUMP, voidtype,			rvalue((*optree['+'])(ADD, pointer(idtree(table)), e)), NULL),			0, 0);		code(Switch);		codelist->u.swtch.table = table;		codelist->u.swtch.sym = swp->sym;		codelist->u.swtch.deflab = swp->deflab;		codelist->u.swtch.size = u - l + 1;		codelist->u.swtch.values = &v[l];		codelist->u.swtch.labels = &swp->labels[l];		if (v[u] - v[l] + 1 >= 10000)			warning("switch generates a huge table\n");	}	if (k > lb) {		assert(lolab != swp->deflab->u.l.label);		definelab(lolab);		swcode(swp, b, lb, k - 1);	}	if (k < ub) {		assert(hilab != swp->deflab->u.l.label);		definelab(hilab);		swcode(swp, b, k + 1, ub);	}}static void cmp(int op, Symbol p, long n, int lab) {	Type ty = signedint(p->type);	listnodes(eqtree(op,			cast(idtree(p), ty),			cnsttree(ty, n)),		lab, 0);}void retcode(Tree p) {	Type ty;	if (p == NULL) {		if (events.returns)			apply(events.returns, cfunc, NULL);		return;	}	p = pointer(p);	ty = assign(freturn(cfunc->type), p);	if (ty == NULL) {		error("illegal return type; found `%t' expected `%t'\n",			p->type, freturn(cfunc->type));		return;	}	p = cast(p, ty);	if (retv)		{			if (iscallb(p))				p = tree(RIGHT, p->type,					tree(CALL+B, p->type,						p->kids[0]->kids[0], idtree(retv)),					rvalue(idtree(retv)));			else {				Type ty = retv->type->type;				assert(isstruct(ty));				if (ty->u.sym->u.s.cfields) {					ty->u.sym->u.s.cfields = 0;					p = asgntree(ASGN, rvalue(idtree(retv)), p);					ty->u.sym->u.s.cfields = 1;				} else					p = asgntree(ASGN, rvalue(idtree(retv)), p);			}			walk(p, 0, 0);			if (events.returns)				apply(events.returns, cfunc, rvalue(idtree(retv)));			return;		}	if (events.returns)		{			Symbol t1 = genident(AUTO, p->type, level);			addlocal(t1);			walk(asgn(t1, p), 0, 0);			apply(events.returns, cfunc, idtree(t1));			p = idtree(t1);		}	if (!isfloat(p->type))		p = cast(p, promote(p->type));	if (isptr(p->type))		{			Symbol q = localaddr(p);			if (q && (q->computed || q->generated))				warning("pointer to a %s is an illegal return value\n",					q->scope == PARAM ? "parameter" : "local");			else if (q)				warning("pointer to %s `%s' is an illegal return value\n",					q->scope == PARAM ? "parameter" : "local", q->name);		}	walk(tree(mkop(RET,p->type), p->type, p, NULL), 0, 0);}void definelab(int lab) {	Code cp;	Symbol p = findlabel(lab);	assert(lab);	walk(NULL, 0, 0);	code(Label)->u.forest = newnode(LABEL+V, NULL, NULL, p);	for (cp = codelist->prev; cp->kind <= Label; )		cp = cp->prev;	while (   cp->kind == Jump	       && cp->u.forest->kids[0]	       && specific(cp->u.forest->kids[0]->op) == ADDRG+P	       && cp->u.forest->kids[0]->syms[0] == p) {		assert(cp->u.forest->kids[0]->syms[0]->u.l.label == lab);		p->ref--;		assert(cp->next);		assert(cp->prev);		cp->prev->next = cp->next;		cp->next->prev = cp->prev;		cp = cp->prev;		while (cp->kind <= Label)			cp = cp->prev;	}}Node jump(int lab) {	Symbol p = findlabel(lab);	p->ref++;	return newnode(JUMP+V, newnode(ADDRG+ttob(voidptype), NULL, NULL, p),		NULL, NULL);}void branch(int lab) {	Code cp;	Symbol p = findlabel(lab);	assert(lab);	walk(NULL, 0, 0);	code(Label)->u.forest = jump(lab);	for (cp = codelist->prev; cp->kind < Label; )		cp = cp->prev;	while (   cp->kind == Label	       && cp->u.forest->op == LABEL+V	       && !equal(cp->u.forest->syms[0], p)) {		equatelab(cp->u.forest->syms[0], p);		assert(cp->next);		assert(cp->prev);		cp->prev->next = cp->next;		cp->next->prev = cp->prev;		cp = cp->prev;		while (cp->kind < Label)			cp = cp->prev;	}	if (cp->kind == Jump || cp->kind == Switch) {		p->ref--;		codelist->prev->next = NULL;		codelist = codelist->prev;	} else {		codelist->kind = Jump;		if (cp->kind == Label		&&  cp->u.forest->op == LABEL+V		&&  equal(cp->u.forest->syms[0], p))			warning("source code specifies an infinite loop\n");	}}void equatelab(Symbol old, Symbol new) {	assert(old->u.l.equatedto == NULL);	old->u.l.equatedto = new;	new->ref++;}static int equal(Symbol lprime, Symbol dst) {	assert(dst && lprime);	for ( ; dst; dst = dst->u.l.equatedto)		if (lprime == dst)			return 1;	return 0;}/* dostmt - do statement while ( expression ) */static void dostmt(int lab, Swtch swp, int lev) {	refinc *= 10.0;	t = gettok();	definelab(lab);	statement(lab, swp, lev);	definelab(lab + 1);	expect(WHILE);	expect('(');	definept(NULL);	walk(conditional(')'), lab, 0);	if (findlabel(lab + 2)->ref)		definelab(lab + 2);}/* foldcond - check if initial test in for(e1;e2;e3) S is necessary */static int foldcond(Tree e1, Tree e2) {	int op = generic(e2->op);	Symbol v;	if (e1 == 0 || e2 == 0)		return 0;	if (generic(e1->op) == ASGN && isaddrop(e1->kids[0]->op)	&& generic(e1->kids[1]->op) == CNST) {		v = e1->kids[0]->u.sym;		e1 = e1->kids[1];	} else		return 0;	if ((op==LE || op==LT || op==EQ || op==NE || op==GT || op==GE)	&& generic(e2->kids[0]->op) == INDIR	&& e2->kids[0]->kids[0]->u.sym == v	&& e2->kids[1]->op == e1->op) {		e1 = simplify(op, e2->type, e1, e2->kids[1]);		if (e1->op == CNST+I)			return e1->u.v.i;	}	return 0;}/* localaddr - returns q if p yields the address of local/parameter q; otherwise returns 0 */static Symbol localaddr(Tree p) {	if (p == NULL)		return NULL;	switch (generic(p->op)) {	case INDIR: case CALL: case ARG:		return NULL;	case ADDRL: case ADDRF:		return p->u.sym;	case RIGHT: case ASGN:		if (p->kids[1])			return localaddr(p->kids[1]);		return localaddr(p->kids[0]);	case COND: {		Symbol q;		assert(p->kids[1] && p->kids[1]->op == RIGHT);		if ((q = localaddr(p->kids[1]->kids[0])) != NULL)			return q;		return localaddr(p->kids[1]->kids[1]);		}	default: {		Symbol q;		if (p->kids[0] && (q = localaddr(p->kids[0])) != NULL)			return q;		return localaddr(p->kids[1]);		}	}}/* whilestmt - while ( expression ) statement */static void whilestmt(int lab, Swtch swp, int lev) {	Coordinate pt;	Tree e;	refinc *= 10.0;	t = gettok();	expect('(');	walk(NULL, 0, 0);	pt = src;	e = texpr(conditional, ')', FUNC);	branch(lab + 1);	definelab(lab);	statement(lab, swp, lev);	definelab(lab + 1);	definept(&pt);	walk(e, lab, 0);	if (findlabel(lab + 2)->ref)		definelab(lab + 2);}

⌨️ 快捷键说明

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