diff --git a/compiler/scasm/amx.h b/compiler/scasm/amx.h index dabfbf7d..f1dbb9ff 100755 --- a/compiler/scasm/amx.h +++ b/compiler/scasm/amx.h @@ -43,7 +43,7 @@ typedef int int32_t; typedef unsigned int uint32_t; #else - //typedef long int int32_t; + typedef long int int32_t; typedef unsigned long int uint32_t; #endif #if defined __WIN32__ || defined _WIN32 || defined WIN32 diff --git a/compiler/scasm/amx_compiler.cpp b/compiler/scasm/amx_compiler.cpp index 119a7efd..223577d6 100755 --- a/compiler/scasm/amx_compiler.cpp +++ b/compiler/scasm/amx_compiler.cpp @@ -106,7 +106,7 @@ void Compiler::Init() /* Load DAT management */ DAT = new DataMngr(cellsize); /* Load Proc management */ - PROC = new ProcMngr; + PROC = new ProcMngr(CError); /* Load Label management */ CLabels = new LabelMngr(CError); /* Load Native management */ @@ -419,12 +419,10 @@ bool Compiler::Parse() FILE *fp = 0; char buffer[256] = {0}; std::stack DefStack; - std::stack LabelStack; curLine = 0; AsmSection sec = Asm_None; lastCip = 0-cellsize; int pass = 0; - Start: fp = fopen(filename.c_str(), "rt"); curLine = 0; @@ -698,8 +696,11 @@ Start: /* Check if the symbol is already used */ if ( (S = CSymbols->FindSymbol(params)) != NULL) { - CError->ErrorMsg(Err_Invalid_Symbol, params.c_str(), S->line); - continue; + if (S->type != Sym_Proc) + { + CError->ErrorMsg(Err_Symbol_Reuse, params.c_str(), S->line); + continue; + } } /* Create instruction */ Asm *ASM = new Asm; @@ -707,12 +708,26 @@ Start: ASM->op = OpCodes["proc"]; ASM->line = curLine; lastCip += cellsize; - /* Add symbol */ - S = CSymbols->AddSymbol(params, Sym_Proc, CurLine()); + if (S == NULL) + { + /* 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 */ CodeList.push_back(ASM); - /* Add to PROC list */ - PROC->AddProc(S, ASM); } else if (code.compare("ENDP") == 0) { /* This is, in theory, not needed * Nonetheless, we check labels here @@ -740,21 +755,24 @@ Start: { LabelMngr::Label *p = CLabels->FindLabel(code); if (p == NULL) + { CError->ErrorMsg(Err_Invalid_Symbol); - else + } else { p->cip = lastCip+cellsize; - continue; + p->sym->line = CurLine(); + } } else { CError->ErrorMsg(Err_Symbol_Reuse, code.c_str(), S->line); } 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 { /* Check if there is a valid opcode */ int op = OpCodes[code]; @@ -790,6 +808,7 @@ Start: FindArguments(params, paramList, argPos, true); if (argPos != (int)(params.size()-1)) { + assert(0); CError->ErrorMsg(Err_Unexpected_Char, params[argPos]); continue; } @@ -1595,6 +1614,9 @@ Start: /* We're not done! Check the label Queue */ CLabels->CompleteQueue(); + + /* and the procedure queue ... */ + PROC->CompleteQueue(); CError->PrintReport(); @@ -2270,6 +2292,8 @@ int Compiler::DerefSymbol(std::string &str, SymbolType sym) if (sym == Sym_Label) { S = CSymbols->AddSymbol(str, Sym_Label, -1); + } else if (sym == Sym_Proc) { + S = CSymbols->AddSymbol(str, Sym_Proc, -1); } else { CError->ErrorMsg(Err_Unknown_Symbol, str.c_str()); return 0; @@ -2284,14 +2308,21 @@ int Compiler::DerefSymbol(std::string &str, SymbolType sym) { case Sym_Proc: { - val = PROC->GetCip(str); - if (val == ProcMngr::ncip) + ProcMngr::AsmProc *p = 0; + + if ( ((p = PROC->FindProc(str)) == NULL) || p->ASM == NULL) { - CError->ErrorMsg(Err_Invalid_Symbol); - return 0; + /* Labels we handle differently. + Add it to the label queue + */ + p = PROC->AddProc(S, NULL); + PROC->QueueProc(str, CurAsm()); + val = ProcMngr::ncip; + } else { + val = p->ASM->cip; } break; - } + } case Sym_Native: { val = CNatives->GetNativeId(str); @@ -2299,7 +2330,7 @@ int Compiler::DerefSymbol(std::string &str, SymbolType sym) { CError->ErrorMsg(Err_Invalid_Symbol); return 0; - } + } break; } case Sym_Dat: @@ -2309,20 +2340,24 @@ int Compiler::DerefSymbol(std::string &str, SymbolType sym) { CError->ErrorMsg(Err_Invalid_Symbol); return 0; - } + } break; } case Sym_Label: { - val = CLabels->GetCip(str); - if (val == LabelMngr::ncip) + LabelMngr::Label *L = 0; + + if ( (L = CLabels->FindLabel(str)) == NULL ) { /* Labels we handle differently. Add it to the label queue */ - CLabels->AddLabel(S, LabelMngr::ncip); + L = CLabels->AddLabel(S, LabelMngr::ncip); CLabels->QueueLabel(str, CurAsm()); + LabelStack.push(str); } + + val = L->cip; break; } default: diff --git a/compiler/scasm/amx_compiler.h b/compiler/scasm/amx_compiler.h index 388d1ab5..fc36e7db 100755 --- a/compiler/scasm/amx_compiler.h +++ b/compiler/scasm/amx_compiler.h @@ -85,6 +85,7 @@ private: private: std::vector CodeList; std::map OpCodes; + std::stack LabelStack; char *Output; ErrorMngr *CError; SymbolList *CSymbols; diff --git a/compiler/scasm/amx_error.cpp b/compiler/scasm/amx_error.cpp index d0ceca8a..01e5ee64 100755 --- a/compiler/scasm/amx_error.cpp +++ b/compiler/scasm/amx_error.cpp @@ -100,6 +100,7 @@ void ErrorMngr::DefineErrors() 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_Pragma) = "Invalid pragma"; + List.at(Err_Invalid_Proc) = "Procedure referenced that does not exist"; List.at(Err_FileNone) = "No file specified"; List.at(Err_FileOpen) = "Could not open file \"%s\""; diff --git a/compiler/scasm/amx_error.h b/compiler/scasm/amx_error.h index 20995671..49819bcc 100755 --- a/compiler/scasm/amx_error.h +++ b/compiler/scasm/amx_error.h @@ -63,6 +63,7 @@ typedef enum Err_Bad_Not, Err_Invalid_Operator, Err_Invalid_Pragma, + Err_Invalid_Proc, errors_end, fatals_start, diff --git a/compiler/scasm/amx_label.cpp b/compiler/scasm/amx_label.cpp index 6709b5f0..76281f49 100755 --- a/compiler/scasm/amx_label.cpp +++ b/compiler/scasm/amx_label.cpp @@ -35,7 +35,7 @@ LabelMngr::Label::Label() void LabelMngr::Clear() { - std::vector::iterator i; + std::list::iterator i; for (i=List.begin(); i!=List.end(); i++) { @@ -46,7 +46,7 @@ void LabelMngr::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; @@ -54,11 +54,13 @@ void LabelMngr::AddLabel(SymbolList::Symbol *sym, int cip) p->cip = cip; List.push_back(p); + + return p; } LabelMngr::Label *LabelMngr::FindLabel(std::string &sym) { - std::vector::iterator i; + std::list::iterator i; for (i=List.begin(); i!=List.end(); i++) { @@ -95,6 +97,7 @@ void LabelMngr::CompleteQueue(bool isLocal) { std::map >::iterator i; std::stack *stk = 0; + std::stack >::iterator> DeleteStack; std::string search; Asm *ASM = 0; LabelMngr::Label *p = 0; @@ -114,6 +117,7 @@ void LabelMngr::CompleteQueue(bool isLocal) CError->ErrorMsg(Err_Bad_Label); stk->pop(); } + DeleteStack.push( i ); } } else { while (!stk->empty()) @@ -122,10 +126,15 @@ void LabelMngr::CompleteQueue(bool isLocal) ASM->params[0] = p->cip; stk->pop(); } + DeleteStack.push( i ); } } - LQ.clear(); + while (!DeleteStack.empty()) + { + LQ.erase(DeleteStack.top()); + DeleteStack.pop(); + } } int LabelMngr::GetCip(std::string &sym) @@ -142,13 +151,18 @@ int LabelMngr::GetCip(std::string &sym) bool LabelMngr::EraseLabel(std::string &sym) { - std::vector::iterator i; + std::list::iterator i; + LabelMngr::Label *L = 0; 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; } } @@ -156,3 +170,12 @@ bool LabelMngr::EraseLabel(std::string &sym) return false; } +void LabelMngr::PrintList() +{ + std::list::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); + } +} \ No newline at end of file diff --git a/compiler/scasm/amx_label.h b/compiler/scasm/amx_label.h index 8361c1a4..e0b0ac25 100755 --- a/compiler/scasm/amx_label.h +++ b/compiler/scasm/amx_label.h @@ -37,7 +37,7 @@ public: ~LabelMngr(); LabelMngr() { CError = NULL; assert(CError!=NULL); } 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); int GetCip(std::string &sym); void Clear(); @@ -45,8 +45,9 @@ public: void QueueLabel(std::string &sym, Asm *ASM); void CompleteQueue(bool isLocal = false); bool EraseLabel(std::string &sym); + void PrintList(); private: - std::vector List; + std::list List; std::map > LQ; ErrorMngr *CError; public: diff --git a/compiler/scasm/amx_proc.cpp b/compiler/scasm/amx_proc.cpp index e30e37a7..b987e43c 100755 --- a/compiler/scasm/amx_proc.cpp +++ b/compiler/scasm/amx_proc.cpp @@ -22,6 +22,18 @@ #include "amxasm.h" +ProcMngr::ProcMngr() +{ + CError = 0; + printf("Instantiated without a compiler!\n"); + assert(CError); +} + +ProcMngr::ProcMngr(ErrorMngr *e) +{ + CError = e; +} + ProcMngr::~ProcMngr() { Clear(); @@ -40,7 +52,7 @@ void ProcMngr::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; @@ -49,6 +61,8 @@ void ProcMngr::AddProc(SymbolList::Symbol *Symbol, Asm *ASM) a->pb = false; List.push_back(a); + + return a; } bool ProcMngr::SetPublic(std::string &sym) @@ -99,9 +113,46 @@ int ProcMngr::GetCip(std::string &sym) p = FindProc(sym); - if (p == NULL) + if (p == NULL || p->ASM == NULL) return ncip; 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 >::iterator i; + std::string search; + ProcMngr::AsmProc *p = 0; + std::stack *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(); + } + } + } +} \ No newline at end of file diff --git a/compiler/scasm/amx_proc.h b/compiler/scasm/amx_proc.h index 4a58d8d7..c2e8a1bc 100755 --- a/compiler/scasm/amx_proc.h +++ b/compiler/scasm/amx_proc.h @@ -35,14 +35,20 @@ public: }; public: ~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); int GetCip(std::string &sym); bool SetPublic(std::string &sym); void GetPublics(std::vector &pbList); + void QueueProc(std::string &sym, Asm *ASM); + void CompleteQueue(); void Clear(); private: std::vector List; + std::map > PQ; + ErrorMngr *CError; public: static const int ncip = -1; }; diff --git a/compiler/scasm/amx_symbol.cpp b/compiler/scasm/amx_symbol.cpp index 5fcb15c8..7429d7f4 100755 --- a/compiler/scasm/amx_symbol.cpp +++ b/compiler/scasm/amx_symbol.cpp @@ -53,7 +53,7 @@ bool IsValidSymbol(std::string &text) void SymbolList::Clear() { - std::vector::iterator i; + std::list::iterator 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) { - std::vector::iterator i; + std::list::iterator i; for (i=List.begin(); i!=List.end(); i++) { if ((*i)->IsEqual(sym)) @@ -112,7 +112,7 @@ SymbolList::Symbol* SymbolList::FindSymbol(std::string &sym) void SymbolList::PrintTable() { - std::vector::iterator i; + std::list::iterator i; for (i=List.begin(); i!=List.end(); i++) { 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) { - std::vector::iterator i; + std::list::iterator i; + SymbolList::Symbol *S = 0; + 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; } } diff --git a/compiler/scasm/amx_symbol.h b/compiler/scasm/amx_symbol.h index 51884714..581fe452 100755 --- a/compiler/scasm/amx_symbol.h +++ b/compiler/scasm/amx_symbol.h @@ -58,7 +58,7 @@ public: void PrintTable(); void Clear(); private: - std::vector List; + std::list List; }; diff --git a/compiler/scasm/amxasm.cpp b/compiler/scasm/amxasm.cpp index 1b7433ae..59c112ad 100755 --- a/compiler/scasm/amxasm.cpp +++ b/compiler/scasm/amxasm.cpp @@ -27,7 +27,7 @@ std::string output_name; Compiler Program; int main(int argc, char **argv) -{ +{ get_options(argc, argv, Program); if (filename.size() < 1) @@ -40,7 +40,6 @@ int main(int argc, char **argv) Program.Load(filename); if (Program.Parse()) { - if (Program.Compile(output_name.size() ? output_name : filename)) printf("Done.\n"); else diff --git a/compiler/scasm/cexpr.cpp b/compiler/scasm/cexpr.cpp index cb283d95..b23541b4 100755 --- a/compiler/scasm/cexpr.cpp +++ b/compiler/scasm/cexpr.cpp @@ -139,6 +139,7 @@ int CExpr::DeHex(std::string blk) blk[pos] -= 32; if (blk[pos] >= 16 || blk[pos] < 0) { + assert(0); if (CError) CError->ErrorMsg(Err_Unexpected_Char, blk[pos]); return 0; @@ -238,7 +239,8 @@ cExprType CExpr::Evaluate(int symNum) Update(); return t; } 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; numVal = CError->DerefSymbol(data, symNum);