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

📄 sym.c

📁 unix环境下实现的cmm语言编译器
💻 C
字号:
/*sym.c: 对符号表进行管理*/#include "cmm.h"struct table{	int level; 			/*符号表的作用域*/	Table previous; 	/*指向上层作用域的符号表*/	struct entry {		struct symbol sym;		struct entry *link;	}*buckets[256];	Symbol all;};#define HASHSIZE NELEMS(((Table)(0))->buckets)int level = GLOBAL; 		/*当前作用域*/static struct table cns = {CONSTANT}, ids = {GLOBAL};Table constants = &cns; 	/*常量的符号表*/Table identifiers = &ids;	/*标示符的符号表*/Table globals = &ids;		/*全局作用域的符号表*/Table labels;				/*标号的符号表*/static char *vtoa(Type ty, Value v);void init_sym(void){	memset(globals->buckets, 0, sizeof globals->buckets);	globals->all = NULL;}/*table:创建作用域为level新的符号表*/Table table(Table tp,int level){	Table new;	NEW0(new,FUNC);	new->level = level;	new->previous = tp;	if(tp && tp->all)		new->all = tp->all;	return new;}/*foreach:遍历作用域为lev的符号表,并为每一个符号调用函数aaply*/void foreach(Table tp, int lev,			void (*apply)(Symbol, void*),void*c1){	while (tp && tp->level > lev)		tp = tp->previous;	if (tp && tp->level == lev) {		Coordinate sav;		Symbol p;		sav = src;		for (p = tp->all;p && p->scope == lev; p=p->up) {			sav = src;			(*apply)(p,c1);		}		src = sav;	}}/*enterscope:进入下层作用域*/void enterscope(void){	++level;}/*exitscope:退出当前的作用域*/void exitscope(void){	if(identifiers->level == level) /*删除当前作用域的符号表*/		identifiers = identifiers->previous;	--level;}/*install:安装名字为name,作用域为lev的标示符于符号表。 *tpp指向上层作用域的符号表,arena为分配存储空间的位置。 *当lev为0调用时,符号将安装于当前作用域的符号表中。*/Symbol install(char *name,Table *tpp,int lev,unsigned arena){	struct entry *p;	Table tp = *tpp;	unsigned h = (unsigned)name&(HASHSIZE -1);	if(tp->level>0 && tp->level < lev)		tp = *tpp = table(tp,lev);	NEW0(p, arena);	p->sym.name = name;	p->sym.scope = lev;	p->sym.up = tp->all;	tp->all = &p->sym;	p->link = tp->buckets[h];	tp->buckets[h] = p;	return &p->sym;}/*lookup:在符号表中查找名字为name的标示符。*/Symbol lookup(char *name, Table tp){	struct entry *p;	unsigned h = (unsigned)name&(HASHSIZE-1);	assert(tp && name);	do {		for(p = tp->buckets[h]; p; p=p->link)			if(p->sym.name == name)				return &p->sym;	}while((tp=tp->previous) != NULL);	return NULL;}/*genlabel:生成n个标号*/int genlabel(int n){	static int label = 1;	label += n;	return label - n;}/*findlabel:在标号的符号表中寻找标号lab, *如果没有则将lab安装到标号的符号表中*/Symbol findlabel(int lab){	struct entry *p;	unsigned h = lab&(HASHSIZE - 1);	for (p=labels->buckets[h]; p ; p=p->link)		if(p->sym.u.l.label == lab)			return &p->sym;	NEW0(p, FUNC);	p->sym.name = stringd(lab);	p->sym.scope = LABELS;	p->sym.u.l.label = lab;	p->sym.up = labels->all;	p->sym.generated = 1;	labels->all = &p->sym;	p->link = labels->buckets[h];	labels->buckets[h] = p;	(*IR->defsymbol)(&p->sym);	return &p->sym;}/*constant:将类型为ty的常量值v安装于常量的符号表中*/Symbol constant(Type ty,Value v){	struct entry *p;	unsigned h = v.i&(HASHSIZE - 1);	assert(ty);	for (p=constants->buckets[h]; p ; p=p->link)		if(eqtype(ty,p->sym.type)) {			switch(ty->op) {			case CHAR: 				if(p->sym.u.c.v.c == v.c) return &p->sym; break;			case INT:				if(p->sym.u.c.v.i == v.i) return &p->sym; break;			case UNSIGNED:				if(p->sym.u.c.v.u == v.u) return &p->sym; break;			case ARRAY: case FUNCTION:			case POINTER: if(p->sym.u.c.v.p == v.p) return &p->sym; break;				}		}	NEW0(p,PERM);	p->sym.name = vtoa(ty,v);	p->sym.scope = CONSTANT;	p->sym.type = ty;	p->sym.u.c.v = v;	p->sym.up = constants->all;	constants->all = &p->sym;	p->link = constants->buckets[h];	constants->buckets[h] = p;	(*IR->defsymbol)(&p->sym);	p->sym.defined = 1;	return &p->sym;}char *vtoa(Type ty, Value v){	assert(ty);	switch (ty->op) {	case CHAR:		return stringd(v.c);	case INT:		return stringd(v.i);	case UNSIGNED:		if ((v.u&~0x7fff) == 0)			return stringd(v.u);		else			return stringf("0x%x", v.u);	case ARRAY:		if (ty->type->op == CHAR)			return v.p;	case POINTER: case FUNCTION:		return stringf("0x%x", v.p);	default:assert(0);	}	return NULL;}Symbol intconst(int n){	Value v;	v.i = n;	return constant(inttype,v);}/*genident:生成类型为ty作用域为lev的内部标示符*/Symbol genident(Type ty, int lev){	Symbol p;	NEW0(p, lev >= LOCALS ? FUNC:PERM);	p->name = stringd(genlabel(1));	p->scope = lev;	p->type = ty;	p->generated = 1;	if (GLOBAL == lev)		(*IR->defsymbol)(p);	return p;}Symbol temporary(int reg, Type ty, int lev){	Symbol p = genident(ty, lev);	p->temporary = 1;	p->sclass = reg;	return p;}Symbol newtemp(int reg,int tc){	Symbol p = temporary(reg,btot(tc), LOCALS);	(*IR->local)(p);	p->defined = 1;	return p;}

⌨️ 快捷键说明

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