Fixed some label issues

Added PROC queueing (to prevent symbol
This commit is contained in:
David Anderson 2004-08-12 16:31:50 +00:00
parent 796a7ad4d7
commit 2a00a62bcb
13 changed files with 175 additions and 50 deletions

View File

@ -43,7 +43,7 @@
typedef int int32_t; typedef int int32_t;
typedef unsigned int uint32_t; typedef unsigned int uint32_t;
#else #else
//typedef long int int32_t; typedef long int int32_t;
typedef unsigned long int uint32_t; typedef unsigned long int uint32_t;
#endif #endif
#if defined __WIN32__ || defined _WIN32 || defined WIN32 #if defined __WIN32__ || defined _WIN32 || defined WIN32

View File

@ -106,7 +106,7 @@ void Compiler::Init()
/* Load DAT management */ /* Load DAT management */
DAT = new DataMngr(cellsize); DAT = new DataMngr(cellsize);
/* Load Proc management */ /* Load Proc management */
PROC = new ProcMngr; PROC = new ProcMngr(CError);
/* Load Label management */ /* Load Label management */
CLabels = new LabelMngr(CError); CLabels = new LabelMngr(CError);
/* Load Native management */ /* Load Native management */
@ -419,12 +419,10 @@ bool Compiler::Parse()
FILE *fp = 0; FILE *fp = 0;
char buffer[256] = {0}; char buffer[256] = {0};
std::stack<int> DefStack; std::stack<int> DefStack;
std::stack<std::string> LabelStack;
curLine = 0; curLine = 0;
AsmSection sec = Asm_None; AsmSection sec = Asm_None;
lastCip = 0-cellsize; lastCip = 0-cellsize;
int pass = 0; int pass = 0;
Start: Start:
fp = fopen(filename.c_str(), "rt"); fp = fopen(filename.c_str(), "rt");
curLine = 0; curLine = 0;
@ -698,8 +696,11 @@ Start:
/* Check if the symbol is already used */ /* Check if the symbol is already used */
if ( (S = CSymbols->FindSymbol(params)) != NULL) if ( (S = CSymbols->FindSymbol(params)) != NULL)
{ {
CError->ErrorMsg(Err_Invalid_Symbol, params.c_str(), S->line); if (S->type != Sym_Proc)
continue; {
CError->ErrorMsg(Err_Symbol_Reuse, params.c_str(), S->line);
continue;
}
} }
/* Create instruction */ /* Create instruction */
Asm *ASM = new Asm; Asm *ASM = new Asm;
@ -707,12 +708,26 @@ Start:
ASM->op = OpCodes["proc"]; ASM->op = OpCodes["proc"];
ASM->line = curLine; ASM->line = curLine;
lastCip += cellsize; lastCip += cellsize;
/* Add symbol */ if (S == NULL)
S = CSymbols->AddSymbol(params, Sym_Proc, CurLine()); {
/* Add symbol */
S = CSymbols->AddSymbol(params, Sym_Proc, CurLine());
/* Add to PROC list */
PROC->AddProc(S, ASM);
} else {
ProcMngr::AsmProc *p = 0;
p = PROC->FindProc(params);
if (p == NULL || p->ASM != NULL)
{
CError->ErrorMsg(Err_Symbol_Reuse, params.c_str(), S->line);
continue;
} else {
p->ASM = ASM;
}
}
/* Add to code list */ /* Add to code list */
CodeList.push_back(ASM); CodeList.push_back(ASM);
/* Add to PROC list */
PROC->AddProc(S, ASM);
} else if (code.compare("ENDP") == 0) { } else if (code.compare("ENDP") == 0) {
/* This is, in theory, not needed /* This is, in theory, not needed
* Nonetheless, we check labels here * Nonetheless, we check labels here
@ -740,21 +755,24 @@ Start:
{ {
LabelMngr::Label *p = CLabels->FindLabel(code); LabelMngr::Label *p = CLabels->FindLabel(code);
if (p == NULL) if (p == NULL)
{
CError->ErrorMsg(Err_Invalid_Symbol); CError->ErrorMsg(Err_Invalid_Symbol);
else } else {
p->cip = lastCip+cellsize; p->cip = lastCip+cellsize;
continue; p->sym->line = CurLine();
}
} else { } else {
CError->ErrorMsg(Err_Symbol_Reuse, code.c_str(), S->line); CError->ErrorMsg(Err_Symbol_Reuse, code.c_str(), S->line);
} }
continue; continue;
} else {
if (code[0] == '_')
{
LabelStack.push(code);
}
S = CSymbols->AddSymbol(code, Sym_Label, CurLine());
CLabels->AddLabel(S, lastCip+cellsize);
} }
if (code[0] == '_')
{
LabelStack.push(code);
}
S = CSymbols->AddSymbol(code, Sym_Label, CurLine());
CLabels->AddLabel(S, lastCip+cellsize);
} else { } else {
/* Check if there is a valid opcode */ /* Check if there is a valid opcode */
int op = OpCodes[code]; int op = OpCodes[code];
@ -790,6 +808,7 @@ Start:
FindArguments(params, paramList, argPos, true); FindArguments(params, paramList, argPos, true);
if (argPos != (int)(params.size()-1)) if (argPos != (int)(params.size()-1))
{ {
assert(0);
CError->ErrorMsg(Err_Unexpected_Char, params[argPos]); CError->ErrorMsg(Err_Unexpected_Char, params[argPos]);
continue; continue;
} }
@ -1595,6 +1614,9 @@ Start:
/* We're not done! Check the label Queue */ /* We're not done! Check the label Queue */
CLabels->CompleteQueue(); CLabels->CompleteQueue();
/* and the procedure queue ... */
PROC->CompleteQueue();
CError->PrintReport(); CError->PrintReport();
@ -2270,6 +2292,8 @@ int Compiler::DerefSymbol(std::string &str, SymbolType sym)
if (sym == Sym_Label) if (sym == Sym_Label)
{ {
S = CSymbols->AddSymbol(str, Sym_Label, -1); S = CSymbols->AddSymbol(str, Sym_Label, -1);
} else if (sym == Sym_Proc) {
S = CSymbols->AddSymbol(str, Sym_Proc, -1);
} else { } else {
CError->ErrorMsg(Err_Unknown_Symbol, str.c_str()); CError->ErrorMsg(Err_Unknown_Symbol, str.c_str());
return 0; return 0;
@ -2284,14 +2308,21 @@ int Compiler::DerefSymbol(std::string &str, SymbolType sym)
{ {
case Sym_Proc: case Sym_Proc:
{ {
val = PROC->GetCip(str); ProcMngr::AsmProc *p = 0;
if (val == ProcMngr::ncip)
if ( ((p = PROC->FindProc(str)) == NULL) || p->ASM == NULL)
{ {
CError->ErrorMsg(Err_Invalid_Symbol); /* Labels we handle differently.
return 0; Add it to the label queue
*/
p = PROC->AddProc(S, NULL);
PROC->QueueProc(str, CurAsm());
val = ProcMngr::ncip;
} else {
val = p->ASM->cip;
} }
break; break;
} }
case Sym_Native: case Sym_Native:
{ {
val = CNatives->GetNativeId(str); val = CNatives->GetNativeId(str);
@ -2299,7 +2330,7 @@ int Compiler::DerefSymbol(std::string &str, SymbolType sym)
{ {
CError->ErrorMsg(Err_Invalid_Symbol); CError->ErrorMsg(Err_Invalid_Symbol);
return 0; return 0;
} }
break; break;
} }
case Sym_Dat: case Sym_Dat:
@ -2309,20 +2340,24 @@ int Compiler::DerefSymbol(std::string &str, SymbolType sym)
{ {
CError->ErrorMsg(Err_Invalid_Symbol); CError->ErrorMsg(Err_Invalid_Symbol);
return 0; return 0;
} }
break; break;
} }
case Sym_Label: case Sym_Label:
{ {
val = CLabels->GetCip(str); LabelMngr::Label *L = 0;
if (val == LabelMngr::ncip)
if ( (L = CLabels->FindLabel(str)) == NULL )
{ {
/* Labels we handle differently. /* Labels we handle differently.
Add it to the label queue Add it to the label queue
*/ */
CLabels->AddLabel(S, LabelMngr::ncip); L = CLabels->AddLabel(S, LabelMngr::ncip);
CLabels->QueueLabel(str, CurAsm()); CLabels->QueueLabel(str, CurAsm());
LabelStack.push(str);
} }
val = L->cip;
break; break;
} }
default: default:

View File

@ -85,6 +85,7 @@ private:
private: private:
std::vector<Asm *> CodeList; std::vector<Asm *> CodeList;
std::map<std::string,int> OpCodes; std::map<std::string,int> OpCodes;
std::stack<std::string> LabelStack;
char *Output; char *Output;
ErrorMngr *CError; ErrorMngr *CError;
SymbolList *CSymbols; SymbolList *CSymbols;

View File

@ -100,6 +100,7 @@ void ErrorMngr::DefineErrors()
List.at(Err_Bad_Not) = "Wrong type argument to bit-complement"; List.at(Err_Bad_Not) = "Wrong type argument to bit-complement";
List.at(Err_Invalid_Operator) = "Operator used on bad type"; List.at(Err_Invalid_Operator) = "Operator used on bad type";
List.at(Err_Invalid_Pragma) = "Invalid pragma"; List.at(Err_Invalid_Pragma) = "Invalid pragma";
List.at(Err_Invalid_Proc) = "Procedure referenced that does not exist";
List.at(Err_FileNone) = "No file specified"; List.at(Err_FileNone) = "No file specified";
List.at(Err_FileOpen) = "Could not open file \"%s\""; List.at(Err_FileOpen) = "Could not open file \"%s\"";

View File

@ -63,6 +63,7 @@ typedef enum
Err_Bad_Not, Err_Bad_Not,
Err_Invalid_Operator, Err_Invalid_Operator,
Err_Invalid_Pragma, Err_Invalid_Pragma,
Err_Invalid_Proc,
errors_end, errors_end,
fatals_start, fatals_start,

View File

@ -35,7 +35,7 @@ LabelMngr::Label::Label()
void LabelMngr::Clear() void LabelMngr::Clear()
{ {
std::vector<LabelMngr::Label *>::iterator i; std::list<LabelMngr::Label *>::iterator i;
for (i=List.begin(); i!=List.end(); i++) for (i=List.begin(); i!=List.end(); i++)
{ {
@ -46,7 +46,7 @@ void LabelMngr::Clear()
List.clear(); List.clear();
} }
void LabelMngr::AddLabel(SymbolList::Symbol *sym, int cip) LabelMngr::Label *LabelMngr::AddLabel(SymbolList::Symbol *sym, int cip)
{ {
LabelMngr::Label *p = new LabelMngr::Label; LabelMngr::Label *p = new LabelMngr::Label;
@ -54,11 +54,13 @@ void LabelMngr::AddLabel(SymbolList::Symbol *sym, int cip)
p->cip = cip; p->cip = cip;
List.push_back(p); List.push_back(p);
return p;
} }
LabelMngr::Label *LabelMngr::FindLabel(std::string &sym) LabelMngr::Label *LabelMngr::FindLabel(std::string &sym)
{ {
std::vector<LabelMngr::Label *>::iterator i; std::list<LabelMngr::Label *>::iterator i;
for (i=List.begin(); i!=List.end(); i++) for (i=List.begin(); i!=List.end(); i++)
{ {
@ -95,6 +97,7 @@ void LabelMngr::CompleteQueue(bool isLocal)
{ {
std::map<std::string,std::stack<Asm *> >::iterator i; std::map<std::string,std::stack<Asm *> >::iterator i;
std::stack<Asm *> *stk = 0; std::stack<Asm *> *stk = 0;
std::stack<std::map<std::string,std::stack<Asm *> >::iterator> DeleteStack;
std::string search; std::string search;
Asm *ASM = 0; Asm *ASM = 0;
LabelMngr::Label *p = 0; LabelMngr::Label *p = 0;
@ -114,6 +117,7 @@ void LabelMngr::CompleteQueue(bool isLocal)
CError->ErrorMsg(Err_Bad_Label); CError->ErrorMsg(Err_Bad_Label);
stk->pop(); stk->pop();
} }
DeleteStack.push( i );
} }
} else { } else {
while (!stk->empty()) while (!stk->empty())
@ -122,10 +126,15 @@ void LabelMngr::CompleteQueue(bool isLocal)
ASM->params[0] = p->cip; ASM->params[0] = p->cip;
stk->pop(); stk->pop();
} }
DeleteStack.push( i );
} }
} }
LQ.clear(); while (!DeleteStack.empty())
{
LQ.erase(DeleteStack.top());
DeleteStack.pop();
}
} }
int LabelMngr::GetCip(std::string &sym) int LabelMngr::GetCip(std::string &sym)
@ -142,13 +151,18 @@ int LabelMngr::GetCip(std::string &sym)
bool LabelMngr::EraseLabel(std::string &sym) bool LabelMngr::EraseLabel(std::string &sym)
{ {
std::vector<LabelMngr::Label *>::iterator i; std::list<LabelMngr::Label *>::iterator i;
LabelMngr::Label *L = 0;
for (i=List.begin(); i!=List.end(); i++) for (i=List.begin(); i!=List.end(); i++)
{ {
if ( (*i)->sym->IsEqual(sym) ) L = (*i);
if ( L->sym->IsEqual(sym) )
{ {
List.erase(i); i = List.erase(i);
L->sym = 0;
delete L;
L = 0;
return true; return true;
} }
} }
@ -156,3 +170,12 @@ bool LabelMngr::EraseLabel(std::string &sym)
return false; return false;
} }
void LabelMngr::PrintList()
{
std::list<LabelMngr::Label *>::iterator i;
for (i=List.begin(); i!=List.end(); i++)
{
printf("Label:\t%s\t%d\t%d\n", (*i)->sym->sym.c_str(), (*i)->cip, (*i)->sym->line);
}
}

View File

@ -37,7 +37,7 @@ public:
~LabelMngr(); ~LabelMngr();
LabelMngr() { CError = NULL; assert(CError!=NULL); } LabelMngr() { CError = NULL; assert(CError!=NULL); }
LabelMngr(ErrorMngr *e) { CError = e; } LabelMngr(ErrorMngr *e) { CError = e; }
void AddLabel(SymbolList::Symbol *sym, int cip); LabelMngr::Label *AddLabel(SymbolList::Symbol *sym, int cip);
LabelMngr::Label *FindLabel(std::string &sym); LabelMngr::Label *FindLabel(std::string &sym);
int GetCip(std::string &sym); int GetCip(std::string &sym);
void Clear(); void Clear();
@ -45,8 +45,9 @@ public:
void QueueLabel(std::string &sym, Asm *ASM); void QueueLabel(std::string &sym, Asm *ASM);
void CompleteQueue(bool isLocal = false); void CompleteQueue(bool isLocal = false);
bool EraseLabel(std::string &sym); bool EraseLabel(std::string &sym);
void PrintList();
private: private:
std::vector<LabelMngr::Label *> List; std::list<LabelMngr::Label *> List;
std::map<std::string, std::stack<Asm *> > LQ; std::map<std::string, std::stack<Asm *> > LQ;
ErrorMngr *CError; ErrorMngr *CError;
public: public:

View File

@ -22,6 +22,18 @@
#include "amxasm.h" #include "amxasm.h"
ProcMngr::ProcMngr()
{
CError = 0;
printf("Instantiated without a compiler!\n");
assert(CError);
}
ProcMngr::ProcMngr(ErrorMngr *e)
{
CError = e;
}
ProcMngr::~ProcMngr() ProcMngr::~ProcMngr()
{ {
Clear(); Clear();
@ -40,7 +52,7 @@ void ProcMngr::Clear()
List.clear(); List.clear();
} }
void ProcMngr::AddProc(SymbolList::Symbol *Symbol, Asm *ASM) ProcMngr::AsmProc *ProcMngr::AddProc(SymbolList::Symbol *Symbol, Asm *ASM)
{ {
ProcMngr::AsmProc *a = new ProcMngr::AsmProc; ProcMngr::AsmProc *a = new ProcMngr::AsmProc;
@ -49,6 +61,8 @@ void ProcMngr::AddProc(SymbolList::Symbol *Symbol, Asm *ASM)
a->pb = false; a->pb = false;
List.push_back(a); List.push_back(a);
return a;
} }
bool ProcMngr::SetPublic(std::string &sym) bool ProcMngr::SetPublic(std::string &sym)
@ -99,9 +113,46 @@ int ProcMngr::GetCip(std::string &sym)
p = FindProc(sym); p = FindProc(sym);
if (p == NULL) if (p == NULL || p->ASM == NULL)
return ncip; return ncip;
return p->ASM->cip; return p->ASM->cip;
} }
void ProcMngr::QueueProc(std::string &sym, Asm *ASM)
{
std::string d(sym);
PQ[d].push(ASM);
}
void ProcMngr::CompleteQueue()
{
std::map<std::string,std::stack<Asm *> >::iterator i;
std::string search;
ProcMngr::AsmProc *p = 0;
std::stack<Asm *> *stk = 0;
for (i=PQ.begin(); i!=PQ.end(); i++)
{
search.assign( (*i).first );
p = FindProc(search);
stk = &((*i).second);
if (p == NULL || p->ASM == NULL)
{
while (!stk->empty())
{
CError->SetLine(stk->top()->line);
CError->ErrorMsg(Err_Invalid_Proc);
stk->pop();
}
} else {
while (!stk->empty())
{
stk->top()->cip = p->ASM->cip;
stk->top()->params[0] = p->ASM->cip;
stk->pop();
}
}
}
}

View File

@ -35,14 +35,20 @@ public:
}; };
public: public:
~ProcMngr(); ~ProcMngr();
void AddProc(SymbolList::Symbol *Symbol, Asm *ASM); ProcMngr();
ProcMngr(ErrorMngr *e);
ProcMngr::AsmProc *AddProc(SymbolList::Symbol *Symbol, Asm *ASM);
ProcMngr::AsmProc *FindProc(std::string &sym); ProcMngr::AsmProc *FindProc(std::string &sym);
int GetCip(std::string &sym); int GetCip(std::string &sym);
bool SetPublic(std::string &sym); bool SetPublic(std::string &sym);
void GetPublics(std::vector<ProcMngr::AsmProc *> &pbList); void GetPublics(std::vector<ProcMngr::AsmProc *> &pbList);
void QueueProc(std::string &sym, Asm *ASM);
void CompleteQueue();
void Clear(); void Clear();
private: private:
std::vector<ProcMngr::AsmProc *> List; std::vector<ProcMngr::AsmProc *> List;
std::map<std::string, std::stack<Asm *> > PQ;
ErrorMngr *CError;
public: public:
static const int ncip = -1; static const int ncip = -1;
}; };

View File

@ -53,7 +53,7 @@ bool IsValidSymbol(std::string &text)
void SymbolList::Clear() void SymbolList::Clear()
{ {
std::vector<SymbolList::Symbol *>::iterator i; std::list<SymbolList::Symbol *>::iterator i;
for (i=List.begin(); i!=List.end(); i++) for (i=List.begin(); i!=List.end(); i++)
{ {
@ -100,7 +100,7 @@ SymbolList::Symbol *SymbolList::AddSymbol(std::string &sym, SymbolType type, int
SymbolList::Symbol* SymbolList::FindSymbol(std::string &sym) SymbolList::Symbol* SymbolList::FindSymbol(std::string &sym)
{ {
std::vector<Symbol*>::iterator i; std::list<Symbol*>::iterator i;
for (i=List.begin(); i!=List.end(); i++) for (i=List.begin(); i!=List.end(); i++)
{ {
if ((*i)->IsEqual(sym)) if ((*i)->IsEqual(sym))
@ -112,7 +112,7 @@ SymbolList::Symbol* SymbolList::FindSymbol(std::string &sym)
void SymbolList::PrintTable() void SymbolList::PrintTable()
{ {
std::vector<Symbol*>::iterator i; std::list<Symbol*>::iterator i;
for (i=List.begin(); i!=List.end(); i++) for (i=List.begin(); i!=List.end(); i++)
{ {
printf("Symbol \"%s\" defined on line %d\n", (*i)->sym.c_str(), (*i)->line); printf("Symbol \"%s\" defined on line %d\n", (*i)->sym.c_str(), (*i)->line);
@ -121,12 +121,17 @@ void SymbolList::PrintTable()
bool SymbolList::EraseSymbol(std::string &sym) bool SymbolList::EraseSymbol(std::string &sym)
{ {
std::vector<SymbolList::Symbol *>::iterator i; std::list<SymbolList::Symbol *>::iterator i;
SymbolList::Symbol *S = 0;
for (i=List.begin(); i!=List.end(); i++) for (i=List.begin(); i!=List.end(); i++)
{ {
if ( (*i)->IsEqual(sym) ) S = (*i);
if ( S && S->IsEqual(sym) )
{ {
List.erase(i); delete S;
i = List.erase(i);
S = 0;
return true; return true;
} }
} }

View File

@ -58,7 +58,7 @@ public:
void PrintTable(); void PrintTable();
void Clear(); void Clear();
private: private:
std::vector<Symbol*> List; std::list<Symbol*> List;
}; };

View File

@ -27,7 +27,7 @@ std::string output_name;
Compiler Program; Compiler Program;
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
get_options(argc, argv, Program); get_options(argc, argv, Program);
if (filename.size() < 1) if (filename.size() < 1)
@ -40,7 +40,6 @@ int main(int argc, char **argv)
Program.Load(filename); Program.Load(filename);
if (Program.Parse()) if (Program.Parse())
{ {
if (Program.Compile(output_name.size() ? output_name : filename)) if (Program.Compile(output_name.size() ? output_name : filename))
printf("Done.\n"); printf("Done.\n");
else else

View File

@ -139,6 +139,7 @@ int CExpr::DeHex(std::string blk)
blk[pos] -= 32; blk[pos] -= 32;
if (blk[pos] >= 16 || blk[pos] < 0) if (blk[pos] >= 16 || blk[pos] < 0)
{ {
assert(0);
if (CError) if (CError)
CError->ErrorMsg(Err_Unexpected_Char, blk[pos]); CError->ErrorMsg(Err_Unexpected_Char, blk[pos]);
return 0; return 0;
@ -238,7 +239,8 @@ cExprType CExpr::Evaluate(int symNum)
Update(); Update();
return t; return t;
} else { } else {
if (CError->IsSymbol(data) || (IsValidSymbol(data) && symNum == Sym_Label)) if (CError->IsSymbol(data)
|| (IsValidSymbol(data) && symNum == Sym_Label || symNum == Sym_Proc))
{ {
type = Val_Number; type = Val_Number;
numVal = CError->DerefSymbol(data, symNum); numVal = CError->DerefSymbol(data, symNum);