From 85afb2a82360f695569cd24ef6c56d1eca7180c0 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 9 Aug 2004 08:43:27 +0000 Subject: [PATCH] Fixed labels so they can be referenced before creation. Cleaned up symbol parsing code. Reversed order of public table. Fixed bug with macro arguments. --- compiler/scasm/amx_compiler.cpp | 389 ++++++++++---------------------- compiler/scasm/amx_compiler.h | 3 + compiler/scasm/amx_data.cpp | 1 + compiler/scasm/amx_error.cpp | 3 +- compiler/scasm/amx_error.h | 1 + compiler/scasm/amx_label.cpp | 54 +++++ compiler/scasm/amx_label.h | 8 + compiler/scasm/amx_macro.cpp | 2 +- compiler/scasm/amx_parser.cpp | 9 + compiler/scasm/amxasm.cpp | 2 + compiler/scasm/cexpr.cpp | 41 ++++ 11 files changed, 238 insertions(+), 275 deletions(-) diff --git a/compiler/scasm/amx_compiler.cpp b/compiler/scasm/amx_compiler.cpp index 8af2e5d8..40ff3ffc 100755 --- a/compiler/scasm/amx_compiler.cpp +++ b/compiler/scasm/amx_compiler.cpp @@ -86,7 +86,7 @@ void Compiler::Init() /* Load Proc management */ PROC = new ProcMngr; /* Load Label management */ - CLabels = new LabelMngr; + CLabels = new LabelMngr(CError); /* Load Native management */ CNatives = new NativeMngr; /* Load the default symbols + opcodes */ @@ -155,7 +155,6 @@ bool Compiler::Compile() AddrTable a; n.Name = (*pl)->Symbol->sym.c_str(); a.addr = (*pl)->ASM->cip; - printf("%s cip = %d\n", n.Name, a.addr); a.offset = (int)Nametbl.size(); Nametbl.push_back(n); PublicsTable.push_back(a); @@ -582,6 +581,7 @@ bool Compiler::Parse() } else if (params.size() < 1 && code[code.size()-1] == ':') { /* Label! */ /* Check if symbol is valid */ + code.erase(code.size()-1, 1); if (!IsValidSymbol(code)) { CError->ErrorMsg(Err_Invalid_Symbol); @@ -590,7 +590,17 @@ bool Compiler::Parse() /* Check if the symbol is already used */ if ( (S = CSymbols->FindSymbol(code)) != NULL) { - CError->ErrorMsg(Err_Invalid_Symbol, code.c_str(), S->line); + if (S->type == Sym_Label) + { + LabelMngr::Label *p = CLabels->FindLabel(code); + if (p == NULL) + CError->ErrorMsg(Err_Invalid_Symbol); + else + p->cip = lastCip+cellsize; + continue; + } else { + CError->ErrorMsg(Err_Symbol_Reuse, code.c_str(), S->line); + } continue; } S = CSymbols->AddSymbol(code, Sym_Label, CurLine()); @@ -620,6 +630,8 @@ bool Compiler::Parse() ASM = new Asm; + curAsm = ASM; + std::vector paramList; if (params.size() > 0) @@ -1419,6 +1431,9 @@ bool Compiler::Parse() } /* Line processing */ } /* While */ + /* We're not done! Check the label Queue */ + CLabels->CompleteQueue(); + CError->PrintReport(); return true; @@ -1574,6 +1589,13 @@ void Compiler::InitOpcodes() CSymbols->AddSymbol("PROC", Sym_Reserved, 0); CSymbols->AddSymbol("ENDP", Sym_Reserved, 0); CSymbols->AddSymbol("stat", Sym_Reserved, 0); + + char buf[24]; + sprintf(buf, "%d", cellsize?cellsize:4); + std::string CellDef("CELL"); + std::string Cell(buf); + CDefines->AddDefine(CellDef, Cell); + CSymbols->AddSymbol("CELL", Sym_Define, 0); } char Compiler::OperChar(OpToken c) @@ -1813,7 +1835,7 @@ void Compiler::ProcessDirective(std::string &text) SymbolList::Symbol *S; if ((S = CSymbols->FindSymbol(symbol)) != NULL) { - CError->ErrorMsg(Err_SymbolRedef, curLine, S->sym.c_str(), S->line); + CError->ErrorMsg(Err_SymbolRedef, S->sym.c_str(), S->line); } if (def.size() < 1) def.assign("1"); @@ -1866,81 +1888,15 @@ int Compiler::Eval(std::string &str, SymbolType sym) if (pos < i || (pos == i && (OperToken(str[i]) == Token_Sub))) { bpstr.assign(str.substr(pos, i-pos)); + Strip(bpstr); e.Set(bpstr); val = 0; if (!e.Analyze() && IsValidSymbol(bpstr)) { - SymbolList::Symbol *S = NULL; - if ( (S = CSymbols->FindSymbol(bpstr)) == NULL) - { - CError->ErrorMsg(Err_Unknown_Symbol, bpstr.c_str()); - assert(0); - return 0; - } - if (sym != Sym_Dat && S->type != sym) - { - assert(0); - CError->ErrorMsg(Err_Invalid_Symbol); - return 0; - } - switch (S->type) - { - case Sym_Proc: - { - val = PROC->GetCip(bpstr); - if (val == ProcMngr::ncip) - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - } - break; - } - case Sym_Native: - { - val = CNatives->GetNativeId(bpstr); - if (val == NativeMngr::ncip) - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - } - break; - } - case Sym_Dat: - { - val = DAT->GetOffset(bpstr); - if (val == DataMngr::nof) - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - } - break; - } - case Sym_Label: - { - val = CLabels->GetCip(bpstr); - if (val == LabelMngr::ncip) - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - } - break; - } - default: - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - break; - } - } + val = DerefSymbol(bpstr, sym); } else if (e.Analyze() && (e.Evaluate() == Val_Number)) { val = e.GetNumber(); } else { - assert(0); CError->ErrorMsg(Err_Invalid_Symbol); return 0; } @@ -1959,81 +1915,15 @@ int Compiler::Eval(std::string &str, SymbolType sym) if (pos < i) { bpstr.assign(str.substr(pos, i-pos)); + Strip(bpstr); e.Set(bpstr); val = 0; if (!e.Analyze() && IsValidSymbol(bpstr)) { - SymbolList::Symbol *S = NULL; - if ( (S = CSymbols->FindSymbol(bpstr)) == NULL) - { - CError->ErrorMsg(Err_Unknown_Symbol, bpstr.c_str()); - assert(0); - return 0; - } - if (sym != Sym_Dat && S->type != sym) - { - assert(0); - CError->ErrorMsg(Err_Invalid_Symbol); - return 0; - } - switch (S->type) - { - case Sym_Proc: - { - val = PROC->GetCip(bpstr); - if (val == ProcMngr::ncip) - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - } - break; - } - case Sym_Native: - { - val = CNatives->GetNativeId(bpstr); - if (val == NativeMngr::ncip) - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - } - break; - } - case Sym_Dat: - { - val = DAT->GetOffset(bpstr); - if (val == DataMngr::nof) - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - } - break; - } - case Sym_Label: - { - val = CLabels->GetCip(bpstr); - if (val == LabelMngr::ncip) - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - } - break; - } - default: - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - break; - } - } + val = DerefSymbol(bpstr, sym); } else if (e.Analyze() && (e.Evaluate() == Val_Number)) { val = e.GetNumber(); } else { - assert(0); CError->ErrorMsg(Err_Invalid_Symbol); return 0; } @@ -2047,78 +1937,15 @@ int Compiler::Eval(std::string &str, SymbolType sym) if (pos < i) { bpstr.assign(str.substr(pos, i-pos)); + Strip(bpstr); e.Set(bpstr); val = 0; if (!e.Analyze() && IsValidSymbol(bpstr)) { - SymbolList::Symbol *S = NULL; - if ( (S = CSymbols->FindSymbol(bpstr)) == NULL) - { - CError->ErrorMsg(Err_Unknown_Symbol, bpstr.c_str()); - assert(0); - return 0; - } - if (sym != Sym_Dat && S->type != sym) - { - assert(0); - CError->ErrorMsg(Err_Invalid_Symbol); - return 0; - } - switch (S->type) - { - case Sym_Proc: - { - val = PROC->GetCip(bpstr); - if (val == ProcMngr::ncip) - { - CError->ErrorMsg(Err_Invalid_Symbol); - return 0; - } - break; - } - case Sym_Native: - { - val = CNatives->GetNativeId(bpstr); - if (val == NativeMngr::ncip) - { - CError->ErrorMsg(Err_Invalid_Symbol); - return 0; - } - break; - } - case Sym_Dat: - { - val = DAT->GetOffset(bpstr); - if (val == DataMngr::nof) - { - CError->ErrorMsg(Err_Invalid_Symbol); - return 0; - } - break; - } - case Sym_Label: - { - val = CLabels->GetCip(bpstr); - if (val == LabelMngr::ncip) - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - } - break; - } - default: - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - break; - } - } + val = DerefSymbol(bpstr, sym); } else if (e.Analyze() && (e.Evaluate() == Val_Number)) { val = e.GetNumber(); } else { - assert(0); CError->ErrorMsg(Err_Invalid_Symbol); return 0; } @@ -2128,7 +1955,12 @@ int Compiler::Eval(std::string &str, SymbolType sym) delete r; if (Stack.size() < 2) { - //TODO: Clear memory + while (Stack.size()) + { + if (Stack.top()) + delete Stack.top(); + Stack.pop(); + } CError->ErrorMsg(Err_Unmatched_Token, str[i]); return 0; } @@ -2145,81 +1977,16 @@ int Compiler::Eval(std::string &str, SymbolType sym) } if (pos < i || pos == i) { + Strip(bpstr); e.Set(bpstr); val = 0; if (!e.Analyze() && IsValidSymbol(bpstr)) { - SymbolList::Symbol *S = NULL; - if ( (S = CSymbols->FindSymbol(bpstr)) == NULL) - { - CError->ErrorMsg(Err_Unknown_Symbol, bpstr.c_str()); - assert(0); - return 0; - } - if (sym != Sym_Dat && S->type != sym) - { - assert(0); - CError->ErrorMsg(Err_Invalid_Symbol); - return 0; - } - switch (S->type) - { - case Sym_Proc: - { - val = PROC->GetCip(bpstr); - if (val == ProcMngr::ncip) - { - CError->ErrorMsg(Err_Invalid_Symbol); - return 0; - } - break; - } - case Sym_Native: - { - val = CNatives->GetNativeId(bpstr); - if (val == NativeMngr::ncip) - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - } - break; - } - case Sym_Dat: - { - val = DAT->GetOffset(bpstr); - if (val == DataMngr::nof) - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - } - break; - } - case Sym_Label: - { - val = CLabels->GetCip(bpstr); - if (val == LabelMngr::ncip) - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - } - break; - } - default: - { - CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); - return 0; - break; - } - } + val = DerefSymbol(bpstr, sym); } else if (e.Analyze() && (e.Evaluate() == Val_Number)) { val = e.GetNumber(); } else { CError->ErrorMsg(Err_Invalid_Symbol); - assert(0); return 0; } r->vals.push_back(val); @@ -2389,3 +2156,79 @@ void Compiler::PrintCodeList() } } } + +int Compiler::DerefSymbol(std::string &str, SymbolType sym) +{ + int val = 0; + + SymbolList::Symbol *S = NULL; + if ( ((S = CSymbols->FindSymbol(str)) == NULL) ) + { + if (sym == Sym_Label) + { + S = CSymbols->AddSymbol(str, Sym_Label, -1); + } else { + CError->ErrorMsg(Err_Unknown_Symbol, str.c_str()); + return 0; + } + } + if (sym != Sym_Dat && S->type != sym) + { + CError->ErrorMsg(Err_Invalid_Symbol); + return 0; + } + switch (S->type) + { + case Sym_Proc: + { + val = PROC->GetCip(str); + if (val == ProcMngr::ncip) + { + CError->ErrorMsg(Err_Invalid_Symbol); + return 0; + } + break; + } + case Sym_Native: + { + val = CNatives->GetNativeId(str); + if (val == NativeMngr::ncip) + { + CError->ErrorMsg(Err_Invalid_Symbol); + return 0; + } + break; + } + case Sym_Dat: + { + val = DAT->GetOffset(str); + if (val == DataMngr::nof) + { + CError->ErrorMsg(Err_Invalid_Symbol); + return 0; + } + break; + } + case Sym_Label: + { + val = CLabels->GetCip(str); + if (val == LabelMngr::ncip) + { + /* Labels we handle differently. + Add it to the label queue + */ + CLabels->AddLabel(S, LabelMngr::ncip); + CLabels->QueueLabel(str, CurAsm()); + } + break; + } + default: + { + CError->ErrorMsg(Err_Invalid_Symbol); + return 0; + break; + } + } + + return val; +} \ No newline at end of file diff --git a/compiler/scasm/amx_compiler.h b/compiler/scasm/amx_compiler.h index 7c4345ef..9d9d6878 100755 --- a/compiler/scasm/amx_compiler.h +++ b/compiler/scasm/amx_compiler.h @@ -83,8 +83,10 @@ public: void Clear(); int CipCount(); int CurCip() { return lastCip; } + Asm *CurAsm() { return curAsm; } bool SetDebug(); public: //private + int DerefSymbol(std::string &str, SymbolType sym = Sym_None); void ProcessDirective(std::string &text); void Init(); void InitOpcodes(); @@ -110,6 +112,7 @@ private: int cellsize; int stacksize; bool debug; + Asm *curAsm; }; #endif //_INCLUDE_AMXCOMPILER_H \ No newline at end of file diff --git a/compiler/scasm/amx_data.cpp b/compiler/scasm/amx_data.cpp index 84e50b08..eabaa589 100755 --- a/compiler/scasm/amx_data.cpp +++ b/compiler/scasm/amx_data.cpp @@ -54,6 +54,7 @@ void DataMngr::Add(std::string &s, CExpr &expr, bool db, char fill) D->symbol.assign(s); D->e = expr; D->fill = fill; + D->db = db; int size = 0; diff --git a/compiler/scasm/amx_error.cpp b/compiler/scasm/amx_error.cpp index 47f40371..4459a7ce 100755 --- a/compiler/scasm/amx_error.cpp +++ b/compiler/scasm/amx_error.cpp @@ -93,7 +93,8 @@ void ErrorMngr::DefineErrors() List.at(Err_Unmatched_Token) = "Unmatched token '%c'"; List.at(Err_Param_Count) = "Expected %d parameters, found %d"; List.at(Err_Unknown_Define) = "Unknown define referenced"; - List.at(Err_Misplaced_Directive) = "Misplaced preprocessor directive."; + List.at(Err_Misplaced_Directive) = "Misplaced preprocessor directive"; + List.at(Err_Bad_Label) = "Label referenced without being created"; 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 c7b92001..dcdadc1d 100755 --- a/compiler/scasm/amx_error.h +++ b/compiler/scasm/amx_error.h @@ -59,6 +59,7 @@ typedef enum Err_Param_Count, Err_Unknown_Define, Err_Misplaced_Directive, + Err_Bad_Label, errors_end, fatals_start, diff --git a/compiler/scasm/amx_label.cpp b/compiler/scasm/amx_label.cpp index ca38f209..4bcdcb87 100755 --- a/compiler/scasm/amx_label.cpp +++ b/compiler/scasm/amx_label.cpp @@ -27,6 +27,12 @@ LabelMngr::~LabelMngr() Clear(); } +LabelMngr::Label::Label() +{ + cip = -1; + sym = 0; +} + void LabelMngr::Clear() { std::vector::iterator i; @@ -65,6 +71,54 @@ LabelMngr::Label *LabelMngr::FindLabel(std::string &sym) return NULL; } +bool LabelMngr::SetCip(std::string &sym, int cip) +{ + LabelMngr::Label *p = NULL; + + p = FindLabel(sym); + + if (p == NULL) + return false; + + p->cip = cip; + + return true; +} + +void LabelMngr::QueueLabel(std::string &sym, Asm *ASM) +{ + std::string d(sym); + LQ[d].push(ASM); +} + +void LabelMngr::CompleteQueue() +{ + std::map >::iterator i; + std::stack *stk = 0; + std::string search; + Asm *ASM = 0; + LabelMngr::Label *p = 0; + + for (i=LQ.begin(); i!=LQ.end(); i++) + { + search.assign( (*i).first ); + p = FindLabel(search); + stk = &((*i).second); + if (p == NULL || p->cip == LabelMngr::ncip) + { + CError->ErrorMsg(Err_Bad_Label); + } + while (!stk->empty()) + { + ASM = stk->top(); + ASM->params[0] = p->cip; + stk->pop(); + } + } + + LQ.clear(); +} + int LabelMngr::GetCip(std::string &sym) { LabelMngr::Label *p = NULL; diff --git a/compiler/scasm/amx_label.h b/compiler/scasm/amx_label.h index 4a033c37..219f20a8 100755 --- a/compiler/scasm/amx_label.h +++ b/compiler/scasm/amx_label.h @@ -29,17 +29,25 @@ public: class Label { public: + Label(); SymbolList::Symbol *sym; int cip; }; public: ~LabelMngr(); + LabelMngr() { CError = NULL; assert(CError!=NULL); } + LabelMngr(ErrorMngr *e) { CError = e; } void AddLabel(SymbolList::Symbol *sym, int cip); LabelMngr::Label *FindLabel(std::string &sym); int GetCip(std::string &sym); void Clear(); + bool SetCip(std::string &sym, int cip); + void QueueLabel(std::string &sym, Asm *ASM); + void CompleteQueue(); private: std::vector List; + std::map > LQ; + ErrorMngr *CError; public: static const int ncip = -1; }; diff --git a/compiler/scasm/amx_macro.cpp b/compiler/scasm/amx_macro.cpp index 59c5160d..b5bfa674 100755 --- a/compiler/scasm/amx_macro.cpp +++ b/compiler/scasm/amx_macro.cpp @@ -152,7 +152,7 @@ void MacroList::SearchAndReplace(std::string &text) symPos = pos + (int)m->symbol.size(); argstring.assign(text.substr(symPos+1, text.size()-symPos)); std::vector argList; - ((Compiler *)Cmp)->FindArguments(argstring, argList, bPos); + ((Compiler *)Cmp)->FindArguments(argstring, argList, bPos, true); /* Build the macro */ std::string *ms; ms = BeginReplacement(m); diff --git a/compiler/scasm/amx_parser.cpp b/compiler/scasm/amx_parser.cpp index 3766f0f2..27e3ac73 100755 --- a/compiler/scasm/amx_parser.cpp +++ b/compiler/scasm/amx_parser.cpp @@ -111,6 +111,15 @@ void Strip(std::string &text) { int i = 0; + if (text.size() == 1) + { + if (isspace(text[0])) + { + text.clear(); + return; + } + } + for (i=0; i<(int)text.size(); i++) { if (!isspace(text[i])) diff --git a/compiler/scasm/amxasm.cpp b/compiler/scasm/amxasm.cpp index 6faa647d..4a8b64c9 100755 --- a/compiler/scasm/amxasm.cpp +++ b/compiler/scasm/amxasm.cpp @@ -28,6 +28,8 @@ int main(int argc, char **argv) { Compiler Program; + getchar(); + get_options(argc, argv, Program); if (filename.size() < 1) diff --git a/compiler/scasm/cexpr.cpp b/compiler/scasm/cexpr.cpp index a92ca6f1..ad8af7ce 100755 --- a/compiler/scasm/cexpr.cpp +++ b/compiler/scasm/cexpr.cpp @@ -188,6 +188,10 @@ int CExpr::Analyze() { size_t pos = 0, xc = 0, xpos = 0; /* run through the characters */ + if (data.compare("$") == 0) + { + return 1; + } for (pos = 0; pos < data.size(); pos++) { if (data[pos] == 'x') @@ -215,12 +219,48 @@ cExprType CExpr::Evaluate() block = new char[2]; + if (data.compare("$") == 0) + { + t = Val_Number; + numVal = CError->CurCip(); + char buf[32]; + sprintf(buf, "%d", numVal); + data.assign(buf); + } + if (data.find('\'', 0) != std::string::npos || data.find('"', 0) != std::string::npos) { /* STRESS TEST */ for (i=0; iErrorMsg(Err_String_Terminate); + t = Val_Error; + } else { + char cp = data[i+1]; + char *nc = 0; + if (cp == 't') + nc = "\t"; + else if (cp == 'n') + nc = "\n"; + else if (cp == '\\') + nc = "\\"; + else if (cp == '"') + nc = "\""; + else if (cp == '\'') + nc = "'"; + if (nc) + { + data.replace(i, 2, nc); + continue; + } + } + } if (IsLiteral(c) != 0) { if (litc == IsLiteral(c)) @@ -267,6 +307,7 @@ cExprType CExpr::Evaluate() numVal++; } } else { + /* Just get the number */ t = Val_Number; numVal = DeHex(data);