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

📄 symtbl.cpp

📁 虚拟机设计与实现——C/C++
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+                                                                   +
+ symtbl.cpp - the symbol table and associated functions            +
+                                                                   +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

/*
	SymTbl---+---GlobalVariable
			 |
			 +---Procedure-----+--StackFrame ( ret, arg, local )
						       |
						       +--Label

	Pass1 - uses directives to fill out GlobVar, Proc entries
	Pass2 - uses above to generate bytecode
*/

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ macros and private variables                                      +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

#define GLOB_INIT	10		/* _INIT = initial array size */
#define GLOB_INC	5		/* _INC = increment size when expand array */

#define PROC_INIT	10
#define PROC_INC	5

#define ARG_INIT	5	
#define ARG_INC		5	

#define LOC_INIT	5
#define LOC_INC		5

#define LBL_INIT	10
#define LBL_INC		10

/*#define SYM_DEBUG		1*/

#ifdef	SYM_DEBUG
#define	SYM_DEBUG0(arg);			printf(arg);
#define SYM_DEBUG1(arg1,arg2);		printf(arg1,arg2);
#define SYM_DEBUG2(arg1,arg2,arg3);	printf(arg1,arg2,arg3);
#else
#define	SYM_DEBUG0(arg);
#define SYM_DEBUG1(arg1,arg2);
#define SYM_DEBUG2(arg1,arg2,arg3);
#endif

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ declaration                                                       +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

class SymbolTable
{
	StringTable *strTbl;

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

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

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

	public:
	struct GlobalVariable *globVar;
	U4 nGlobVar;
	U4 iGlobVar;

	struct Procedure *proc;
	U4 nProc;
	U4 iProc;

	SymbolTable(StringTable *st);
	~SymbolTable();

	void addGlobVar(struct GlobalVariable *add);
	void addProc(struct Procedure *add);

	/*set elements of current procedure*/
	void setProcRetHL(struct StackFrame *add);
	void addProcArgHL(struct StackFrame *add); 
	void addProcLocHL(struct StackFrame *add); 
	void addProcLblHL(struct Label *add); 

	void printSymTbl();

	void test();
};

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ definitions                                                       +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

SymbolTable::SymbolTable(StringTable *st)
{
	U4 i;

	strTbl = st;

	globVar = (struct GlobalVariable*)
		      malloc(GLOB_INIT*sizeof(struct GlobalVariable));

	if(globVar==NULL)
	{
		ERROR0("SymbolTable::SymbolTable(): out of memory\n");
		FATAL_ERROR();
	}
	nGlobVar = GLOB_INIT;
	iGlobVar = 0;

	proc = (struct Procedure*)
		   malloc(PROC_INIT*sizeof(struct Procedure));

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

	return;

}/*end constructor*/

/*-----------------------------------------------------------------*/

void SymbolTable::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");
		FATAL_ERROR();
	}
	(*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");
		FATAL_ERROR();
	}
	(*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");
		FATAL_ERROR();
	}
	(*ptr).nLabel = LBL_INIT;
	(*ptr).iLabel = 0;
	return;

}/*end initProc*/

/*-----------------------------------------------------------------*/

SymbolTable::~SymbolTable()
{
	free(globVar);
	SYM_DEBUG1("SymbolTable::~SymbolTable(): free %lu globals\n",nGlobVar);
	freeProc(proc);
	return;

}/*end destructor*/

/*-----------------------------------------------------------------*/

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

}/*end freeProc*/

/*-----------------------------------------------------------------*/

void SymbolTable::addGlobVar(struct GlobalVariable *add)
{
	U4 i;
	struct GlobalVariable *new_gv;

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

	if(iGlobVar == nGlobVar)
	{
		U4 newsize = nGlobVar + GLOB_INC;
		new_gv = (struct GlobalVariable*)
			     malloc((newsize)*(sizeof(struct GlobalVariable)));
		if(new_gv==NULL)
		{
			ERROR0("SymbolTable::addGlobVar(): out of memory\n");
			FATAL_ERROR();
		}
		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;

}/*end addGlobVar*/

/*-----------------------------------------------------------------*/

void SymbolTable::addProc(struct Procedure *add)
{
	U4 i;
	Procedure *new_p;

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

	if(iProc == nProc)
	{
		U4 newsize = nProc + PROC_INC;
		new_p = (struct Procedure*)
			    malloc(newsize*sizeof(struct Procedure));
		if(new_p==NULL)
		{
			ERROR0("SymbolTable::addProc(): out of memory\n");
			FATAL_ERROR();
		}
		else
		{
			for(i=nProc;i<newsize;i++){ initProc(&new_p[i]); }
			for(i=0;i<nProc;i++){ new_p[i] = proc[i]; }
			delete(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;

}/*end addProc*/

/*-----------------------------------------------------------------*/

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

}/*end setProcRetHL*/

void SymbolTable::setProcRet(struct Procedure *ptr, 
							 struct StackFrame *add)
{
	(*ptr).nRet=1;
	(*ptr).ret=*add;
	return;

}/*end setProcRet*/

/*-----------------------------------------------------------------*/

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

}/*end addProcArgHL*/

void SymbolTable::addProcArg(struct Procedure *ptr, 
							 struct StackFrame *add)
{
	U4 i;
	struct StackFrame *new_sf;

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

	if((*ptr).iArg == (*ptr).nArg)
	{
		U4 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");
			FATAL_ERROR();
		}
		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;

}/*end addProcArg*/

/*-----------------------------------------------------------------*/

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

}/*end addProcLocHL*/

void SymbolTable::addProcLoc(struct Procedure *ptr, 
							 struct StackFrame *add)
{
	U4 i;
	struct StackFrame *new_sf;

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

	if((*ptr).iLocal == (*ptr).nLocal)
	{
		U4 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");
			FATAL_ERROR();
		}
		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;

}/*end addProcLoc*/

/*-----------------------------------------------------------------*/

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

}/*end addProcLblHL*/

void SymbolTable::addProcLbl(struct Procedure *ptr, 
							 struct Label *add)
{
	U4 i;
	struct Label *new_sf;

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

	if((*ptr).iLabel == (*ptr).nLabel)
	{
		U4 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");
			FATAL_ERROR();
		}
		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;

}/*end addProcLbl*/

/*-----------------------------------------------------------------*/

void SymbolTable::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;

⌨️ 快捷键说明

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