?? pascalcompiler.cpp
字號:
// PascalSintAnalyzer.cpp: implementation of the CPascalCompiler class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "zscpascal.h"
#include "PascalCompiler.h"
#include "VirtualMachine.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPascalCompiler::CPascalCompiler(CString str):
CPascalLexAnalyzer(str)
{
m_nVNivel = 0;
// Code Table Init Stuff
m_nLabelCount = 1;
m_Code = NULL;
}
CPascalCompiler::~CPascalCompiler()
{
POSITION pos = m_RecordList.GetHeadPosition();
while (pos != NULL)
{
Record * record = m_RecordList.GetNext(pos);
delete record;
}
delete m_Code;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 6/8/99 1:22:26 PM
// Function name : CPascalCompiler::ProgramSursa
// Description : The main sintactic thing
// Return type : void
///////////////////////////////////////////////////////////////
void CPascalCompiler::ProgramSursa()
{
// Initialize the level
// The leveling system will be American style the base level will be 1
m_nVNivel = 0;
IncreaseLevel();
if (NextToken() != TT_KW_PROGRAM)
throw error(SET_EXPECTED,CString("\"program\""));
if (NextToken() != TT_WORD)
throw error(SET_EXPECTED, CString("identifier"));
// insert a symbol for the programm
Symbol *simb = new Symbol;
simb->m_sName = GetStrValue();
simb->m_nNivel = m_nVNivel;
InsertSymbol(simb);
if (NextToken() != ';')
throw error(SET_EXPECTED, CString(";"));
Bloc(simb);
m_EntryPoint = simb->m_nAdrStart ;
if (NextToken() != '.')
throw error(SET_EXPECTED, CString("."));
DecreaseLevel();
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 5/25/99 6:18:55 PM
// Function name : CPascalCompiler::Bloc
// Description : This function processes a program block
// Return type : void
///////////////////////////////////////////////////////////////
void CPascalCompiler::Bloc(Symbol *simbb)
{
int val, varSize = 0;
while (1)
{
if ((val = NextToken()) == TT_KW_CONST)
ListaDeclConst();
else
if (val == TT_KW_VAR)
ListaDeclVar(varSize);
else
if (val == TT_KW_PROCEDURE)
{
IncreaseLevel();
ParamList lp;
CString nume;
AntetProc(lp,nume);
Symbol *simb = new Symbol;
simb->m_sName = nume;
simb->m_nClass = CT_PROCEDURE;
simb->m_nNivel = m_nVNivel;
simb->m_nAdrStart = -1;
simb->m_ListaPar .AddTail(&lp);
simb->m_nNrPar = lp.GetCount ();
InsertSymbol(simb);
m_pCurentBlock = simb;
Bloc(simb);
m_pCurentBlock = simbb;
Symbol *simbaux = new Symbol;
*simbaux = *simb;
if (NextToken() != ';')
throw error(SET_EXPECTED, CString(";"));
DecreaseLevel();
InsertSymbol(simbaux);
}
else
if (val == TT_KW_FUNCTION)
{
IncreaseLevel();
int type;
ParamList lp;
CString nume;
AntetFunc(lp,type,nume);
Symbol *simb = new Symbol;
simb->m_sName = nume;
simb->m_nClass = CT_FUNCTION;
simb->m_nNivel = m_nVNivel;
simb->m_nAdrStart = -1;
simb->m_nType = type;
simb->m_ListaPar .AddTail(&lp);
simb->m_nNrPar = lp.GetCount ();
InsertSymbol(simb);
m_pCurentBlock = simb;
Bloc(simb);
m_pCurentBlock = simbb;
Symbol *simbaux = new Symbol;
*simbaux = *simb;
if (NextToken() != ';')
throw error(SET_EXPECTED, CString(";"));
DecreaseLevel();
InsertSymbol(simbaux);
}
else
{
PushBack();
// Block code beginning generation
AddComment(simbb->m_sName + " code beginning");
simbb->m_nAdrStart = m_Code->GetCurCodePos();
// now some address relocation
POSITION pos = m_AdrList.GetHeadPosition();
while (pos != NULL)
{
POSITION prev = pos;
AddressPlace place = m_AdrList.GetNext(pos);
if (simbb->m_sName == place.m_sSimb)
{
m_Code->SetAddress(place.m_nPosition,simbb->m_nAdrStart);
m_AdrList.RemoveAt(prev);
}
}
GenerateCode(INSTR_ENTER,(BYTE)m_nVNivel,(REGISTER) varSize);
InstrCompusa();
GenerateCode(INSTR_LEAVE);
GenerateCode(INSTR_RET);
break;
}
}
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 8/3/99 3:42:39 PM
// Function name : CPascalCompiler::ListaDeclConst
// Description : The constant declaration list
// Return type : void
///////////////////////////////////////////////////////////////
void CPascalCompiler::ListaDeclConst()
{
while (1)
{
DeclConst();
if (NextToken() != ';')
throw error(SET_EXPECTED, CString(";"));
if (NextToken() != TT_WORD)
{
PushBack();
break;
}
PushBack();
}
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 8/3/99 3:43:19 PM
// Function name : CPascalCompiler::DeclConst
// Description : a constant declaration
// Return type : void
///////////////////////////////////////////////////////////////
void CPascalCompiler::DeclConst()
{
Symbol *simb = new Symbol; // The symbol
if (NextToken() != TT_WORD)
throw error(SET_EXPECTED, CString("identifier"));
simb->m_sName = GetStrValue();
if (NextToken() != '=')
throw error(SET_EXPECTED, CString("="));
ExprInfo ct;
ExprStatica(ct);
simb->m_nClass = CT_CONST;
simb->m_nNivel = m_nVNivel;
simb->m_nType = ct.m_nAtribTip ;
switch (simb->m_nType)
{
case ET_INTEGER:
CV_INTEGER(simb->m_Val) = ct.m_nAttribValue ;
break;
case ET_REAL:
CV_REAL(simb->m_Val) = ct.m_dAttribValue ;
break;
case ET_CHAR:
CV_CHAR(simb->m_Val) = ct.m_cAttribValue ;
break;
}
InsertSymbol (simb);
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 8/3/99 3:43:52 PM
// Function name : CPascalCompiler::ListaDeclVar
// Description : The variable Declaration list
// Return type : void
// Argument : int &varSize - the size of the variables
///////////////////////////////////////////////////////////////
void CPascalCompiler::ListaDeclVar(int &varSize)
{
while (1)
{
DeclVar(varSize);
if (NextToken() != ';')
throw error(SET_EXPECTED, CString(";"));
if (NextToken() != TT_WORD)
{
PushBack();
break;
}
PushBack();
}
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 8/3/99 4:12:32 PM
// Function name : CPascalCompiler::AntetProc
// Description : Procedure declaration
// Return type : void
// Argument : ParamList &listaParam - parameter list
// Argument : CString &nume - the function name
///////////////////////////////////////////////////////////////
void CPascalCompiler::AntetProc(ParamList &listaParam, CString &nume)
{
if (NextToken()!= TT_WORD)
throw error(SET_EXPECTED, CString("identifier"));
nume = GetStrValue();
if (NextToken()== ';')
return;
PushBack();
Parametri(listaParam, nume);
if (NextToken()!= ';')
throw error(SET_EXPECTED, CString(";"));
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 8/3/99 4:16:10 PM
// Function name : CPascalCompiler::AntetFunc
// Description : Function declaration
// Return type : void
// Argument : ParamList &listaParam - parameters list
// Argument : int &type - the returning value type
// Argument : CString &nume - the name of the function
///////////////////////////////////////////////////////////////
void CPascalCompiler::AntetFunc(ParamList &listaParam, int &type, CString &nume)
{
if (NextToken()!= TT_WORD)
throw error(SET_EXPECTED, CString("identifier"));;
nume = GetStrValue();
if (NextToken()!= ':')
{
PushBack();
Parametri(listaParam, nume);
if (NextToken()!= ':')
throw error(SET_EXPECTED, CString(":"));
}
TypeInfo info;
TipSimplu(info);
if (NextToken()!= ';')
throw error(SET_EXPECTED, CString(";"));
type = info.m_nType ;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 8/3/99 4:24:05 PM
// Function name : CPascalCompiler::Tip
// Description : Type parsing
// Return type : void
// Argument : TypeInfo &info - this structure is filled by the function
///////////////////////////////////////////////////////////////
void CPascalCompiler::Tip(TypeInfo &info)
{
int val = NextToken();
if (val == TT_KW_INTEGER
|| val == TT_KW_REAL
|| val == TT_KW_CHAR)
{
PushBack();
info.m_nClass = CT_VAR_SIMP;
TipSimplu(info);
}
if (val == TT_KW_ARRAY)
{
PushBack();
info.m_nClass = CT_VAR_ARRAY;
TipTablou(info);
}
if (val == TT_KW_RECORD)
{
PushBack();
info.m_nClass = CT_VAR_RECORD;
TipRecord(info);
}
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 8/3/99 4:31:41 PM
// Function name : CPascalCompiler::TipSimplu
// Description : Simple type parsing
// Return type : void
// Argument : TypeInfo& info - the info is returned by function
///////////////////////////////////////////////////////////////
void CPascalCompiler::TipSimplu(TypeInfo& info)
{
int val = NextToken();
if (val == TT_KW_INTEGER)
{
info.m_nType = ET_INTEGER;
info.m_nSize = SC_INT;
}
else
if (val == TT_KW_REAL)
{
info.m_nType = ET_REAL;
info.m_nSize = SC_REAL;
}
else
if (val == TT_KW_CHAR)
{
info.m_nType = ET_CHAR;
info.m_nSize = SC_CHAR;
}
else
throw error(SET_EXPECTED, CString("Basic Type"));;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 8/3/99 4:33:15 PM
// Function name : CPascalCompiler::Parametri
// Description : Parameter parsing
// Return type : void
// Argument : ParamList &listaParam - the returned parameter list
// Argument : CString &function - da name
///////////////////////////////////////////////////////////////
void CPascalCompiler::Parametri(ParamList &listaParam,CString &function)
{
if (NextToken()!= '(')
throw error(SET_EXPECTED, CString("("));;
while (1)
{
DeclParam(listaParam, function);
if (NextToken()!= ';')
{
PushBack();
break;
}
}
if (NextToken()!= ')')
throw error(SET_EXPECTED, CString(")"));;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 8/3/99 4:34:02 PM
// Function name : CPascalCompiler::DeclParam
// Description :
// Return type : void
// Argument : ParamList &listaParam
// Argument : CString &function
///////////////////////////////////////////////////////////////
void CPascalCompiler::DeclParam(ParamList &listaParam, CString &function)
{
int transmisie = LV_VALUE;
StringList list;
if (NextToken() == TT_KW_VAR)
{
transmisie = LV_ADDRESS;
NextToken();
}
PushBack();
while (1)
{
if (NextToken() != TT_WORD)
throw error(SET_EXPECTED, CString("identifier"));;
list.AddTail(GetStrValue());
if (NextToken()!=',')
{
PushBack();
break;
}
}
if (NextToken() != ':')
throw error(SET_EXPECTED, CString(":"));
TypeInfo info;
TipSimplu(info);
POSITION pos = list.GetHeadPosition();
while (pos != NULL)
{
CString numepar = list.GetNext(pos);
Symbol *simb = new Symbol;
simb->m_sName = numepar;
if (transmisie == LV_VALUE)
simb->m_nClass = CT_PARAM_VAL;
else
simb->m_nClass = CT_PARAM_ADR;
simb->m_nType = info.m_nType ;
simb->m_nNivel = m_nVNivel;
Param par;
par.m_nTransmisie =transmisie;
par.m_nType = info.m_nType ;
listaParam.AddTail (par);
simb->m_nAdrel = ((int)listaParam.GetCount());
simb->m_sRelated = function;
InsertSymbol(simb);
}
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 8/3/99 4:34:11 PM
// Function name : CPascalCompiler::InstrCompusa
// Description :
// Return type : void
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -