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

📄 pascalcompiler.cpp

📁 袖珍型的pascal编译器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// Function name	: CPascalCompiler::InsertSymbol
// Description	    : 
// Return type		: void 
// Argument         : Symbol *s
///////////////////////////////////////////////////////////////

void CPascalCompiler::InsertSymbol(Symbol *s)
{
	Symbol *simb=NULL;
	if (m_SymbTableCollection.RetreaveSymbolCL(s->m_sName,simb))
	{
		throw error(SET_GENERAL,CString(s->m_sName)+CString(" item is already declared "));
	}
	m_SymbTableCollection.InsertSymbol (s);
}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 5/28/99 6:37:10 PM
// Function name	: CPascalCompiler::IsProc
// Description	    : Check if the parameter is a procedure
// Return type		: BOOL 
// Argument         : CString &str
///////////////////////////////////////////////////////////////

BOOL CPascalCompiler::IsProc(CString &str)
{
	Symbol *simb=NULL;
	if (!RetreaveSymbol(str,simb))
		return FALSE;
	return (simb->m_nClass == CT_PROCEDURE);
}




///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:35:50 PM
// Function name	: CPascalCompiler::Atribuire
// Description	    : 
// Return type		: void 
///////////////////////////////////////////////////////////////

void CPascalCompiler::Atribuire()
{
	// Variabila
	ExprInfo t1;
	ExprInfo t2;
	VariabilaAdr(t1);
	if (NextToken()!=TT_IS)
		throw error(SET_EXPECTED, CString(":="));
	Expr(t2);
	if (t1.m_nAtribLValue == LV_VALUE)
		throw error(SET_GENERAL, CString("Invalid variable"));
	if (t1.m_nAtribTip != t2.m_nAtribTip )
	{
		if (!(t1.m_nAtribTip == ET_REAL && t2.m_nAtribTip !=ET_CHAR))
			throw error(SET_GENERAL, CString("Trying to assign between incompatible types"));
	}
	GenerateCode(INSTR_STO);
}



///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 5/27/99 7:13:38 PM
// Function name	: CPascalCompiler::Variabila
// Description	    : This proceses a variable for evaluation purposes, value is put on the stack
// Return type		: void 
// Argument         : ExprInfo &type
///////////////////////////////////////////////////////////////

void CPascalCompiler::Variabila(ExprInfo &type)
{
	if (NextToken()!=TT_WORD)
		throw error(SET_EXPECTED, CString("identifier"));
	CString numevar = GetStrValue();
	int val	= NextToken();
	if (val=='[')
	{
		// Matrix
		Expr(type);	// Puts the index of the matrix on the stack

		if (NextToken()!=']')
			throw error(SET_EXPECTED, CString("]"));
		if (type.m_nAtribTip != ET_INTEGER)
			throw error(SET_GENERAL,CString("Table must have integer index"));
		Symbol *simb = NULL;
		if (!RetreaveSymbol(numevar,simb))
			throw error(SET_GENERAL,CString("Undeclared variable: ")+CString(numevar));
		if (simb->m_nClass!=CT_VAR_ARRAY)
				throw error(SET_GENERAL,CString("Invalid variable usage: ")+CString(numevar));
		type.m_nAtribLValue = LV_ADDRESS;
		type.m_nAtribTip = simb->m_nType ;
		// Generate code
		// put the variable on the stack
		// the index is on the stack Lets move it to the RX register
		GenerateCode(INSTR_MVRX);
		// Now we can try to push the value on the stack
		// let us check the level of the value with the current level
		
		if (m_nVNivel == simb->m_nNivel )
		{
			// No Frame change needed
			GenerateCode(INSTR_LODIX,(OFFSET) (simb->m_nAdrel+m_nVNivel+1));
		}
		else
		{
			// Frame Change needed
			GenerateCode(INSTR_CHGSFP,(BYTE)simb->m_nNivel);
			GenerateCode(INSTR_LODIX,(OFFSET)(simb->m_nAdrel+simb->m_nNivel+1));
			// Remake the frame
			GenerateCode(INSTR_RSTSFP);
		}


		return;
	}
	else
		if (val=='.')
		{
			if (NextToken()!=TT_WORD)
				throw error(SET_EXPECTED, CString("identifier"));
			CString numecamp = GetStrValue();
			
			Symbol *simb1 = NULL,*simb2 = NULL;
			if (!RetreaveSymbol(numevar,simb1))
				throw error(SET_GENERAL,CString("Undeclared variable: ")+CString(numevar));
			if (simb1->m_nClass!=CT_VAR_RECORD)
				throw error(SET_GENERAL,CString("Invalid variable usage: ")+CString(numevar));

			if (!RetreaveSymbol(numecamp,simb2))
				throw error(SET_GENERAL,CString("Invalid record field: ")+CString(numecamp));
			if (simb2->m_nClass!=CT_VAR_RECORD_FIELD)
				throw error(SET_GENERAL,CString("Invalid record field: ")+CString(numecamp));
			if (simb2->m_ListaRec.Find(numevar)==NULL)
				throw error(SET_GENERAL,CString("Invalid record field: ")+CString(numecamp));

			type.m_nAtribLValue = LV_ADDRESS;
			type.m_nAtribTip = simb2->m_nType ;

			// Generate code for putting the shit on the stack

			if (m_nVNivel == simb1->m_nNivel )
			{
				// No Frame change needed
				GenerateCode(INSTR_LOD,(OFFSET) (simb1->m_nAdrel+simb2->m_nDeplRec +m_nVNivel+1));
			}
			else
			{
				// Frame Change needed
				GenerateCode(INSTR_CHGSFP,(BYTE)simb1->m_nNivel);
				GenerateCode(INSTR_LOD,(OFFSET)(simb1->m_nAdrel+simb1->m_nNivel + simb2->m_nDeplRec +1 ));
				// Remake the frame
				GenerateCode(INSTR_RSTSFP);
			}

			return;
		}
		else
		{
			Symbol *simb = NULL;
			if (!RetreaveSymbol(numevar,simb))
				throw error(SET_GENERAL,CString("Undeclared variable: ")+CString(numevar));
			if (simb->m_nClass!=CT_VAR_SIMP && 
				simb->m_nClass!=CT_PARAM_VAL && 
				simb->m_nClass!=CT_PARAM_ADR &&
				simb->m_nClass!=CT_CONST)
				throw error(SET_GENERAL,CString("Invalid variable : ")+CString(numevar));

			type.m_nAtribTip = simb->m_nType ;	
			if (simb->m_nClass==CT_CONST)
				{
					type.m_nAtribLValue = LV_VALUE;
					StackEntry entry;
					entry.m_nType = simb->m_nType;
					entry.m_Info = simb->m_Val ;
					GenerateCode(INSTR_LODI,entry);
				}
			
				type.m_nAtribLValue = LV_ADDRESS;
				// Generate code for normal stuff
				
				
				if (m_nVNivel != simb->m_nNivel)
					GenerateCode(INSTR_CHGSFP,(BYTE)simb->m_nNivel);

				Symbol *auxsimb = NULL;
				int np = 0;
				if (RetreaveSymbol(simb->m_sRelated,auxsimb))
					np = auxsimb->m_ListaPar.GetCount();
				switch (simb->m_nClass)
				{
				case CT_VAR_SIMP:
					GenerateCode(INSTR_LOD,(OFFSET) (simb->m_nAdrel+simb->m_nNivel+1));
					break;
				case CT_PARAM_VAL:
					GenerateCode(INSTR_LOD,(OFFSET) (simb->m_nAdrel-np -2));
					break;
				case CT_PARAM_ADR:
					GenerateCode(INSTR_LODEA,(OFFSET) (simb->m_nAdrel-np-2));
					break;

				}
				if (m_nVNivel != simb->m_nNivel)
					GenerateCode(INSTR_RSTSFP);

			PushBack();
		}
}





///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 5/27/99 7:15:53 PM
// Function name	: CPascalCompiler::Variabila
// Description	    : This variable stuff is used for addressing purposes
//					: at the left side of a assignement, put's the address to the stack
// Return type		: void 
// Argument         : ExprInfo &type
// Argument         : REGISTER & address
// Argument         : int level
///////////////////////////////////////////////////////////////

