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

📄 compilecode.cpp

📁 我的简易编译器终于在花了近20个工作日后完成了。按照设计是做成一个FormulaEx.dll
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		FillJmpChain(nJmpChainElse);
		BackOff();
	}
}

void CCompileCode::CmpWhileSen()
{
	if(Advance() != BS_LBRACKET){
		WordMissing("(");
		BackOff();
		return ;
	}
	int nJmpChain = ISN_JMP_TAG;

	int nLabel = m_pFormulaModula->GetFormulaItemSum();

	int boolIsn = CmpFormula();
	if(Advance() != BS_RBRACKET){
		WordMissing(")");
		BackOff();
		return ;
	}
	GenFormula(OP_JZ,nJmpChain,boolIsn);
	nJmpChain = m_pFormulaModula->GetFormulaItemSum()-1;

	SJMPChain sWhileChain;
	sWhileChain.SEN_TYPE = RES_WHILE;
	sWhileChain.nBegChain = ISN_JMP_TAG;
	sWhileChain.nEndChain = nJmpChain;

	m_JMPChain.Push(sWhileChain);

	CmpSentence();

	GenFormula(OP_JMP,nLabel);
	sWhileChain = m_JMPChain.Pop();

	FillJmpChain(sWhileChain.nEndChain );
	FillJmpChain(sWhileChain.nBegChain,nLabel );
}

// Extended

void CCompileCode::CmpForSen()
{
	if(Advance() != BS_LBRACKET){
		WordMissing("(");
		BackOff();
		return ;
	}
	// Compile initialize sentence
	int nIsn = Advance();
	switch(nIsn){
	case RES_INT:
	case RES_FLOAT: 
	case RES_STRING:
	case RES_DEFINE:// { SIGN define
		CmpSignDef();
		break;
//	case BS_SEMICOLON:// ;
//		BackOff();
//		break;
	default:
		BackOff();
		while(1){
			CmpSingleSentence();
			nIsn = Advance();
			if(nIsn == BS_SEMICOLON){ //;
				BackOff();
				break;
			}
			if(nIsn != BS_COMMA){ //,
				WordMissing(";");
				break;
			}
		}
		break;
	}

	nIsn = Advance();
	if(nIsn != KEY_UNKNOWN && nIsn != BS_SEMICOLON)
		WordMissing(";");

	// compile condition sentence
	int nJmpEndChain = ISN_JMP_TAG;

	int nCondTag = m_pFormulaModula->GetFormulaItemSum();
	int nCondIsn = CmpFormula();

	nIsn = Advance();
	if(nIsn != KEY_UNKNOWN && nIsn != BS_SEMICOLON)
		WordMissing(";");
	if(nCondIsn != SEN_EMPTY){
		GenFormula(OP_JZ,nJmpEndChain,nCondIsn);
		nJmpEndChain = m_pFormulaModula->GetFormulaItemSum()-1;
	}
	GenFormula(OP_JMP,ISN_JMP_TAG);

	// compile step sentence
	int nStepTag = m_pFormulaModula->GetFormulaItemSum();
	int nJmpBeginChain = nStepTag - 1;
	while(1){
		CmpSingleSentence();
		nIsn = Advance();
		if(nIsn == BS_RBRACKET){ // )
			break;
		}
		if(nIsn != BS_COMMA){ //,
			WordMissing(")");
			break;
		}
	}
	GenFormula(OP_JMP,nCondTag);
	FillJmpChain(nJmpBeginChain );


//	FORMULATABLE stepFormulaTable;
	SJMPChain sForChain;
	sForChain.SEN_TYPE = RES_FOR;
	sForChain.nBegChain = ISN_JMP_TAG;
	sForChain.nEndChain = nJmpEndChain;

	m_JMPChain.Push(sForChain);

	CmpSentence();

	GenFormula(OP_JMP,nStepTag);

	sForChain = m_JMPChain.Pop();
	FillJmpChain(sForChain.nEndChain );
	FillJmpChain(sForChain.nBegChain,nStepTag );
}

