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