void CPascalCompiler::VariabilaAdr(ExprInfo &type)
{
	// set default value for relative stuff

	if (NextToken()!=TT_WORD)
		throw error(SET_EXPECTED, CString("identifier"));
	CString numevar = GetStrValue();
	int val	= NextToken();
	if (val=='[')
	{
		// Matrix
		Expr(type);	// Puts the index of the matrix on the stack

		if (NextToken()!=']')
			throw error(SET_EXPECTED, CString("]"));
		if (type.m_nAtribTip != ET_INTEGER)
			throw error(SET_GENERAL,CString("Table must have integer index"));
		Symbol *simb = NULL;
		if (!RetreaveSymbol(numevar,simb))
			throw error(SET_GENERAL,CString("Undeclared variable: ")+CString(numevar));
		if (simb->m_nClass!=CT_VAR_ARRAY)
				throw error(SET_GENERAL,CString("Invalid variable usage: ")+CString(numevar));
		type.m_nAtribLValue = LV_ADDRESS;
		type.m_nAtribTip = simb->m_nType ;

		// prepare the addres and the level
		// This is only for arrays, they ca only be 
		GenerateCode(INSTR_MVRX);	// put the index result in RX register
		if (m_nVNivel == simb->m_nNivel )
		{
			// No Frame change needed
			GenerateCode(INSTR_LODAX,(OFFSET) (simb->m_nAdrel+m_nVNivel+1));
		}
		else
		{
			// Frame Change needed
			GenerateCode(INSTR_CHGSFP,(BYTE)simb->m_nNivel);
			GenerateCode(INSTR_LODAX,(OFFSET)(simb->m_nAdrel+simb->m_nNivel+1));
			// Remake the frame
			GenerateCode(INSTR_RSTSFP);
		}


		
		return;
	}
	else
		if (val=='.')
		{
			// REcord
			if (NextToken()!=TT_WORD)
				throw error(SET_EXPECTED, CString("identifier"));
			CString numecamp = GetStrValue();
			
			Symbol *simb1 = NULL,*simb2 = NULL;
			if (!RetreaveSymbol(numevar,simb1))
				throw error(SET_GENERAL,CString("Undeclared variable: ")+CString(numevar));
			if (simb1->m_nClass!=CT_VAR_RECORD)
				throw error(SET_GENERAL,CString("Invalid variable usage: ")+CString(numevar));

			if (!RetreaveSymbol(numecamp,simb2))
				throw error(SET_GENERAL,CString("Invalid record field: ")+CString(numecamp));
			if (simb2->m_nClass!=CT_VAR_RECORD_FIELD)
				throw error(SET_GENERAL,CString("Invalid record field: ")+CString(numecamp));
			if (simb2->m_ListaRec.Find(numevar)==NULL)
				throw error(SET_GENERAL,CString("Invalid record field: ")+CString(numecamp));
			type.m_nAtribLValue = LV_ADDRESS;
			type.m_nAtribTip = simb2->m_nType ;

			// now generate bulshit 
			if (m_nVNivel == simb1->m_nNivel )
			{
				// No Frame change needed
				GenerateCode(INSTR_LODA,(OFFSET) (simb1->m_nAdrel+simb2->m_nDeplRec +m_nVNivel+1));
			}
			else
			{
				// Frame Change needed
				GenerateCode(INSTR_CHGSFP,(BYTE)simb1->m_nNivel);
				GenerateCode(INSTR_LODA,(OFFSET)(simb1->m_nAdrel+simb1->m_nNivel + simb2->m_nDeplRec +1 ));
				// Remake the frame
				GenerateCode(INSTR_RSTSFP);
			}		
			return;
		}
		else
		{
			Symbol *simb = NULL;
			if (!RetreaveSymbol(numevar,simb))
				throw error(SET_GENERAL,CString("Undeclared variable: ")+CString(numevar));
			if (simb->m_nClass!=CT_VAR_SIMP && 
				simb->m_nClass!=CT_PARAM_VAL && 
				simb->m_nClass!=CT_PARAM_ADR &&
				simb->m_nClass!=CT_FUNCTION)
				throw error(SET_GENERAL,CString("Invalid variable : ")+CString(numevar));
				type.m_nAtribLValue = LV_ADDRESS;
				type.m_nAtribTip = simb->m_nType ;

				if (m_nVNivel != simb->m_nNivel)
					GenerateCode(INSTR_CHGSFP,(BYTE)simb->m_nNivel);

				Symbol *auxsimb = NULL ;
				int np;
				if (RetreaveSymbol(simb->m_sRelated,auxsimb))
					np = auxsimb->m_ListaPar.GetCount();
				switch (simb->m_nClass)
				{
				case CT_VAR_SIMP:
					GenerateCode(INSTR_LODA,(OFFSET) (simb->m_nAdrel+simb->m_nNivel+1));
					break;
				case CT_PARAM_VAL:
					GenerateCode(INSTR_LODA,(OFFSET) (simb->m_nAdrel-np -2));
					break;
				case CT_PARAM_ADR:
					GenerateCode(INSTR_LOD,(OFFSET) (simb->m_nAdrel-np-2));
					break;
				case CT_FUNCTION:
					// the return value of the function
					if (m_pCurentBlock != simb)
						throw error(SET_GENERAL,CString("Invalid instruction !!!"));
					GenerateCode(INSTR_LODA,(OFFSET) (-(simb->m_ListaPar.GetCount() + 2)));
					break;

				}
				if (m_nVNivel != simb->m_nNivel)
					GenerateCode(INSTR_RSTSFP);

			PushBack();
		}
}









///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:36:12 PM
// Function name	: CPascalCompiler::Expr
// Description	    : 
// Return type		: void 
// Argument         : ExprInfo& type
///////////////////////////////////////////////////////////////

void CPascalCompiler::Expr(ExprInfo& type)
{
	ExprInfo et;
	int c='+';
	while (1)
	{
		Termen(type);
		switch (et.m_nAtribTip)	// tipul termenului precedent
		{
		case ET_REAL:
			if (type.m_nAtribTip !=ET_REAL && type.m_nAtribTip !=ET_INTEGER)
				throw error(SET_GENERAL,CString("Ivalid operation between incompatible Types"));
			// Generate code 
			if (c == '+')
				GenerateCode(INSTR_ADD);
			else 
				GenerateCode(INSTR_SUB);
			break;
		case ET_INTEGER:
			if (type.m_nAtribTip !=ET_REAL && type.m_nAtribTip !=ET_INTEGER)
				throw error(SET_GENERAL,CString("Ivalid operation between incompatible Types"));
			if (type.m_nAtribTip == ET_REAL)
				et.m_nAtribTip = ET_REAL;
			// Generate code
			if (c == '+')
				GenerateCode(INSTR_ADD);
			else 
				GenerateCode(INSTR_SUB);

			break;
		case ET_CHAR:
			if (type.m_nAtribTip != ET_CHAR)
				throw error(SET_GENERAL,CString("Ivalid operation between incompatible Types"));
			// Generate code
			if (c == '+')
				GenerateCode(INSTR_ADD);
			else 
				GenerateCode(INSTR_SUB);

			break;
		default:
			et.m_nAtribTip  = type.m_nAtribTip ;
			et.m_nAtribLValue = type.m_nAtribLValue ;
		}
		int val = NextToken();
		if (val!='+' && val != '-')
		{
			PushBack();
			break;
		}
		c = val;
		et.m_nAtribLValue = LV_VALUE;
	}
	
	type = et;
}




///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:36:22 PM
// Function name	: CPascalCompiler::Termen
// Description	    : 
// Return type		: void 
// Argument         : ExprInfo& type
///////////////////////////////////////////////////////////////

void CPascalCompiler::Termen(ExprInfo& type)
{
	ExprInfo et;
	int c ='*';

	while (1)
	{
		Factor(type);
		switch (et.m_nAtribTip)	// tipul termenului precedent
		{
		case ET_REAL:
			if (type.m_nAtribTip !=ET_REAL && type.m_nAtribTip !=ET_INTEGER)
				throw error(SET_GENERAL,CString("Ivalid operation between incompatible Types"));
			if (c == TT_KW_MOD )
				throw error(SET_GENERAL,CString("Ivalid operation With real numbers"));
			
			// Generate code
			if (c == TT_KW_MOD)
				GenerateCode(INSTR_MOD);
			if (c == TT_KW_DIV)
				GenerateCode(INSTR_DIV);
			if (c == '/')
				GenerateCode(INSTR_DIV);
			if (c == '*')
				GenerateCode(INSTR_MUL);
			
			
			break;
		case ET_INTEGER:
			if (type.m_nAtribTip !=ET_REAL && type.m_nAtribTip !=ET_INTEGER)
				throw error(SET_GENERAL,CString("Ivalid operation between incompatible Types"));
			if (type.m_nAtribTip == ET_REAL)
			{
				if (c == TT_KW_MOD)
					throw error(SET_GENERAL,CString("Ivalid operation With real numbers"));
				et.m_nAtribTip = ET_REAL;
			}
			// Generate code
			if (c == TT_KW_MOD)
				GenerateCode(INSTR_MOD);
			if (c == TT_KW_DIV)
				GenerateCode(INSTR_DIV);
			if (c == '/')
				GenerateCode(INSTR_DIV);
			if (c == '*')
				GenerateCode(INSTR_MUL);

			break;
		case ET_CHAR:
			throw error(SET_GENERAL,CString("Ivalid operation with Strings"));
			break;
		default:
			et.m_nAtribTip  = type.m_nAtribTip ;
			et.m_nAtribLValue = type.m_nAtribLValue ;
		}

		int val = NextToken();
		if (val!='*' && val != '/' && val!=TT_KW_MOD && val != TT_KW_DIV)
		{
			PushBack();
			break;
		}
		et.m_nAtribLValue = LV_VALUE;
		c = val;
	}

⌨️ 快捷键说明

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