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

📄 symtbl.c

📁 < 虚拟机设计与实现>>的 windows版本
💻 C
字号:
#include "symtbl.h"

#include "strtbl.h"
#include "error.h"

/*called via public constructors/destructors*/
int initProc(struct Procedure * ptr);
void freeProc(struct Procedure ** ptr);

/*called via public addProc___HL */
int setProcRet(struct Procedure *ptr, struct StackFrame *add);
int addProcArg(struct Procedure *ptr, struct StackFrame *add);
int addProcLoc(struct Procedure *ptr, struct StackFrame *add);
int addProcLbl(struct Procedure *ptr, struct Label *add);

/*called via public printSymTbl*/
void printGlobVar(struct GlobalVariable *ptr);
void printProc(struct Procedure *ptr);

int SymbolTable_init()
{
	U4 i;

	globVar = (struct GlobalVariable *)
		      malloc(GLOB_INIT * sizeof(struct GlobalVariable));
	if (globVar == NULL)
	{
		ERROR0("SymbolTable::SymbolTable_init(): out of memory\n");
		return FALSE;
	}
	nGlobVar = GLOB_INIT;
	iGlobVar = 0;

	proc = (struct Procedure *)
		   malloc(PROC_INIT * sizeof(struct Procedure));
	if (proc == NULL)
	{
		ERROR0("SymbolTable::SymbolTable(): out of memory\n");
		return FALSE;
	}
	nProc = PROC_INIT;
	iProc = 0;
	for (i = 0; i < PROC_INIT; i++)
	{ 
		if (initProc(&proc[i]) == FALSE)
			return FALSE;
	}
	
	SYM_DEBUG1("SymbolTable::SymbolTable_init(): %lu globals\n", GLOB_INIT);
	SYM_DEBUG1("SymbolTable::SymbolTable_init(): %lu procs\n", PROC_INIT);

	return TRUE;

}

void SymbolTable_free()
{
	if (globVar != NULL)
	{
		free(globVar);
		globVar = NULL;
		SYM_DEBUG1("SymbolTable::SymbolTable_free(): free %lu globals\n", nGlobVar);
	}
	
	if (proc != NULL)
	    freeProc(&proc);
	return;
}

void freeProc(struct Procedure ** ptr)
{
	U4 i;

	SYM_DEBUG1("SymbolTable::freeProc(): freeing %lu procs\n", nProc);
	for (i = 0; i < nProc; i++)
	{
		if ((*ptr)[i].arg != NULL)
		{
		    free((*ptr)[i].arg);
			(*ptr)[i].arg = NULL;
		}
		if ((*ptr)[i].local != NULL)
		{
		    free((*ptr)[i].local);
			(*ptr)[i].local = NULL;
		}
		if ((*ptr)[i].label != NULL)
		{
		    free((*ptr)[i].label);
			(*ptr)[i].label = NULL;
		}
	}
	free(*ptr);
	*ptr = NULL;
	SYM_DEBUG0("SymbolTable::freeProc(): done freeing procs\n");
	return;

}

int initProc(struct Procedure * ptr)
{
	(*ptr).text = 0;		
	(*ptr).address = 0;		
	(*ptr).line = 0;
	
	/*exactly one struct StackFrame ret*/
	(*ptr).nRet = 0;

	(*ptr).arg = (struct StackFrame *)
		         malloc(ARG_INIT * sizeof(struct StackFrame));
	if ((*ptr).arg == NULL)
	{
		ERROR0("SymbolTable::initProc(): out of memory\n");
		return FALSE;
	}
	(*ptr).nArg = ARG_INIT;
	(*ptr).iArg = 0;

	(*ptr).local = (struct StackFrame *)
		           malloc(LOC_INIT * sizeof(struct StackFrame));
	if ((*ptr).local == NULL)
	{
		ERROR0("SymbolTable::initProc(): out of memory\n");
		return FALSE;
	}
	(*ptr).nLocal = LOC_INIT;
	(*ptr).iLocal = 0;

	(*ptr).label = (struct Label *)
		           malloc(LBL_INIT * sizeof(struct Label));
	if ((*ptr).label == NULL)
	{
		ERROR0("SymbolTable::initProc(): out of memory\n");
		return FALSE;
	}
	(*ptr).nLabel = LBL_INIT;
	(*ptr).iLabel = 0;
	return TRUE;

}

int addGlobVar(struct GlobalVariable * add)
{
	U4 i;
	U4 newsize;
	struct GlobalVariable * new_gv;

	/* capacity n will have indices 0,...,n-1 */

	if (iGlobVar == nGlobVar)
	{
		newsize = nGlobVar + GLOB_INC;
		new_gv = (struct GlobalVariable *)
			     malloc(newsize * sizeof(struct GlobalVariable));
		if (new_gv == NULL)
		{
			ERROR0("SymbolTable::addGlobVar(): out of memory\n");
			return FALSE;
		}
		else
		{
			for (i = 0; i < nGlobVar; i++)
			{ 
				new_gv[i] = globVar[i]; 
			}
			free(globVar);
			globVar = new_gv;
			nGlobVar = nGlobVar + GLOB_INC;
		}
	}
	
	globVar[iGlobVar] = *add;
	iGlobVar++;
	return TRUE;

}

int addProc(struct Procedure * add)
{
	U4 i;
	U4 newsize;
	struct Procedure * new_p;

	/* capacity n will have indices 0,...,n-1 */

	if (iProc == nProc)
	{
		newsize = nProc + PROC_INC;
		new_p = (struct Procedure *)
			    malloc(newsize * sizeof(struct Procedure));
		if (new_p == NULL)
		{
			ERROR0("SymbolTable::addProc(): out of memory\n");
			return FALSE;
		}
		else
		{
			for (i = nProc; i < newsize; i++)
			{ 
				if (initProc(&new_p[i]) == FALSE)
			        return FALSE;
			}
			for (i = 0; i < nProc; i++)
			{ 
				new_p[i] = proc[i]; 
			}
			free(proc);
			proc = new_p;
			nProc = nProc + PROC_INC;
		}
	}
	
	/*
	adding virgin proc, no internal elements yet
	(i.e. args, locals, labels )
	*/

	proc[iProc].text = (*add).text;
	proc[iProc].address = (*add).address;
	proc[iProc].line = (*add).line;

	iProc++;
	return TRUE;

}

int setProcRet(struct Procedure *ptr, struct StackFrame *add)
{
	if ((*ptr).nRet == 1)
	{
		ERROR1("SymbolTable::setProcRet() line %d: duplicated return.\n", (*add).line);
		return FALSE;
	}
	(*ptr).nRet = 1;
	(*ptr).ret = *add;
	return TRUE;

}

int addProcArg(struct Procedure *ptr, struct StackFrame *add)
{
	U4 i;
	U4 newsize;
	struct StackFrame * new_sf;

	/* capacity n will have indices 0,...,n-1 */

	if ((*ptr).iArg == (*ptr).nArg)
	{
		newsize = (*ptr).nArg + ARG_INC;
		new_sf = (struct StackFrame *)
			     malloc(newsize * sizeof(struct StackFrame));
		if (new_sf == NULL)
		{
			ERROR0("SymbolTable::addProcArg(): out of  memory\n");
			return FALSE;
		}
		else
		{
			for (i = 0; i < (*ptr).nArg; i++)
			{ 
				new_sf[i] = (*ptr).arg[i]; 
			}
			free((*ptr).arg);
			(*ptr).arg = new_sf;
			(*ptr).nArg = (*ptr).nArg + ARG_INC;
		}
	}
	
	(*ptr).arg[(*ptr).iArg] = *add;
	(*ptr).iArg++;
	return TRUE;

}

int addProcLoc(struct Procedure *ptr, struct StackFrame *add)
{
	U4 i;
	U4 newsize;
	struct StackFrame *new_sf;

	/* capacity n will have indices 0,...,n-1 */

	if ((*ptr).iLocal == (*ptr).nLocal)
	{
		newsize = (*ptr).nLocal + LOC_INC;
		new_sf = (struct StackFrame *)
			     malloc(newsize * sizeof(struct StackFrame));
		if (new_sf == NULL)
		{
			ERROR0("SymbolTable::addProcArg(): out of memory\n");
			return FALSE;
		}
		else
		{
			for (i = 0; i < (*ptr).nLocal; i++)
			{ 
				new_sf[i] = (*ptr).local[i]; 
			}
			free((*ptr).local);
			(*ptr).local = new_sf;
			(*ptr).nLocal = (*ptr).nLocal + LOC_INC;
		}
	}
	
	(*ptr).local[(*ptr).iLocal] = *add;
	(*ptr).iLocal++;
	return TRUE;

}

int addProcLbl(struct Procedure *ptr, struct Label *add)
{
	U4 i;
	U4 newsize;
	struct Label * new_sf;

	/* capacity n will have indices 0,...,n-1 */

	if ((*ptr).iLabel == (*ptr).nLabel)
	{
		newsize = (*ptr).nLabel + LBL_INC;
		new_sf = (struct Label *)
			     malloc(newsize * sizeof(struct Label));
		if (new_sf == NULL)
		{
			ERROR0("SymbolTable::addProcArg(): out of memory\n");
			return FALSE;
		}
		else
		{
			for (i = 0; i < (*ptr).nLabel; i++)
			{ 
				new_sf[i] = (*ptr).label[i]; 
			}
			free((*ptr).label);
			(*ptr).label = new_sf;
			(*ptr).nLabel = (*ptr).nLabel + LBL_INC;
		}
	}
	
	(*ptr).label[(*ptr).iLabel] = *add;
	(*ptr).iLabel++;
	return TRUE;

}

int setProcRetHL(struct StackFrame * add)
{
	/*
	add arg while processing current procedure
	current proc is at (iProc-1) 
	*/
	return setProcRet(&proc[iProc - 1], add);

}

int addProcArgHL(struct StackFrame * add)
{
	/*
	add arg while processing current procedure
	current proc is at (iProc-1) 
	*/
	return addProcArg(&proc[iProc - 1], add);

}

int addProcLocHL(struct StackFrame * add)
{
	/*
	add local while processing current procedure
	current proc is at (iProc-1) 
	*/
	return addProcLoc(&proc[iProc - 1], add);

}

int addProcLblHL(struct Label * add)
{
	/*
	add label while processing current procedure
	current proc is at (iProc-1) 
	*/
	return addProcLbl(&proc[iProc - 1], add);

}

void printSymTbl()
{
	U4 i;

	printf("\nSYMBOL TABLE------------\n");
	for (i = 0; i < iGlobVar; i++)
	{
		printf("%d) ",i); 
		printGlobVar(&globVar[i]); 
		printf("\n");
	}
	for(i = 0; i < iProc; i++)
	{
		printf("%d) ",i); 
		printProc(&proc[i]); 
		printf("\n");
	}
	return;

}

void printGlobVar(struct GlobalVariable *ptr)
{
	printf("GLOBAL VAR--------------\n");
	printf("identifier=%s\n", &(strtbl_text[(*ptr).text]));
	printf("data type=%s\n", globSz[(*ptr).dType]);
	printf("length="); 
	pU8((*ptr).len); 
	printf("\n");
	printf("size="); 
	pU8((*ptr).size); 
	printf("\n");
	printf("offset="); 
	pS8(-((S8)(*ptr).offset)); 
	printf("\n");
	printf("line=%lu\n", (*ptr).line); 
	return;

}

void printProc(struct Procedure *ptr)
{
	U4 i;
	
	printf("PROC--------------------\n");
	printf("identifier=%s\n", &(strtbl_text[(*ptr).text]));
	printf("address="); 
	pU8((*ptr).address); 
	printf("\n");
	printf("line=%lu\n\n", (*ptr).line);

	if ((*ptr).nRet)
	{
		printf("RET\n");
		printf("\tid=%s\n", &(strtbl_text[((*ptr).ret).text]));
		printf("\tfpOffset=%ld\n", ((*ptr).ret).fpOffset);
		printf("\tline=%lu\n", ((*ptr).ret).line);
	}

	printf("ARGS\n");
	for (i = 0; i < (*ptr).iArg; i++)
	{
		printf("\t%d)",i);
		printf("id=%s\n", &(strtbl_text[((*ptr).arg[i]).text]));
		printf("\tfpOffset=%ld\n", ((*ptr).arg[i]).fpOffset);
		printf("\tline=%lu\n",((*ptr).arg[i]).line);
	}

	printf("LOCALS\n");
	for (i = 0; i < (*ptr).iLocal; i++)
	{
		printf("\t%d)",i);
		printf("id=%s\n", &(strtbl_text[((*ptr).local[i]).text]));
		printf("\tfpOffset=%ld\n", ((*ptr).local[i]).fpOffset);
		printf("\tline=%lu\n",((*ptr).local[i]).line);
	}

	printf("LABELS\n");
	for (i = 0; i < (*ptr).iLabel; i++)
	{
		printf("\t%d)",i);
		printf("id=%s\n", &(strtbl_text[((*ptr).label[i]).text]));
		printf("\taddress="); 
		pU8(((*ptr).label[i]).address); 
		printf("\n");
		printf("\tline=%lu\n",((*ptr).label[i]).line);
	}
	return;

}

void test_SymbolTable()
{
	U8 str_index;
	char name[32];
	struct GlobalVariable globvar;

	struct Procedure proc;
	struct StackFrame sf;
	struct Label label;

	strcpy(name, "gVar_1");
	str_index = strtbl_iStr;
	addStrTbl(name);
	globvar.text = str_index;
	globvar.dType = 1;
	globvar.len = 0;
	globvar.size = 0;
	globvar.offset = 0;
	globvar.line = 0;
	addGlobVar(&globvar);

	strcpy(name, "gVar_2");
	str_index = strtbl_iStr;
	addStrTbl(name);
	globvar.text = str_index;
	globvar.dType = 1;
	globvar.len = 0;
	globvar.size = 0;
	globvar.offset = 2;
	globvar.line = 0;
	addGlobVar(&globvar);

	/*add 1 procedures*/

	strcpy(name, "proc1");
	str_index = strtbl_iStr;
	addStrTbl(name);
	proc.text = str_index;
	proc.address = 0;
	proc.line = 0;
	addProc(&proc);

	strcpy(name, "proc1_ret");
	str_index = strtbl_iStr;
	addStrTbl(name);
	sf.text = str_index;
	sf.fpOffset = 0;
	sf.line = 0;
	setProcRetHL(&sf);

	strcpy(name, "proc1_arg1");
	str_index = strtbl_iStr;
	addStrTbl(name);
	sf.text = str_index;
	sf.fpOffset = 0;
	sf.line =0;
	addProcArgHL(&sf);

	strcpy(name, "proc1_arg2");
	str_index = strtbl_iStr;
	addStrTbl(name);
	sf.text = str_index;
	sf.fpOffset = 0;
	sf.line =0;
	addProcArgHL(&sf);
	
	strcpy(name, "proc1_arg3");
	str_index = strtbl_iStr;
	addStrTbl(name);
	sf.text = str_index;
	sf.fpOffset = 0;
	sf.line =0;
	addProcArgHL(&sf);
	
	strcpy(name, "proc1_arg4");
	str_index = strtbl_iStr;
	addStrTbl(name);
	sf.text = str_index;
	sf.fpOffset = 0;
	sf.line =0;
	addProcArgHL(&sf);
	
	strcpy(name, "proc1_loc1");
	str_index = strtbl_iStr;
	addStrTbl(name);
	sf.text = str_index;
	sf.fpOffset = 0;
	sf.line =0;
	addProcLocHL(&sf);
	
	strcpy(name, "proc1_loc2");
	str_index = strtbl_iStr;
	addStrTbl(name);
	sf.text = str_index;
	sf.fpOffset = 0;
	sf.line =0;
	addProcLocHL(&sf);
	
	strcpy(name, "proc1_loc3");
	str_index = strtbl_iStr;
	addStrTbl(name);
	sf.text = str_index;
	sf.fpOffset = 0;
	sf.line =0;
	addProcLocHL(&sf);
	
	strcpy(name, "proc1_loc4");
	str_index = strtbl_iStr;
	addStrTbl(name);
	sf.text = str_index;
	sf.fpOffset = 0;
	sf.line =0;
	addProcLocHL(&sf);
	
	strcpy(name, "proc1_lbl1");
	str_index = strtbl_iStr;
	addStrTbl(name);
	label.text = str_index;
	label.address = 0;
	label.line =0;
	addProcLblHL(&label);
	
	strcpy(name, "proc1_lbl2");
	str_index = strtbl_iStr;
	addStrTbl(name);
	label.text = str_index;
	label.address = 0;
	label.line =0;
	addProcLblHL(&label);
	
	strcpy(name, "proc1_lbl3");
	str_index = strtbl_iStr;
	addStrTbl(name);
	label.text = str_index;
	label.address = 0;
	label.line =0;
	addProcLblHL(&label);
	
	strcpy(name, "proc1_lbl4");
	str_index = strtbl_iStr;
	addStrTbl(name);
	label.text = str_index;
	label.address = 0;
	label.line =0;
	addProcLblHL(&label);

	printSymTbl();
	printStrTbl();
	return;

}

⌨️ 快捷键说明

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