void CCompileCode::CmpSwitchSen()
{
	if(Advance() != BS_LBRACKET){
		WordMissing("(");
		BackOff();
		return ;
	}
	int nCondIsn = Advance();
	if(	nCondIsn != RES_INT		&&
		nCondIsn != RES_FLOAT	&&
		nCondIsn != RES_STRING	&&
		nCondIsn != RES_DEFINE )
		BackOff();
	nCondIsn = CmpFormula();
	if(m_pFormulaModula->IsTemp(nCondIsn))
		m_pFormulaModula->LockTemp(nCondIsn);

	if(Advance() != BS_RBRACKET){
		WordMissing(")");
		BackOff();
		return ;
	}
	if(Advance() != BS_LFBRACKET){
		WordMissing("{");
		BackOff();
		return ;
	}

	SJMPChain sSwitchChain;
	sSwitchChain.SEN_TYPE = RES_SWITCH;
	sSwitchChain.nBegChain = ISN_JMP_TAG;
	sSwitchChain.nEndChain = ISN_JMP_TAG;
	m_JMPChain.Push(sSwitchChain);
	int nTagISN,nTmpIsn;

	int nPreChain   = ISN_JMP_TAG;
	int nSkipCase   = ISN_JMP_TAG;
	int nDefauleTag = ISN_JMP_TAG;
	int nValueIsn;
	while(1){
		nTagISN = Advance();
		if(nTagISN == RES_DEFAULT){
			if(nDefauleTag != ISN_JMP_TAG)
				RaiseError("too many default in the switch sentence!");
			nDefauleTag = m_pFormulaModula->GetFormulaItemSum();
		}else if(nTagISN == RES_CASE){

			FillJmpChain(nPreChain);
			nValueIsn = CmpFormula();
			if( nValueIsn == UNKNOWN)
				RaiseError("condition is missing!");
			GenFormula(OP_JNE,ISN_JMP_TAG,nCondIsn,nValueIsn);
			nPreChain = m_pFormulaModula->GetFormulaItemSum()-1;
		}else{
			BackOff();
			break;
		}
		nTmpIsn = Advance();
		if(nTmpIsn != BS_COLON){
			WordMissing(":");
			BackOff();
			return;
		}
		FillJmpChain(nSkipCase );

		while(1){
			nTmpIsn = Advance();
			BackOff();
			if( nTmpIsn == UNKNOWN		||
				nTmpIsn == BS_RFBRACKET ||
				nTmpIsn == RES_DEFAULT ||
				nTmpIsn == RES_CASE )
				break;
			CmpSentence();
		}
		GenFormula(OP_JMP,ISN_JMP_TAG);
		nSkipCase = m_pFormulaModula->GetFormulaItemSum()-1;
	} 

	FillJmpChain(nPreChain );
	if(nDefauleTag != ISN_JMP_TAG)
		GenFormula(OP_JMP,nDefauleTag);
	FillJmpChain(nSkipCase );
	
	sSwitchChain = m_JMPChain.Pop();
	FillJmpChain(sSwitchChain.nEndChain );

	if(m_pFormulaModula->IsTemp(nCondIsn)){
		m_pFormulaModula->UnlockTemp(nCondIsn);
		m_pFormulaModula->UsedTemp();
	}

	if(Advance() != BS_RFBRACKET){
		WordMissing("}");
		BackOff();
	}
}

void CCompileCode::CmpReturn()
{
	m_SourceCode.m_bAcceptOpt = FALSE;
	int nItem = CmpFormula();
	GenFormula(OP_RET,ISN_EMPTY,nItem);
	int nIsn = Advance();
/*	if(nIsn == BS_RFBRACKET){
		BackOff();
		return;
	}
*/
	if(nIsn != KEY_UNKNOWN && nIsn != BS_SEMICOLON)
		WordMissing(";");
}

BOOL CCompileCode::CmpMultiSentence()
{
	int nIsn = Advance();
	while(  nIsn != UNKNOWN && 
			nIsn != BS_RFBRACKET)
	{
		BackOff();
		CmpSentence();
		nIsn = Advance();
//		if( nIsn != BS_SEMICOLON)
//			WordMissing(";");
//		nIsn = Advance();
	}
	return nIsn == BS_RFBRACKET;
}

BOOL CCompileCode::CmpSingleSentence()
{
	int nSignISN = Advance();
	int nTmpIsn;
	if(nSignISN == OP_INC){
		nSignISN = Advance();
		if(m_CurWT != WT_SIGN){
			RaiseError("signal is missing!");
			BackOff();
			return FALSE;
		}
		nTmpIsn = m_pFormulaModula->AddConst("1"); 
		GenFormula(OP_ADD,nSignISN,nSignISN,nTmpIsn);
		return TRUE;
	}

	if(nSignISN == OP_DEC){
		nSignISN = Advance();
		if(m_CurWT != WT_SIGN){
			RaiseError("signal is missing!");
			BackOff();
			return FALSE;
		}
		nTmpIsn = m_pFormulaModula->AddConst("1"); 
		GenFormula(OP_SUB,nSignISN,nSignISN,nTmpIsn);
		return TRUE;
	}

	if(m_CurWT == WT_SEPARATOR){
		BackOff();
		return TRUE;
	}
	if(m_CurWT == WT_SYSFUNC){
		CmpCallSysFunc();
		m_pFormulaModula->UsedTemp();
		return TRUE;
	}

	if(m_CurWT != WT_SIGN){
		RaiseError("signal is missing!");
		return FALSE;
	}

	int nEvalOpt = Advance();
	if(nEvalOpt == OP_INC){
		nTmpIsn = m_pFormulaModula->AddConst("1"); 
		GenFormula(OP_ADD,nSignISN,nSignISN,nTmpIsn);
		return TRUE;
	}

	if(nEvalOpt == OP_DEC){
		nTmpIsn = m_pFormulaModula->AddConst("1"); 
		GenFormula(OP_SUB,nSignISN,nSignISN,nTmpIsn);
		return TRUE;
	}

	if(m_CurWT != WT_EVALUATE){
		WordMissing("=");
		return FALSE;
	}

	nTmpIsn = CmpFormula();
	switch(nEvalOpt){
	case OP_EVALUATE:
		GenFormula(OP_EVALUATE,nSignISN,nTmpIsn);
		break;
	case OP_E_ADD:
		GenFormula(OP_ADD,nSignISN,nSignISN,nTmpIsn);
		break;
	case OP_E_SUB:
		GenFormula(OP_SUB,nSignISN,nSignISN,nTmpIsn);
		break;
	case OP_E_MUL:
		GenFormula(OP_MUL,nSignISN,nSignISN,nTmpIsn);
		break;
	case OP_E_DIV:
		GenFormula(OP_DIV,nSignISN,nSignISN,nTmpIsn);
		break;
	default:
		return FALSE;
	}
	return TRUE;
}

