From b14708d6f2da9848237191544073d12791cae89e Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 9 Aug 2004 05:23:32 +0000 Subject: [PATCH] Fixed some more bugs, added #if/#else/#endif and more opcodes, and .DATA stat --- compiler/scasm/amx_compiler.cpp | 175 ++++++++++++++++++++++++++------ compiler/scasm/amx_compiler.h | 5 +- compiler/scasm/amx_data.cpp | 26 +++-- compiler/scasm/amx_data.h | 3 +- compiler/scasm/amx_error.cpp | 12 +++ compiler/scasm/amx_error.h | 4 + compiler/scasm/amx_parser.cpp | 3 + compiler/scasm/amxasm.cpp | 35 +++++-- compiler/scasm/amxasm.h | 3 +- 9 files changed, 215 insertions(+), 51 deletions(-) diff --git a/compiler/scasm/amx_compiler.cpp b/compiler/scasm/amx_compiler.cpp index 849e8e9d..8af2e5d8 100755 --- a/compiler/scasm/amx_compiler.cpp +++ b/compiler/scasm/amx_compiler.cpp @@ -28,6 +28,7 @@ Compiler::Compiler() cellsize = 4; Output = 0; stacksize = cellsize * 4096; + debug = false; Init(); } @@ -51,9 +52,19 @@ Compiler::Compiler(std::string &f) Output = 0; filename.assign(f); stacksize = cellsize * 4096; + debug = false; Init(); } +bool Compiler::SetDebug() +{ + bool state = debug; + + debug = debug ? false : true; + + return state; +} + void Compiler::Load(std::string &f) { filename.assign(f); @@ -108,7 +119,7 @@ bool Compiler::Compile() } int32_t fileSize = 0; - int16_t magic = AMX_MAGIC; + int16_t magic = (int16_t)AMX_MAGIC; char file_version = CUR_FILE_VERSION; char amx_version = MIN_AMX_VERSION; int16_t flags = 0; @@ -145,24 +156,24 @@ bool Compiler::Compile() n.Name = (*pl)->Symbol->sym.c_str(); a.addr = (*pl)->ASM->cip; printf("%s cip = %d\n", n.Name, a.addr); - a.offset = Nametbl.size(); + a.offset = (int)Nametbl.size(); Nametbl.push_back(n); PublicsTable.push_back(a); } - natives = publics + (PublicsTable.size() * (sizeof(int32_t) * 2)); + natives = publics + (int)(PublicsTable.size() * (sizeof(int32_t) * 2)); for (nl = NativeList.begin(); nl != NativeList.end(); nl++) { NameRecord n; AddrTable a; n.Name = (*nl)->S->sym.c_str(); a.addr = 0; - a.offset = Nametbl.size(); + a.offset = (int)Nametbl.size(); Nametbl.push_back(n); NativesTable.push_back(a); } - libraries = natives + (NativesTable.size() * (sizeof(int32_t) * 2)); + libraries = natives + (int)(NativesTable.size() * (sizeof(int32_t) * 2)); pubvars = libraries; tags = pubvars; names = tags; @@ -175,14 +186,14 @@ bool Compiler::Compile() int off = (*ai).offset; NameMap[cOffset] = off; (*ai).offset = cOffset; - cOffset += strlen(Nametbl.at(off).Name) + 1; + cOffset += (int)strlen(Nametbl.at(off).Name) + 1; } for (ai = NativesTable.begin(); ai != NativesTable.end(); ai++) { int off = (*ai).offset; NameMap[cOffset] = off; (*ai).offset = cOffset; - cOffset += strlen(Nametbl.at(off).Name) + 1; + cOffset += (int)strlen(Nametbl.at(off).Name) + 1; } cod = cOffset; @@ -280,16 +291,25 @@ bool Compiler::Compile() const char *s = 0; for (dmi = dm.begin(); dmi != dm.end(); dmi++) { - if ( (*dmi)->e.GetType() == Val_Number ) + if ( (*dmi)->db ) { - val = (*dmi)->e.GetNumber(); - fwrite((void *)&val, sizeof(int32_t), 1, fp); - } else { - s = (*dmi)->e.GetString(); - for (int q = 0; q < (*dmi)->e.Size(); q++) + if ( (*dmi)->e.GetType() == Val_Number ) { - val = s[q]; - fwrite((void*)&val, sizeof(int32_t), 1, fp); + val = (*dmi)->e.GetNumber(); + fwrite((void *)&val, sizeof(int32_t), 1, fp); + } else { + s = (*dmi)->e.GetString(); + for (int q = 0; q < (*dmi)->e.Size(); q++) + { + val = s[q]; + fwrite((void*)&val, sizeof(int32_t), 1, fp); + } + } + } else { + char c = (*dmi)->fill; + for (int iter=0; iter<=(*dmi)->e.GetNumber(); iter++) + { + fwrite((void*)&c, sizeof(char), 1, fp); } } } @@ -314,6 +334,7 @@ bool Compiler::Parse() { std::ifstream fp(filename.c_str()); char buffer[256] = {0}; + std::stack DefStack; curLine = 0; AsmSection sec = Asm_None; lastCip = 0-cellsize; @@ -328,15 +349,73 @@ bool Compiler::Parse() { fp.getline(buffer, 255); curLine++; - + /* Check for preprocessor directives */ if (buffer[0] == '#') { std::string procline(buffer); - ProcessDirective(procline); + if (procline.substr(0, 3).compare("#if") == 0) + { + std::string def; + std::string temp; + std::string comp; + StringBreak(procline, def, temp); + StringBreak(temp, def, comp); + DefineMngr::Define *D = 0; + if ((D = CDefines->FindDefine(def)) == 0) + { + DefStack.push(0); + } else if (D->GetDefine()->compare(comp) == 0) { + DefStack.push(1); + } else { + DefStack.push(0); + } + } else if (procline.substr(0, 5).compare("#else") == 0) { + if (DefStack.size()) + { + if (DefStack.top() == 1) + { + DefStack.pop(); + DefStack.push(0); + } else if (DefStack.top() == 0) { + DefStack.pop(); + DefStack.push(1); + } + } else { + CError->ErrorMsg(Err_Misplaced_Directive); + } + continue; + } else if (procline.substr(0, 6).compare("#endif") == 0) { + if (DefStack.size()) + { + DefStack.pop(); + } else { + CError->ErrorMsg(Err_Misplaced_Directive); + } + continue; + } else { + /* Check for previous operations */ + if (DefStack.size()) + { + if (DefStack.top() < 1) + { + continue; + } + } + ProcessDirective(procline); + } continue; } + /* Check for previous operations */ + if (DefStack.size()) + { + if (DefStack.top() < 1) + { + continue; + } + } + /* Strip the line */ std::string line(buffer); StripComments(line); @@ -400,13 +479,35 @@ bool Compiler::Parse() continue; } - /* Add and evaluate the expression */ - CExpr e(CError); - e.Set(data); - e.Evaluate(); - - /* Add into the DAT section */ - DAT->Add(symbol, e, (fmt.compare("db")==0)?true:false); + if (fmt.compare("db") == 0) + { + /* Add and evaluate the expression */ + CExpr e(CError); + e.Set(data); + e.Evaluate(); + + /* Add into the DAT section */ + DAT->Add(symbol, e, true); + } else if (fmt.compare("stat") == 0) { + CExpr e(CError); + + if (data.find("fill") != std::string::npos) + { + std::string fill, amt; + StringBreak(data, amt, buf); + StringBreak(buf, data, fill); + CExpr t(CError); + t.Set(fill); + t.Evaluate(); + e.Set(amt); + e.Evaluate(); + DAT->Add(symbol, e, false, (char)t.GetNumber()); + } else { + e.Set(data); + e.Evaluate(); + DAT->Add(symbol, e, false, 0); + } + } CSymbols->AddSymbol(symbol, Sym_Dat, CurLine()); } else if (sec == Asm_Public) { if (!IsValidSymbol(line)) @@ -504,7 +605,21 @@ bool Compiler::Parse() continue; } - Asm *ASM = new Asm; + Asm *ASM = 0; + + if (debug) + { + ASM = new Asm; + ASM->cip = lastCip+cellsize; + ASM->op = OP_LINE; + ASM->params.push_back(curLine); + ASM->params.push_back(0); + CodeList.push_back(ASM); + lastCip+=cellsize*3; + } + + ASM = new Asm; + std::vector paramList; if (params.size() > 0) @@ -1221,12 +1336,9 @@ bool Compiler::Parse() } case OP_LINE: { - /* Not yet implemented */ - assert(0); - /*CHK_PARAMS(3); + CHK_PARAMS(2); PUSH_PARAM(1, Sym_Dat); PUSH_PARAM(1, Sym_Dat); - PUSH_PARAM(1, Sym_Dat);*/ break; } case OP_SYMBOL: @@ -1241,12 +1353,9 @@ bool Compiler::Parse() } case OP_SRANGE: { - /* Not yet implemented */ - assert(0); - /*CHK_PARAMS(3); + CHK_PARAMS(2); PUSH_PARAM(1, Sym_Dat); PUSH_PARAM(1, Sym_Dat); - PUSH_PARAM(1, Sym_Dat);*/ break; } case OP_JUMP_PRI: diff --git a/compiler/scasm/amx_compiler.h b/compiler/scasm/amx_compiler.h index a0e9f68f..7c4345ef 100755 --- a/compiler/scasm/amx_compiler.h +++ b/compiler/scasm/amx_compiler.h @@ -82,7 +82,9 @@ public: int FindArguments(std::string &text, std::vector &List, int &end, bool simple = false); void Clear(); int CipCount(); -private: + int CurCip() { return lastCip; } + bool SetDebug(); +public: //private void ProcessDirective(std::string &text); void Init(); void InitOpcodes(); @@ -107,6 +109,7 @@ private: int lastCip; int cellsize; int stacksize; + bool debug; }; #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 1fdda0ce..84e50b08 100755 --- a/compiler/scasm/amx_data.cpp +++ b/compiler/scasm/amx_data.cpp @@ -44,26 +44,40 @@ DataMngr::Datum::Datum() { db = false; offset = -1; + fill = 0; } -void DataMngr::Add(std::string &s, CExpr &expr, bool db) +void DataMngr::Add(std::string &s, CExpr &expr, bool db, char fill) { DataMngr::Datum *D = new DataMngr::Datum(); D->symbol.assign(s); D->e = expr; + D->fill = fill; - int size = ((D->e.GetType() == Val_Number) ? - cellsize : D->e.Size() * cellsize); + int size = 0; + + if (db) + { + size = ((D->e.GetType() == Val_Number) ? + cellsize : D->e.Size() * cellsize); + } else { + size = D->e.GetNumber(); + } if (List.size() == 0) { D->offset = 0; } else { DataMngr::Datum *p = List[List.size()-1]; - D->offset = p->offset + - ((p->e.GetType() == Val_Number) ? - cellsize : p->e.Size() * cellsize); + if (p->db) + { + D->offset = p->offset + + ((p->e.GetType() == Val_Number) ? + cellsize : p->e.Size() * cellsize); + } else { + D->offset = p->offset + p->e.GetNumber(); + } } cursize += size; diff --git a/compiler/scasm/amx_data.h b/compiler/scasm/amx_data.h index cc559b86..6888f275 100755 --- a/compiler/scasm/amx_data.h +++ b/compiler/scasm/amx_data.h @@ -34,12 +34,13 @@ public: CExpr e; bool db; int offset; + char fill; }; public: ~DataMngr(); DataMngr() { cellsize = 4; lastOffset = 0; cursize = 0; } DataMngr(int cell) { lastOffset = 0; cellsize = cell; cursize = 0; } - void Add(std::string &s, CExpr &expr, bool db = false); + void Add(std::string &s, CExpr &expr, bool db = false, char fill = 0); DataMngr::Datum *FindData(std::string &sym); void GetData(std::vector &dList); int GetOffset(std::string &sym); diff --git a/compiler/scasm/amx_error.cpp b/compiler/scasm/amx_error.cpp index 3687f201..47f40371 100755 --- a/compiler/scasm/amx_error.cpp +++ b/compiler/scasm/amx_error.cpp @@ -38,6 +38,16 @@ void ErrorMngr::Clear() HighestError = Err_None; } +int ErrorMngr::CurLine() +{ + return ((Compiler *)Cmp)->CurLine(); +} + +int ErrorMngr::CurCip() +{ + return ((Compiler *)Cmp)->CurCip(); +} + ErrorMngr::ErrorMngr(void *c) { Cmp = c; @@ -82,6 +92,8 @@ void ErrorMngr::DefineErrors() List.at(Err_Opcode) = "Invalid or unrecognized opcode"; 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_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 b78faa0c..c7b92001 100755 --- a/compiler/scasm/amx_error.h +++ b/compiler/scasm/amx_error.h @@ -57,6 +57,8 @@ typedef enum Err_Opcode, Err_Unmatched_Token, Err_Param_Count, + Err_Unknown_Define, + Err_Misplaced_Directive, errors_end, fatals_start, @@ -91,6 +93,8 @@ public: void ErrorMsg(ErrorCode error, ...); ErrorType GetStatus() { return HighestError; } void PrintReport(); + int CurLine(); + int CurCip(); }; #endif //_INCLUDE_AMX_ERROR diff --git a/compiler/scasm/amx_parser.cpp b/compiler/scasm/amx_parser.cpp index 8def3ecb..3766f0f2 100755 --- a/compiler/scasm/amx_parser.cpp +++ b/compiler/scasm/amx_parser.cpp @@ -87,6 +87,9 @@ void StringBreak(std::string &Source, std::string &Left, std::string &Right) int l=0; unsigned int i=0; + Left.clear(); + Right.clear(); + for (i=0; i &List); +void print_version(); #endif //_INCLUDE_AMXASM_H