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

📄 pascalcompiler.cpp

📁 袖珍型的pascal编译器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	type = et;
}



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

void CPascalCompiler::Factor(ExprInfo &type)
{
	StackEntry entry;
	int val = NextToken();
	if (val == '-')
	{
		entry.m_nType = SE_INTEGER;		
		CV_INTEGER(entry.m_Info) = (INTEGER)0;
		GenerateCode(INSTR_LODI,entry);	
		Factor(type);
		GenerateCode(INSTR_SUB);	
		return;
	}
	if (val == TT_INTEGER)
	{
		type.m_nAtribLValue = LV_VALUE;
		type.m_nAtribTip = ET_INTEGER;
		
		// Generate code
		entry.m_nType = SE_INTEGER;		
		CV_INTEGER(entry.m_Info) = (INTEGER)GetNumValue ();
		GenerateCode(INSTR_LODI,entry);
		return;
	}
	if (val == TT_REAL)
	{
		type.m_nAtribLValue = LV_VALUE;
		type.m_nAtribTip = ET_REAL;

		// Generate Code
		entry.m_nType = SE_REAL;		
		CV_REAL(entry.m_Info) = (REAL)GetNumValue ();
		GenerateCode(INSTR_LODI,entry);

		return;
	}
	if (val == TT_CHAR)
	{
		type.m_nAtribLValue = LV_VALUE;
		type.m_nAtribTip = ET_CHAR;

		// Generate Code
		entry.m_nType = SE_CHAR;		
		CV_CHAR(entry.m_Info) = (CHAR)(GetStrValue()[0]);
		GenerateCode(INSTR_LODI,entry);

		return;
	}
	if (val == '(')
	{
		Expr(type);
		if (NextToken()!=')')
			throw error(SET_EXPECTED, CString(")"));
		return;
	}
	if (val == TT_WORD)
		if (IsFunc(GetStrValue()))
		{
			PushBack();
			ApelFunc(type);	// Leaves result on stack
			return;
		}
		else 
		{
			PushBack();
			Variabila(type); // Leaves result on stack
			return;
		}
	
	throw error(SET_EXPECTED, CString("number or constant or identifier or function or variable "));;
}




///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:36:42 PM
// Function name	: CPascalCompiler::IsFunc
// Description	    : 
// Return type		: BOOL 
// Argument         : CString &str
///////////////////////////////////////////////////////////////

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



///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 5/28/99 3:35:29 PM
// Function name	: CPascalCompiler::ApelFunc
// Description	    : Function calling
// Return type		: void 
// Argument         : ExprInfo &type
///////////////////////////////////////////////////////////////

void CPascalCompiler::ApelFunc(ExprInfo &type)
{
	if (NextToken()!=TT_WORD)
		throw error(SET_EXPECTED, CString("identifier"));
	Symbol *simb = NULL;
	CString functie = GetStrValue();
	RetreaveSymbol(functie,simb);
	AddComment("Calling: " + GetStrValue());
	// alocate the return value on the stack
	StackEntry entry;
	entry.m_nType = simb->m_nType ;
	GenerateCode(INSTR_LODI,entry);

	POSITION pos = simb->m_ListaPar.GetHeadPosition ();
	if (NextToken()=='(')
	{
		while (1)
		{
			if (pos == NULL)
				throw error(SET_GENERAL, CString("Too many parameters"));
			Param par = simb->m_ListaPar .GetNext(pos);
			
			// This part put's the entire parameters on the stack
			if (par.m_nTransmisie == LV_ADDRESS)
				VariabilaAdr(type);
			else
				Expr(type);

			if (type.m_nAtribTip != par.m_nType )
				throw error(SET_GENERAL, CString("Invalid Parameter type"));
			if (par.m_nTransmisie == LV_ADDRESS && type.m_nAtribLValue== LV_VALUE )
				throw error(SET_GENERAL, CString("Invalid Parameter, must be a variable"));
			
	


			if (NextToken()!=',')
			{
				PushBack();
				if (pos != NULL)
					throw error(SET_GENERAL, CString("Too few parameters"));
				break;
			}
		}
		if (NextToken()!=')')
			throw error(SET_EXPECTED, CString(")"));
	}
	else
	{
		PushBack();
		if (simb->m_ListaPar.GetCount () != 0)
				throw error(SET_GENERAL, CString("Some parameters expected"));
	}
	type.m_nAtribLValue = LV_VALUE;
	type.m_nAtribTip = simb->m_nType ;
	// Generate code for the call
	if (simb->m_nAdrStart == -1)
	{
		AddressPlace place;
		place.m_nPosition = m_Code->GetCurCodePos() + VM_ICSIZE;
		place.m_sSimb = functie ;
		m_AdrList.AddHead(place);
	}
	GenerateCode(INSTR_CALL,(REGISTER)simb->m_nAdrStart, simb->m_sName);
	GenerateCode(INSTR_RED,(OFFSET)simb->m_ListaPar.GetCount());
	// THe result is leaved on the stack
}




