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

📄 stmt.c

📁 lcc,一个可变目标c语言编译器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "c.h"static char rcsid[] = "$Id: stmt.c,v 1.1 2002/08/28 23:12:46 drh Exp $";#define SWSIZE 512#define den(i,j) ((j-buckets[i]+1.0)/(v[j]-v[buckets[i]]+1))struct code codehead = { Start };Code codelist = &codehead;float density = 0.5;Table stmtlabs;static int foldcond(Tree e1, Tree e2);static void caselabel(Swtch, long, int);static void cmp(int, Symbol, long, int);static Tree conditional(int);static void dostmt(int, Swtch, int);static int equal(Symbol, Symbol);static void forstmt(int, Swtch, int);static void ifstmt(int, int, Swtch, int);static Symbol localaddr(Tree);static void stmtlabel(void);static void swstmt(int, int, int);static void whilestmt(int, Swtch, int);Code code(int kind) {	Code cp;	if (!reachable(kind))		warning("unreachable code\n");	NEW(cp, FUNC);	cp->kind = kind;	cp->prev = codelist;	cp->next = NULL;	codelist->next = cp;	codelist = cp;	return cp;}int reachable(int kind) {	Code cp;	if (kind > Start) {		Code cp;		for (cp = codelist; cp->kind < Label; )			cp = cp->prev;		if (cp->kind == Jump || cp->kind == Switch)			return 0;	}	return 1;}void addlocal(Symbol p) {	if (!p->defined) {		code(Local)->u.var = p;		p->defined = 1;		p->scope = level;	}}void definept(Coordinate *p) {	Code cp = code(Defpoint);	cp->u.point.src = p ? *p : src;	cp->u.point.point = npoints;	if (ncalled > 0) {		int n = findcount(cp->u.point.src.file,			cp->u.point.src.x, cp->u.point.src.y);		if (n > 0)			refinc = (float)n/ncalled;	}	if (glevel > 2)	locus(identifiers, &cp->u.point.src);	if (events.points && reachable(Gen))		{			Tree e = NULL;			apply(events.points, &cp->u.point.src, &e);			if (e)				listnodes(e, 0, 0);		}}void statement(int loop, Swtch swp, int lev) {	float ref = refinc;	if (Aflag >= 2 && lev == 15)		warning("more than 15 levels of nested statements\n");	switch (t) {	case IF:       ifstmt(genlabel(2), loop, swp, lev + 1); break;	case WHILE:    whilestmt(genlabel(3), swp, lev + 1); break;	case DO:       dostmt(genlabel(3), swp, lev + 1); expect(';');					break;	case FOR:      forstmt(genlabel(4), swp, lev + 1); break;	case BREAK:    walk(NULL, 0, 0);		       definept(NULL);		       if (swp && swp->lab > loop)		       	branch(swp->lab + 1);		       else if (loop)		       	branch(loop + 2);		       else		       	error("illegal break statement\n");		       t = gettok(); expect(';');					   break;	case CONTINUE: walk(NULL, 0, 0);		       definept(NULL);		       if (loop)		       	branch(loop + 1);		       else		       	error("illegal continue statement\n");		       t = gettok(); expect(';');					      break;	case SWITCH:   swstmt(loop, genlabel(2), lev + 1); break;	case CASE:     {		       	int lab = genlabel(1);		       	if (swp == NULL)		       		error("illegal case label\n");		       	definelab(lab);		       	while (t == CASE) {		       		static char stop[] = { IF, ID, 0 };		       		Tree p;		       		t = gettok();		       		p = constexpr(0);		       		if (generic(p->op) == CNST && isint(p->type)) {		       			if (swp) {		       				needconst++;		       				p = cast(p, swp->sym->type);		       				if (p->type->op == UNSIGNED)		       					p->u.v.i = extend(p->u.v.u, p->type);		       				needconst--;		       				caselabel(swp, p->u.v.i, lab);		       			}		       		} else		       			error("case label must be a constant integer expression\n");		       		test(':', stop);		       	}		       	statement(loop, swp, lev);		       } break;	case DEFAULT:  if (swp == NULL)		       	error("illegal default label\n");		       else if (swp->deflab)		       	error("extra default label\n");		       else {		       	swp->deflab = findlabel(swp->lab);		       	definelab(swp->deflab->u.l.label);		       }		       t = gettok();		       expect(':');		       statement(loop, swp, lev); break;	case RETURN:   {		       	Type rty = freturn(cfunc->type);		       	t = gettok();		       	definept(NULL);		       	if (t != ';')		       		if (rty == voidtype) {		       			error("extraneous return value\n");		       			expr(0);		       			retcode(NULL);		       		} else		       			retcode(expr(0));		       	else {		       		if (rty != voidtype) {		       			warning("missing return value\n");		       			retcode(cnsttree(inttype, 0L));		       		} else		       			retcode(NULL);		       	}		       	branch(cfunc->u.f.label);		       } expect(';');					    break;	case '{':      compound(loop, swp, lev + 1); break;	case ';':      definept(NULL); t = gettok(); break;	case GOTO:     walk(NULL, 0, 0);		       definept(NULL);		       t = gettok();		       if (t == ID) {		       	Symbol p = lookup(token, stmtlabs);		       	if (p == NULL) {				p = install(token, &stmtlabs, 0, FUNC);				p->scope = LABELS;				p->u.l.label = genlabel(1);				p->src = src;			}		       	use(p, src);		       	branch(p->u.l.label);		       	t = gettok();		       } else		       	error("missing label in goto\n"); expect(';');					  break;	case ID:       if (getchr() == ':') {		       	stmtlabel();		       	statement(loop, swp, lev);		       	break;		       }	default:       definept(NULL);		       if (kind[t] != ID) {		       	error("unrecognized statement\n");		       	t = gettok();		       } else {		       	Tree e = expr0(0);		       	listnodes(e, 0, 0);		       	if (nodecount == 0 || nodecount > 200)		       		walk(NULL, 0, 0);		       	else if (glevel) walk(NULL, 0, 0);		       	deallocate(STMT);		       } expect(';');						break;	}	if (kind[t] != IF && kind[t] != ID	&& t != '}' && t != EOI) {		static char stop[] = { IF, ID, '}', 0 };		error("illegal statement termination\n");		skipto(0, stop);	}	refinc = ref;}static void ifstmt(int lab, int loop, Swtch swp, int lev) {	t = gettok();	expect('(');	definept(NULL);	walk(conditional(')'), 0, lab);	refinc /= 2.0;	statement(loop, swp, lev);	if (t == ELSE) {		branch(lab + 1);		t = gettok();		definelab(lab);		statement(loop, swp, lev);		if (findlabel(lab + 1)->ref)			definelab(lab + 1);	} else		definelab(lab);}static Tree conditional(int tok) {	Tree p = expr(tok);	if (Aflag > 1 && isfunc(p->type))		warning("%s used in a conditional expression\n",			funcname(p));	return cond(p);}static void stmtlabel(void) {	Symbol p = lookup(token, stmtlabs);	if (p == NULL) {		p = install(token, &stmtlabs, 0, FUNC);		p->scope = LABELS;		p->u.l.label = genlabel(1);		p->src = src;	}	if (p->defined)		error("redefinition of label `%s' previously defined at %w\n", p->name, &p->src);	p->defined = 1;	definelab(p->u.l.label);	t = gettok();	expect(':');}static void forstmt(int lab, Swtch swp, int lev) {	int once = 0;	Tree e1 = NULL, e2 = NULL, e3 = NULL;	Coordinate pt2, pt3;		t = gettok();	expect('(');	definept(NULL);	if (kind[t] == ID)		e1 = texpr(expr0, ';', FUNC);	else		expect(';');	walk(e1, 0, 0);	pt2 = src;	refinc *= 10.0;	if (kind[t] == ID)		e2 = texpr(conditional, ';', FUNC);	else		expect(';');	pt3 = src;	if (kind[t] == ID)		e3 = texpr(expr0, ')', FUNC);	else {		static char stop[] = { IF, ID, '}', 0 };		test(')', stop);	}	if (e2) {		once = foldcond(e1, e2);		if (!once)			branch(lab + 3);	}	definelab(lab);	statement(lab, swp, lev);	definelab(lab + 1);	definept(&pt3);	if (e3)		walk(e3, 0, 0);	if (e2) {		if (!once)			definelab(lab + 3);		definept(&pt2);		walk(e2, lab, 0);	} else {		definept(&pt2);		branch(lab);	}	if (findlabel(lab + 2)->ref)		definelab(lab + 2);}static void swstmt(int loop, int lab, int lev) {	Tree e;	struct swtch sw;	Code head, tail;	t = gettok();	expect('(');	definept(NULL);	e = expr(')');	if (!isint(e->type)) {		error("illegal type `%t' in switch expression\n",			e->type);		e = retype(e, inttype);	}	e = cast(e, promote(e->type));	if (generic(e->op) == INDIR && isaddrop(e->kids[0]->op)	&& e->kids[0]->u.sym->type == e->type	&& !isvolatile(e->kids[0]->u.sym->type)) {		sw.sym = e->kids[0]->u.sym;		walk(NULL, 0, 0);	} else {		sw.sym = genident(REGISTER, e->type, level);		addlocal(sw.sym);		walk(asgn(sw.sym, e), 0, 0);	}	head = code(Switch);	sw.lab = lab;	sw.deflab = NULL;	sw.ncases = 0;	sw.size = SWSIZE;	sw.values = newarray(SWSIZE, sizeof *sw.values, FUNC);	sw.labels = newarray(SWSIZE, sizeof *sw.labels, FUNC);	refinc /= 10.0;	statement(loop, &sw, lev);	if (sw.deflab == NULL) {		sw.deflab = findlabel(lab);		definelab(lab);		if (sw.ncases == 0)			warning("switch statement with no cases\n");	}	if (findlabel(lab + 1)->ref)		definelab(lab + 1);

⌨️ 快捷键说明

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