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

📄 symbol.c

📁 用C++编写的一个编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
			sym1 = sym1->next;
			sym2 = sym2->next;
		}
		if(sym2||sym1)//not end at the same time
			return 2;
		break;

	case bt_pointer:
		if(t1->array_vol != t2->array_vol)
			return 1;
		if(checkTypeSame(t1->subtype, t2->subtype))
			return 1;
		else return 0;
	case bt_typedef:
		if(t1->tname&&t2->tname
			&&strcmp(t1->tname,t2->tname))
			return 2;	//with the same name
	}
	return 0;
}
//only const string
int add_const(char *string)
{
	static int total, size;
	char *str;
	if(!string)
		debug("[add_const] null pointer input\n");
	total += size;
	size = strlen(string)+1;
	str = dmalloc(size, false);
	memcpy(str, string, size);
	push_List(&const_list, str);
	return total;
}
void *value_init(struct _expnode *exp)
{
	//now just this, lack stuct or array init
	if(exp != NULL)
		return &(exp->val);
	else 
		return NULL;
}
int global_define(
	struct _supertype *prefix,
	struct _sym *var
)
{
	Type *tmptype;
	HashNode *hashnode;

	if(!prefix)
	{
		debug("[global_define]null pointer input\n");
		return -1;
	}
	if(!var)
	{
		if(prefix->sc == sc_typedef)
			generror(ERR_SYNTAX_ERROR, "no target type name");
//		else
//			generror(ERR_SYNTAX_ERROR, "can not specify a type with storage class");
		return -1;
	}
	if(prefix->sc == sc_auto || prefix->sc == sc_register)
	{
		generror(ERR_STORAGE_CLASS, "register/auto in global area");
		return -1;
	}
//??the name of array/function is const pointer
	for(;var;var = var->next)
	{
		if(prefix->sc == sc_typedef)
		{
			tmptype = newType(var->name, bt_typedef, NULL);
			tmptype->subtype = compoundType(var->datatype, prefix->datatype);
			checkTypeSize(tmptype);//may be of no use
			add_newType(tmptype);
			continue;
		}
		
		////??????????
		
		var->init = value_init(var->init);
		var->datatype = compoundType(var->datatype, prefix->datatype);
		checkTypeSize(var->datatype);
		hashnode= add_node(symtab, SYMTABSIZE, var->name, var);
		var->value.linkname = var->name;
		if(var->datatype->basic_type != bt_func)
		{
			if(prefix->sc == UNKNOWN)
				var->storage_class = sc_global;
			else 
				var->storage_class = prefix->sc;
			
			if(var->datatype->array_vol != 0)
				var->const_flag = true;
			if(hashnode)
				generror(ERR_REDEF_VAR, var->name);
			else if(var->storage_class == sc_external)
				push_List(&extern_list, var);
			else 
			{
				if(var->storage_class == sc_global)
					push_List(&extern_list, var);
				if(var->init)
					push_List(&data_list, var);
				else 
					push_List(&bss_list, var);
			}
		}
		else 
		{
			if(prefix->sc == UNKNOWN)
				var->storage_class = sc_external;
			else 
				var->storage_class = prefix->sc; 

			//function name is a constant function pointer
			var->datatype->basic_type = bt_funcptr;
			var->datatype->size = 4;
			var->const_flag = true;
			var->value.localdata =0;
			if(hashnode)
			{
				if(checkTypeSame(((Symbol*)hashnode->val)->datatype, var->datatype)>1)
					generror(ERR_DECL_CONFLICT, var->name);
			}
			else 
				push_List(&extern_list, var);
			
		}
	}
	return 0;
}
int add_local_sym(Symbol *sym)
{
	HashNode *hashnode;
	Symbol *tmp;
	ListNode *item;

	hashnode = add_node(symtab, SYMTABSIZE, sym->name, sym);
	if(hashnode)
	{
		do{
		for(item = current_block->add.head;item;item=item->next)
		{
			tmp = item->content;
			if(!strcmp(tmp->name, sym->name))
				break;
		}
		if(item)break;
		for(item=current_block->dup.head;item;item= item->next)
		{
			tmp = item->content;
			if(!strcmp(tmp->name, sym->name))
				break;
		}
		}while(0);
		if(item)
			return -1;
		else
		{
			push_List(&current_block->dup, hashnode->val);
			hashnode->val = sym;
		}
	}
	else 
	{
		push_List(&current_block->add, sym);
	}
	return 0;
}