///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:36:53 PM
// Function name	: CPascalCompiler::InstrWhile
// Description	    : 
// Return type		: void 
///////////////////////////////////////////////////////////////

void CPascalCompiler::InstrWhile()
{
	CString label,label2;
	if (NextToken()!=TT_KW_WHILE)
		throw error(SET_EXPECTED, CString("while"));
	int ujmpAdr = m_Code->GetCurCodePos();
	label2.Format("ET%d", m_nLabelCount ++);
	InsertLabel(label2 + ":");
	Conditie();
	label.Format("ET%d",m_nLabelCount ++);
	int jumpAdr = m_Code->GetCurCodePos() + VM_ICSIZE;
	GenerateCode(INSTR_NFJP,0,label);
	if (NextToken()!=TT_KW_DO)
		throw error(SET_EXPECTED, CString("do"));
	Instr();
	GenerateCode(INSTR_UJP,ujmpAdr,label2);
	InsertLabel(label+":");
	m_Code->SetAddress(jumpAdr,m_Code->GetCurCodePos());
}



///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 6/8/99 1:16:45 PM
// Function name	: CPascalCompiler::Conditie
// Description	    : Evaluare conditie
// Return type		: void 
///////////////////////////////////////////////////////////////

void CPascalCompiler::Conditie()
{
	int val;
	BOOL first = TRUE;
	int op = TT_KW_AND;
	while (1)
	{
		if (NextToken()!=TT_KW_NOT)
			PushBack();
		ExprLogica();
		val = NextToken();
		if (!first)
			if (op == TT_KW_OR)
				GenerateCode(INSTR_OR);
			else
				GenerateCode(INSTR_AND);

		if (val != TT_KW_AND && val != TT_KW_OR)
		{
			PushBack();
			break;
		}
		op = val;
		first = FALSE;
	}
}




///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:37:02 PM
// Function name	: CPascalCompiler::ExprLogica
// Description	    : 
// Return type		: void 
///////////////////////////////////////////////////////////////

void CPascalCompiler::ExprLogica()
{
	ExprInfo type1, type2;
	Expr(type1);
	int val = NextToken();
	switch (val)
	{
	case '=':break;
	case '<':break;
	case '>':break;
	case TT_GTE:break;
	case TT_LWE:break;
	case TT_NE:break;
	default: throw error(SET_EXPECTED, CString("logical operator"));
	}
	Expr(type2);
	if (type1.m_nAtribTip == ET_CHAR && type2.m_nAtribTip != ET_CHAR)
		throw error(SET_EXPECTED, CString("same operand types"));
	if ((type1.m_nAtribTip == ET_INTEGER || type1.m_nAtribTip != ET_REAL) &&
		(type2.m_nAtribTip == ET_CHAR))
		throw error(SET_EXPECTED, CString("same operand types"));

	// Now generating code
	
	switch (val)
	{
	case '=':
		GenerateCode(INSTR_EQU);
		break;
	case '<':
		GenerateCode(INSTR_LES);
		break;
	case '>':break;
		GenerateCode(INSTR_GRT);
		break;
	case TT_GTE:
		GenerateCode(INSTR_GEQ);
		break;
	case TT_LWE:
		GenerateCode(INSTR_LEQ);
		break;
	case TT_NE:
		GenerateCode(INSTR_NEQ);
		break;
	}

}



///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:37:11 PM
// Function name	: CPascalCompiler::InstrRepeat
// Description	    : 
// Return type		: void 
///////////////////////////////////////////////////////////////

void CPascalCompiler::InstrRepeat()
{
	if (NextToken()!=TT_KW_REPEAT)
		throw error(SET_EXPECTED, CString("repeat"));
	int jumpAdr = m_Code->GetCurCodePos();
	CString label;
	label.Format("ET%d",m_nLabelCount ++);
	InsertLabel(label + ":");
	Instr();
	if (NextToken()!=TT_KW_UNTIL)
		throw error(SET_EXPECTED, CString("until"));
	Conditie();
	GenerateCode(INSTR_NFJP,(REGISTER)jumpAdr,label);
}



///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 8/3/99 4:37:17 PM
// Function name	: CPascalCompiler::InstrIf
// Description	    : 
// Return type		: void 
///////////////////////////////////////////////////////////////

void CPascalCompiler::InstrIf()
{
	CString label;
	
	// unnecesary comparison, but ... :-) who cares
	if (NextToken()!=TT_KW_IF)
		throw error(SET_EXPECTED, CString("if"));

	Conditie();
	if (NextToken()!=TT_KW_THEN)
		throw error(SET_EXPECTED, CString("then"));

	// now we have the result of the condition on the stack
	int place1 = m_Code->GetCurCodePos()+VM_ICSIZE;
	label.Format("ET%d",m_nLabelCount++);
	GenerateCode(INSTR_NFJP,(REGISTER)0,label);
	Instr();
	int place2 = m_Code->GetCurCodePos()+VM_ICSIZE;
	CString label2 = label;
	label.Format("ET%d",m_nLabelCount++);
	GenerateCode(INSTR_UJP,(REGISTER)0,label);
	InsertLabel(label2+":");
	m_Code->SetAddress(place1,(REGISTER) m_Code->GetCurCodePos())	;
	if (NextToken()==TT_KW_ELSE)
	{
		Instr();
	}
	else PushBack();
	m_Code->SetAddress(place2,(REGISTER) m_Code->GetCurCodePos())	;
	InsertLabel(label + ":");
}




///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 6/1/99 2:56:22 PM
// Function name	: CPascalCompiler::InstrFor
// Description	    : This function is is version one
// Return type		: void 
///////////////////////////////////////////////////////////////

void CPascalCompiler::InstrFor()
{
	BOOL ascending;
	BOOL stepspecified = FALSE;
	if (NextToken()!=TT_KW_FOR)
		throw error(SET_EXPECTED, CString("for"));
	ExprInfo type;
	// Start Counter address generation record
	POSITION countAdr = StartNewRecord();
	VariabilaAdr(type);
	StopRecord (countAdr);
	// The address of the variable is on the stack
	

	if (type.m_nAtribLValue!=LV_ADDRESS)
		throw error(SET_GENERAL, CString("Variable expected"));
	if (type.m_nAtribTip != ET_INTEGER)
		throw error(SET_GENERAL, CString("Variable of integer type expected"));
	if (NextToken()!=TT_IS)
		throw error(SET_EXPECTED, CString(":="));
	// now putting the initial value on the stack
	Expr(type);

	// Store the initial value in the counter
	GenerateCode(INSTR_STO);

	
	if (type.m_nAtribTip != ET_INTEGER)
		throw error(SET_GENERAL, CString("The For value must be of integer type"));
	int val = NextToken();
	if (val==TT_KW_TO)
	{
		// varianta To
		ascending = TRUE;
	}
	else
		if (val==TT_KW_DOWNTO)
		{
			// varianta DownTo
			ascending = FALSE;
		}
		else throw error(SET_EXPECTED, CString("to or downto"));

	// Now redirect the code generation to a temporary code storage
	Code * oldCode = NULL;
	Code * tmpCode = new Code;
	
	oldCode = Redirect(tmpCode);
	
	// Record the target value
	
	POSITION targetValue = StartNewRecord();
	Expr(type);
	StopRecord(targetValue);

	if (type.m_nAtribTip != ET_INTEGER)
	{
		delete oldCode;
		throw error(SET_GENERAL, CString("The For value must be of integer type"));
	}
	POSITION stepValue = NULL;
	
	if (NextToken() == TT_KW_STEP)
	{
		stepValue = StartNewRecord();
		Expr(type);
		StopRecord(stepValue);
		if (type.m_nAtribTip != ET_INTEGER)
		{
			delete oldCode;
			throw error(SET_GENERAL, CString("The For value must be of integer type"));
		}
		// now we have the increment on stack
		stepspecified = TRUE;
	}
	else PushBack();
	if (NextToken()!=TT_KW_DO)
	{
		delete oldCode;
		throw error(SET_EXPECTED, CString("do"));
	}
	
	// writing code
	Redirect(oldCode);

	int et1 = m_Code->GetCurCodePos();
	InsertLabel(CString("ET1:"));

	PasteRecord(countAdr);
	GenerateCode(INSTR_USTO);
	PasteRecord(targetValue);
	if (ascending)
		GenerateCode(INSTR_GRT);
	else
		GenerateCode(INSTR_LES);
	int place = m_Code->GetCurCodePos()+VM_ICSIZE;
	GenerateCode(INSTR_FJP,(REGISTER)0,CString("ET2"));

	Instr();

	PasteRecord(countAdr);
	GenerateCode(INSTR_COPY);
	GenerateCode(INSTR_USTO);
	if (stepspecified)
		PasteRecord(stepValue);
	else
	{
		StackEntry entry;
		entry.m_nType = SE_INTEGER;
		CV_INTEGER(entry.m_Info) = 1;
		GenerateCode(INSTR_LODI,entry);
	}
	if (ascending)
		GenerateCode(INSTR_ADD);
	else
		GenerateCode(INSTR_SUB);
	GenerateCode(INSTR_STO);
	GenerateCode(INSTR_UJP,(REGISTER) et1,CString("ET1"));
	m_Code->SetAddress(place,(REGISTER) m_Code->GetCurCodePos())	;
	InsertLabel (CString("ET2:"));

	RemoveRecord(countAdr);

⌨️ 快捷键说明

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