BOOL CCompileCode::CmpSentence()
{
	ASSERT(m_pFormulaModula);
	int nIsn = Advance();
	switch(nIsn){
	case BS_SEMICOLON:// empty sentence
		return TRUE;
		
	case RES_IF: // if
		CmpIfElseSen();
		return TRUE;
		
	case RES_WHILE:	// while
		CmpWhileSen();
		return TRUE;

	case RES_FOR:	// for
		CmpForSen();
		return TRUE;

	case RES_SWITCH:	// switch
		CmpSwitchSen();
		return TRUE;

	case RES_RETURN:	// return sentence
		CmpReturn();
		return TRUE;

	case RES_INT:
	case RES_FLOAT: 
	case RES_STRING:
	case RES_DEFINE:// { SIGN define
		CmpSignDef();
		nIsn = Advance();
		if(nIsn != KEY_UNKNOWN && nIsn != BS_SEMICOLON)
			WordMissing(";");
		return TRUE;

	case RES_METHOD:
	case RES_FUNC:	// { function define
		CmpFuncDef();
		return TRUE;
	case OP_INC:
	case OP_DEC: 
		BackOff();
		CmpSingleSentence();
		nIsn = Advance();
		if(nIsn != KEY_UNKNOWN && nIsn != BS_SEMICOLON)
			WordMissing(";");
		return TRUE;
	case RES_BREAK:// break;
		{
			int nJC = ISN_JMP_TAG;
			PJMPCHAIN pChain = m_JMPChain.GetTop();

			if( pChain == NULL)
				RaiseError("break not in loop or switch!");
			else
				nJC = pChain->nEndChain;

			GenFormula(OP_JMP,nJC);
			nJC = m_pFormulaModula->GetFormulaItemSum()-1;

			if(pChain != NULL)
				pChain->nEndChain = nJC;

			nIsn = Advance();
			if(nIsn != KEY_UNKNOWN && nIsn != BS_SEMICOLON)
				WordMissing(";");
		}
		return TRUE;
	case RES_CONTINUE: // continue;
		{
			int nJC = ISN_JMP_TAG;
			PJMPCHAIN pChain = m_JMPChain.GetTopLoopChain();

			if( pChain == NULL)
				RaiseError("continue not in loop!");
			else
				nJC = pChain->nBegChain;

			GenFormula(OP_JMP, nJC ); //   以区别 break
			nJC = m_pFormulaModula->GetFormulaItemSum()-1;

			if(pChain != NULL)
				pChain->nBegChain = nJC;

			nIsn = Advance();
			if(nIsn != KEY_UNKNOWN && nIsn != BS_SEMICOLON)
				WordMissing(";");
		}
		return TRUE;
	case BS_LFBRACKET:	// { multi sentence
		CmpMultiSentence();
		return TRUE;
	}

	switch(m_CurWT){
	case WT_SIGN:	// evaluate
		//GEN Evaluate Formula
		BackOff();
		CmpSingleSentence();
		nIsn = Advance();
		if(nIsn != KEY_UNKNOWN && nIsn != BS_SEMICOLON)
			WordMissing(";");
		return TRUE;
	case WT_MODULE:	// call module
		CmpCallModule(ISN_EMPTY);
		return TRUE;
	case WT_SYSFUNC:
		BackOff();
		CmpSingleSentence();
		return TRUE;
	default:
		break;
	}
	RaiseError(m_sCurWord + " not correctly begin a sentence !");
	return FALSE;
}

void CCompileCode::SetFormulaModule(PFORMUALMODULE pFM)
{
	m_pFormulaModula = pFM; 
//	m_SourceCode.SetSource(pFM->GetSource(),pFM->GetSourceLen()); 
}

int  CCompileCode::Compile()
{
	Reset();
	CmpMultiSentence();
	m_sCurWord = m_SourceCode.GetAWord();
	if( m_sCurWord != "")
		RaiseError("more content can't be compiled!");
	//repeat CmpSentence
	GenFormula(OP_END,ISN_EMPTY);
	return 0;
}

int	 CCompileCode::GetErrorSum()
{
	return m_slErrorMsgs.GetCount();
}

void CCompileCode::ClearError()
{
	m_slErrorMsgs.RemoveAll();
}

CString CCompileCode::GetErrorDesc(int nInd)
{
	POSITION p = m_slErrorMsgs.FindIndex(nInd);
	if(p==NULL)
		return CString("");
	return m_slErrorMsgs.GetAt(p);
}

⌨️ 快捷键说明

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