struct _stmtnode *local_define(
	struct _supertype *prefix,
	struct _sym *var
)
{
	char buf[64];
	ExpNode *left, *init = NULL;
	if(!prefix)
	{
		debug("[local_define]null pointer input\n");
		return NULL;
	}
	
	if(prefix->sc == UNKNOWN || prefix->sc == sc_register)
		prefix->sc = sc_auto;

	for(;var;var = var->next)
	{
		var->storage_class = prefix->sc;
		var->datatype = compoundType(var->datatype, prefix->datatype);
		checkTypeSize(var->datatype);
		if(var->datatype->array_vol != 0)
			var->const_flag = true;
		if(add_local_sym(var))
		{
			generror(ERR_REDEF_VAR, var->name);
			continue;
		}
		
		if(var->storage_class == sc_external)
		{
			debug("You had better to declare a external variable in a local area");
			/*pre= hashnode->val;
			if(checkTypeSame(pre->datatype, var->datatype))
				generror(ERR_DECL_CONFLICT, var->name);
				*/
		}
		else if(var->storage_class == sc_static)
		{
			sprintf(buf, "%s@%s@l%d", var->name, current_func->name, lineno);
			var->value.linkname = newstrcpy(buf, UNKNOWN);
			push_List(&bss_list, var);
		}
		else //assume no func decl here 
		{
			current_func->value.localdata = align_add(
				current_func->value.localdata, var->datatype->size);
			var->value.offset = -current_func->value.localdata;
		}
		//check
		
		if(var->init)
		{
			left = evaluate_id_exp(var->name);
			appendObject(&init, evaluate_assign_exp(exp_assign, left, var->init));
		}
	}
	if(init)
		return newCalcStmt(stmt_exp, init, NULL, NULL, NULL, currentfile, lineno);
	else
		return NULL;
}
//log out all the symbols from the symbol table
//recover all the symbols in dup list
void enter_block()
{
	current_block = dmalloc(sizeof(LocalDefines), false);
	push_List(&block_list, current_block);
}
//log out all the symbols from the symbol table
//recover all the symbols in dup list
void leave_block()
{
	ListNode *add=current_block->add.head, *dup=current_block->dup.head;
	Symbol *sym;
	HashNode *hashnode;
	for(;add;add=add->next)
	{
		sym = add->content;
		remove_node(symtab,SYMTABSIZE, sym->name);
	}
	for(;dup;dup= dup->next)
	{
		sym = dup->content;
		hashnode = lookup_node(symtab,SYMTABSIZE, sym->name);
		hashnode->val = sym;
	}
	popback_List(&block_list);
}
//the parameter and return value to ready 
//call  asm_func_begin
int blocklevel;
void prepare_local(
	struct _sym *func
)
{
	Symbol *para;
	int paraoffset = 8;
	HashNode *hashnode = lookup_node(symtab, SYMTABSIZE, func->name);
	//check redefine
	para = hashnode->val;
	if(para->storage_class ==sc_global)
		generror(ERR_REDEF_FUNC, para->name);

	func->storage_class = sc_global;
	current_func = func;

	enter_block();
	blocklevel=0;

	para = func->datatype->arglist;
	if(para->datatype->basic_type == bt_void)
		return;
	while(para&&para->datatype->basic_type != bt_ellipsis)
	{
		para->storage_class = sc_auto;
		para->datatype->array_vol=0;//array parameter is pointer 
		checkTypeSize(para->datatype);
		if(add_local_sym(para))
		{
			generror(ERR_REDEF_VAR, para->name);
		}
		else
		{
			para->value.offset = paraoffset;
			paraoffset += (para->datatype->size+3)&~3;//in stack there are only times of dword
		}
		para =para->next;
	}
}

void exit_local()
{
	Symbol *func = current_func;
	
	clean_named_label();
	leave_block();
	current_func = NULL;
	//release_local();
}

struct _datatype *add_newType(
	struct _datatype *newtype
)
{
	HashNode *hash;
	Type *pre;
	if(!newtype->tname||!newtype->tname[0])
	{
		debug("can not define a type without a name\n");
		return newtype;
	}
	hash = add_node(typetab, TYPETABSIZE, newtype->tname, newtype);
	if(hash)
	{
		pre = hash->val;
		if(checkTypeSame(pre, newtype))
			generror(ERR_REDEF_TYPE, newtype->tname);
		newtype = pre;
	}
	else 
	{
		//port to global memory management
		//hash->val = new_sameType(newtype, false);
	}
	return newtype;
}


//get out of a function, remember to clean this list
void clean_named_label()
{
	Symbol *label;
	while(label = popfront_List(&label_list))
	{
		remove_node(symtab, SYMTABSIZE, label->name);
	}
}

struct _sym *add_named_label(
	char *labelname, 
	int labelno
)
{
	Symbol *asym = newSymbol(labelname, sc_label, NULL), *pre;
	HashNode *hashnode = add_node(symtab, SYMTABSIZE, labelname, asym);
	if(hashnode)
	{
		pre = hashnode->val;
		if(pre->storage_class == sc_label)
		{
			if(labelno != UNKNOWN)
			{
				if(pre->value.labelno != UNKNOWN)
					generror(ERR_REDEF_LABEL, labelname);
				else pre->value.labelno = labelno;
			}	
			return pre;
		}
		else
		{ 
			generror(ERR_REDEF_VAR, labelname);
			return NULL;
		}
	}
	else 
	{
		asym->value.labelno = labelno;
		push_List(&label_list, asym);
		return asym;
	}
}

⌨️ 快捷键说明

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