?? pascalcompiler.cpp
字號(hào):
// 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;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -