diff --git a/compiler/scasm/amx_compiler.cpp b/compiler/scasm/amx_compiler.cpp index 617e46fd..849e8e9d 100755 --- a/compiler/scasm/amx_compiler.cpp +++ b/compiler/scasm/amx_compiler.cpp @@ -26,11 +26,14 @@ Compiler::Compiler() { curLine = -1; cellsize = 4; + Output = 0; + stacksize = cellsize * 4096; Init(); } Compiler::~Compiler() { + Clear(); delete CDefines; delete CError; delete CLabels; @@ -43,10 +46,12 @@ Compiler::~Compiler() Compiler::Compiler(std::string &f) { - Init(); - filename.assign(f); curLine = -1; cellsize = 4; + Output = 0; + filename.assign(f); + stacksize = cellsize * 4096; + Init(); } void Compiler::Load(std::string &f) @@ -77,13 +82,241 @@ void Compiler::Init() InitOpcodes(); } +int Compiler::CipCount() +{ + std::vector::iterator i; + std::vector::iterator j; + int cipc = 0; + + for (i=CodeList.begin(); i!=CodeList.end(); i++) + { + cipc+=cellsize; + for (j=(*i)->params.begin(); j!=(*i)->params.end(); j++) + { + cipc+=cellsize; + } + } + + return cipc; +} + +bool Compiler::Compile() +{ + if (CodeList.size() < 1 || !CError || CError->GetStatus() >= Err_Error) + { + return false; + } + + int32_t fileSize = 0; + int16_t magic = AMX_MAGIC; + char file_version = CUR_FILE_VERSION; + char amx_version = MIN_AMX_VERSION; + int16_t flags = 0; + int16_t defsize = 8; + int32_t cod, dat, hea, stp, cip, publics, natives, libraries; + int32_t pubvars, tags, names; + int hdrEnd = sizeof(AMX_HEADER); + + std::vector ProcList; + std::vector::iterator pl; + std::vector NativeList; + std::vector::iterator nl; + std::map NameMap; + + /* Tables */ + std::vector Nametbl; + std::vector PublicsTable; + std::vector NativesTable; + std::vector::iterator ai; + std::vector::iterator nt; + + PROC->GetPublics(ProcList); + CNatives->GetNatives(NativeList); + + /* The only way I see to do this is to build the nametable first. + */ + + /* Public table starts right after the header */ + publics = hdrEnd; + for (pl = ProcList.begin(); pl != ProcList.end(); pl++) + { + NameRecord n; + 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 = Nametbl.size(); + Nametbl.push_back(n); + PublicsTable.push_back(a); + } + + natives = publics + (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(); + Nametbl.push_back(n); + NativesTable.push_back(a); + } + + libraries = natives + (NativesTable.size() * (sizeof(int32_t) * 2)); + pubvars = libraries; + tags = pubvars; + names = tags; + + /* Fill out the tables */ + int cOffset = names + sizeof(int16_t); + int16_t nameHdr = 0x1F; + for (ai = PublicsTable.begin(); ai != PublicsTable.end(); ai++) + { + int off = (*ai).offset; + NameMap[cOffset] = off; + (*ai).offset = cOffset; + cOffset += 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; + } + + cod = cOffset; + dat = cod + CipCount(); + hea = dat + DAT->GetSize(); + stp = hea + stacksize; + int16_t cipHdr = 0x00; + cip = -1; + fileSize = hea; + + std::string amxname; + amxname.assign(filename); + int pos = amxname.find(".asm"); + if (pos != std::string::npos) + { + amxname.replace(pos, 4, ".amx"); + } else { + amxname.append(".amx"); + } + + FILE *fp = fopen(amxname.c_str(), "wb"); + + fwrite((void*)&fileSize, sizeof(int32_t), 1, fp); + fwrite((void*)&magic, sizeof(int16_t), 1, fp); + fwrite((void*)&file_version, sizeof(char), 1, fp); + fwrite((void*)&amx_version, sizeof(char), 1, fp); + fwrite((void*)&flags, sizeof(int16_t), 1, fp); + fwrite((void*)&defsize, sizeof(int16_t), 1, fp); + + fwrite((void*)&cod, sizeof(int32_t), 1, fp); + fwrite((void*)&dat, sizeof(int32_t), 1, fp); + fwrite((void*)&hea, sizeof(int32_t), 1, fp); + fwrite((void*)&stp, sizeof(int32_t), 1, fp); + fwrite((void*)&cip, sizeof(int32_t), 1, fp); + fwrite((void*)&publics, sizeof(int32_t), 1, fp); + fwrite((void*)&natives, sizeof(int32_t), 1, fp); + fwrite((void*)&libraries, sizeof(int32_t), 1, fp); + fwrite((void*)&pubvars, sizeof(int32_t), 1, fp); + fwrite((void*)&tags, sizeof(int32_t), 1, fp); + fwrite((void*)&names, sizeof(int32_t), 1, fp); + + for (ai = PublicsTable.begin(); ai != PublicsTable.end(); ai++) + { + fwrite((void*)&((*ai).addr), sizeof(int32_t), 1, fp); + fwrite((void*)&((*ai).offset), sizeof(int32_t), 1, fp); + } + + for (ai = NativesTable.begin(); ai != NativesTable.end(); ai++) + { + fwrite((void*)&((*ai).addr), sizeof(int32_t), 1, fp); + fwrite((void*)&((*ai).offset), sizeof(int32_t), 1, fp); + } + + fwrite((void*)&(nameHdr), sizeof(int16_t), 1, fp); + + for (ai = PublicsTable.begin(); ai != PublicsTable.end(); ai++) + { + int off = (*ai).offset; + int offs = NameMap[off]; + const char *s = Nametbl.at(offs).Name; + fwrite(s, sizeof(char), strlen(s)+1, fp); + } + + for (ai = NativesTable.begin(); ai != NativesTable.end(); ai++) + { + int off = (*ai).offset; + int offs = NameMap[off]; + const char *s = Nametbl.at(offs).Name; + fwrite(s, sizeof(char), strlen(s)+1, fp); + } + + //fwrite((void*)&cipHdr, sizeof(int16_t), 1, fp); + + /* Write the code */ + + std::vector::iterator ci; + std::vector::iterator di; + int cop = 0; + for (ci = CodeList.begin(); ci != CodeList.end(); ci++) + { + cop = (*ci)->op; + fwrite((void *)&cop, sizeof(int32_t), 1, fp); + for (di = (*ci)->params.begin(); di != (*ci)->params.end(); di++) + { + cop = (*di); + fwrite((void *)&cop, sizeof(int32_t), 1, fp); + } + } + + std::vector dm; + std::vector::iterator dmi; + DAT->GetData(dm); + + int val = 0; + const char *s = 0; + for (dmi = dm.begin(); dmi != dm.end(); dmi++) + { + if ( (*dmi)->e.GetType() == Val_Number ) + { + 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); + } + } + } + + fclose(fp); + + return true; +} + +void Compiler::Clear() +{ + DAT->Clear(); + CDefines->Clear(); + CMacros->Clear(); + CLabels->Clear(); + CNatives->Clear(); + PROC->Clear(); + CSymbols->Clear(); +} + bool Compiler::Parse() { std::ifstream fp(filename.c_str()); char buffer[256] = {0}; curLine = 0; AsmSection sec = Asm_None; - lastCip = -1; + lastCip = 0-cellsize; if (!fp.is_open()) { @@ -157,7 +390,7 @@ bool Compiler::Parse() SymbolList::Symbol *S = NULL; if ((S = CSymbols->FindSymbol(symbol)) != NULL) { - CError->ErrorMsg(Err_Symbol_Reuse, symbol.c_str(), S->GetLine()); + CError->ErrorMsg(Err_Symbol_Reuse, symbol.c_str(), S->line); continue; } @@ -174,7 +407,7 @@ bool Compiler::Parse() /* Add into the DAT section */ DAT->Add(symbol, e, (fmt.compare("db")==0)?true:false); - CSymbols->AddSymbol(symbol.c_str(), Sym_Dat, CurLine()); + CSymbols->AddSymbol(symbol, Sym_Dat, CurLine()); } else if (sec == Asm_Public) { if (!IsValidSymbol(line)) { @@ -187,9 +420,9 @@ bool Compiler::Parse() CError->ErrorMsg(Err_Unknown_Symbol, line.c_str()); continue; } - if ( (S->GetType() != Sym_Proc) ) + if ( (S->type != Sym_Proc) ) { - CError->ErrorMsg(Err_Symbol_Type, Sym_Proc, S->GetType()); + CError->ErrorMsg(Err_Symbol_Type, Sym_Proc, S->type); continue; } if (!PROC->SetPublic(line)) @@ -206,10 +439,10 @@ bool Compiler::Parse() SymbolList::Symbol *S = NULL; if ( (S = CSymbols->FindSymbol(line)) != NULL) { - CError->ErrorMsg(Err_Invalid_Symbol, line.c_str(), S->GetLine()); + CError->ErrorMsg(Err_Invalid_Symbol, line.c_str(), S->line); continue; } - S = CSymbols->AddSymbol(line.c_str(), Sym_Native, CurLine()); + S = CSymbols->AddSymbol(line, Sym_Native, CurLine()); CNatives->AddNative(S); } else if (sec == Asm_Code) { std::string code; @@ -229,15 +462,16 @@ bool Compiler::Parse() /* Check if the symbol is already used */ if ( (S = CSymbols->FindSymbol(params)) != NULL) { - CError->ErrorMsg(Err_Invalid_Symbol, params.c_str(), S->GetLine()); + CError->ErrorMsg(Err_Invalid_Symbol, params.c_str(), S->line); continue; } /* Create instruction */ Asm *ASM = new Asm; - ASM->cip = ++lastCip; + ASM->cip = lastCip + cellsize; ASM->op = OpCodes["proc"]; + lastCip += cellsize; /* Add symbol */ - S = CSymbols->AddSymbol(params.c_str(), Sym_Proc, CurLine()); + S = CSymbols->AddSymbol(params, Sym_Proc, CurLine()); /* Add to code list */ CodeList.push_back(ASM); /* Add to PROC list */ @@ -255,11 +489,11 @@ 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->GetLine()); + CError->ErrorMsg(Err_Invalid_Symbol, code.c_str(), S->line); continue; } - S = CSymbols->AddSymbol(code.c_str(), Sym_Label, CurLine()); - CLabels->AddLabel(S, lastCip+1); + S = CSymbols->AddSymbol(code, Sym_Label, CurLine()); + CLabels->AddLabel(S, lastCip+cellsize); } else { /* Check if there is a valid opcode */ int op = OpCodes[code]; @@ -283,8 +517,9 @@ bool Compiler::Parse() } } - ASM->cip = ++lastCip; + ASM->cip = (lastCip+cellsize); ASM->op = op; + lastCip += cellsize; switch (op) { @@ -1072,8 +1307,10 @@ bool Compiler::Parse() CodeList.push_back(ASM); } /* Asm_Code */ } /* Section If */ - } - } + } /* Line processing */ + } /* While */ + + CError->PrintReport(); return true; } @@ -1432,7 +1669,7 @@ void Compiler::ProcessDirective(std::string &text) SymbolList::Symbol *S; if ((S = CSymbols->FindSymbol(symbol)) != NULL) { - CError->ErrorMsg(Err_SymbolRedef, curLine, S->GetSymbol(), S->GetLine()); + CError->ErrorMsg(Err_SymbolRedef, curLine, S->sym.c_str(), S->line); } /* Store the argstring, which is the rest of the data */ std::string argstring; @@ -1455,7 +1692,7 @@ void Compiler::ProcessDirective(std::string &text) } CMacros->AddMacroEnd(m); /* Make sure to add the symbol */ - CSymbols->AddSymbol(symbol.c_str(), Sym_Macro, curLine); + CSymbols->AddSymbol(symbol, Sym_Macro, curLine); //TODO: ClearList(ArgList); } } else if (!directive.compare("stacksize")) { @@ -1467,11 +1704,11 @@ void Compiler::ProcessDirective(std::string &text) SymbolList::Symbol *S; if ((S = CSymbols->FindSymbol(symbol)) != NULL) { - CError->ErrorMsg(Err_SymbolRedef, curLine, S->GetSymbol(), S->GetLine()); + CError->ErrorMsg(Err_SymbolRedef, curLine, S->sym.c_str(), S->line); } if (def.size() < 1) def.assign("1"); - CSymbols->AddSymbol(symbol.c_str(), Sym_Define, curLine); + CSymbols->AddSymbol(symbol, Sym_Define, curLine); CDefines->AddDefine(symbol, def); } } @@ -1531,13 +1768,13 @@ int Compiler::Eval(std::string &str, SymbolType sym) assert(0); return 0; } - if (sym != Sym_Dat && S->GetType() != sym) + if (sym != Sym_Dat && S->type != sym) { assert(0); CError->ErrorMsg(Err_Invalid_Symbol); return 0; } - switch (S->GetType()) + switch (S->type) { case Sym_Proc: { @@ -1624,13 +1861,13 @@ int Compiler::Eval(std::string &str, SymbolType sym) assert(0); return 0; } - if (sym != Sym_Dat && S->GetType() != sym) + if (sym != Sym_Dat && S->type != sym) { assert(0); CError->ErrorMsg(Err_Invalid_Symbol); return 0; } - switch (S->GetType()) + switch (S->type) { case Sym_Proc: { @@ -1712,13 +1949,13 @@ int Compiler::Eval(std::string &str, SymbolType sym) assert(0); return 0; } - if (sym != Sym_Dat && S->GetType() != sym) + if (sym != Sym_Dat && S->type != sym) { assert(0); CError->ErrorMsg(Err_Invalid_Symbol); return 0; } - switch (S->GetType()) + switch (S->type) { case Sym_Proc: { @@ -1810,13 +2047,13 @@ int Compiler::Eval(std::string &str, SymbolType sym) assert(0); return 0; } - if (sym != Sym_Dat && S->GetType() != sym) + if (sym != Sym_Dat && S->type != sym) { assert(0); CError->ErrorMsg(Err_Invalid_Symbol); return 0; } - switch (S->GetType()) + switch (S->type) { case Sym_Proc: { diff --git a/compiler/scasm/amx_compiler.h b/compiler/scasm/amx_compiler.h index 5e562d26..a0e9f68f 100755 --- a/compiler/scasm/amx_compiler.h +++ b/compiler/scasm/amx_compiler.h @@ -37,7 +37,7 @@ if (paramList.size() >= n) \ { \ ASM->params.push_back(Eval(*(paramList[n-1]), sym)); \ - lastCip++; \ + lastCip+=cellsize; \ } typedef enum @@ -80,6 +80,8 @@ public: void PrintCodeList(); public: int FindArguments(std::string &text, std::vector &List, int &end, bool simple = false); + void Clear(); + int CipCount(); private: void ProcessDirective(std::string &text); void Init(); @@ -91,6 +93,7 @@ private: private: std::vector CodeList; std::map OpCodes; + char *Output; ErrorMngr *CError; SymbolList *CSymbols; DefineMngr *CDefines; @@ -103,6 +106,7 @@ private: int curLine; int lastCip; int cellsize; + int stacksize; }; #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 a9c2fb21..1fdda0ce 100755 --- a/compiler/scasm/amx_data.cpp +++ b/compiler/scasm/amx_data.cpp @@ -23,6 +23,11 @@ #include "amxasm.h" DataMngr::~DataMngr() +{ + Clear(); +} + +void DataMngr::Clear() { std::vector::iterator i; @@ -48,6 +53,9 @@ void DataMngr::Add(std::string &s, CExpr &expr, bool db) D->symbol.assign(s); D->e = expr; + int size = ((D->e.GetType() == Val_Number) ? + cellsize : D->e.Size() * cellsize); + if (List.size() == 0) { D->offset = 0; @@ -58,6 +66,8 @@ void DataMngr::Add(std::string &s, CExpr &expr, bool db) cellsize : p->e.Size() * cellsize); } + cursize += size; + List.push_back(D); } @@ -86,4 +96,19 @@ int DataMngr::GetOffset(std::string &sym) return DataMngr::nof; return D->offset; +} + +int DataMngr::GetSize() +{ + return cursize; +} + +void DataMngr::GetData(std::vector &dList) +{ + std::vector::iterator i; + + for (i=List.begin(); i!=List.end(); i++) + { + dList.push_back( (*i) ); + } } \ No newline at end of file diff --git a/compiler/scasm/amx_data.h b/compiler/scasm/amx_data.h index 522fbdaf..cc559b86 100755 --- a/compiler/scasm/amx_data.h +++ b/compiler/scasm/amx_data.h @@ -37,17 +37,21 @@ public: }; public: ~DataMngr(); - DataMngr() { cellsize = 4; lastOffset = 0; } - DataMngr(int cell) { lastOffset = 0; cellsize = cell; } + 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); DataMngr::Datum *FindData(std::string &sym); + void GetData(std::vector &dList); int GetOffset(std::string &sym); + int GetSize(); + void Clear(); private: std::vector List; int lastOffset; int cellsize; + int cursize; public: static const int nof = -1; }; -#endif //_INCLUDE_AMXDATA_H \ No newline at end of file +#endif //_INCLUDE_AMXDATA_H diff --git a/compiler/scasm/amx_define.cpp b/compiler/scasm/amx_define.cpp index 10ecb318..d00beae4 100755 --- a/compiler/scasm/amx_define.cpp +++ b/compiler/scasm/amx_define.cpp @@ -23,6 +23,11 @@ #include "amxasm.h" DefineMngr::~DefineMngr() +{ + Clear(); +} + +void DefineMngr::Clear() { std::vector::iterator i; diff --git a/compiler/scasm/amx_define.h b/compiler/scasm/amx_define.h index eabf8f35..5acc89ee 100755 --- a/compiler/scasm/amx_define.h +++ b/compiler/scasm/amx_define.h @@ -40,6 +40,7 @@ private: std::vector List; public: ~DefineMngr(); + void Clear(); DefineMngr::Define *AddDefine(std::string &sym, std::string &def); DefineMngr::Define *FindDefine(std::string &sym); void SearchAndReplace(std::string &text); diff --git a/compiler/scasm/amx_error.cpp b/compiler/scasm/amx_error.cpp index d41128c4..3687f201 100755 --- a/compiler/scasm/amx_error.cpp +++ b/compiler/scasm/amx_error.cpp @@ -25,7 +25,17 @@ ErrorMngr::ErrorMngr() { printf("Not instantiated with a compiler."); - exit(0); + Cmp = NULL; + assert(Cmp); +} + +void ErrorMngr::Clear() +{ + Totals[0] = 0; + Totals[1] = 0; + Totals[2] = 0; + Totals[3] = 0; + HighestError = Err_None; } ErrorMngr::ErrorMngr(void *c) @@ -36,6 +46,7 @@ ErrorMngr::ErrorMngr(void *c) Totals[1] = 0; Totals[2] = 0; Totals[3] = 0; + HighestError = Err_None; } ErrorType ErrorMngr::GetErrorType(ErrorCode id) @@ -82,8 +93,21 @@ void ErrorMngr::DefineErrors() List.at(Err_MacroParamCount) = "Parameter count for macro \"%s\" incorrect"; List.at(Err_FatalTokenError) = "Fatal token error encountered"; List.at(Err_Invalid_Section) = "Section identifier \"%s\" is not valid, ignoring section."; +} - HighestError = Err_None; +void ErrorMngr::PrintReport() +{ + static char *ErrorSwi[4] = {"Notice", "Warning", "Error", "Fatal Error"}; + int i = 0; + + printf("+---------------------------+\n"); + + for (i=0; i<4; i++) + { + printf("| %ss: %s%d |\n", ErrorSwi[i], (i!=3)?"\t\t":"\t", Totals[i]); + } + + printf("+---------------------------+\n"); } void ErrorMngr::ErrorMsg(ErrorCode error, ...) diff --git a/compiler/scasm/amx_error.h b/compiler/scasm/amx_error.h index 032e3a4f..b78faa0c 100755 --- a/compiler/scasm/amx_error.h +++ b/compiler/scasm/amx_error.h @@ -87,8 +87,10 @@ private: public: ErrorMngr(); ErrorMngr(void *c); + void Clear(); void ErrorMsg(ErrorCode error, ...); ErrorType GetStatus() { return HighestError; } + void PrintReport(); }; #endif //_INCLUDE_AMX_ERROR diff --git a/compiler/scasm/amx_label.cpp b/compiler/scasm/amx_label.cpp index 53715f8f..ca38f209 100755 --- a/compiler/scasm/amx_label.cpp +++ b/compiler/scasm/amx_label.cpp @@ -24,6 +24,11 @@ LabelMngr::~LabelMngr() { + Clear(); +} + +void LabelMngr::Clear() +{ std::vector::iterator i; for (i=List.begin(); i!=List.end(); i++) diff --git a/compiler/scasm/amx_label.h b/compiler/scasm/amx_label.h index ca1ebff4..4a033c37 100755 --- a/compiler/scasm/amx_label.h +++ b/compiler/scasm/amx_label.h @@ -37,10 +37,11 @@ public: void AddLabel(SymbolList::Symbol *sym, int cip); LabelMngr::Label *FindLabel(std::string &sym); int GetCip(std::string &sym); + void Clear(); private: std::vector List; public: static const int ncip = -1; }; -#endif //_INCLUDE_AMXLABEL_H \ No newline at end of file +#endif //_INCLUDE_AMXLABEL_H diff --git a/compiler/scasm/amx_macro.cpp b/compiler/scasm/amx_macro.cpp index dee4be92..59c5160d 100755 --- a/compiler/scasm/amx_macro.cpp +++ b/compiler/scasm/amx_macro.cpp @@ -23,6 +23,11 @@ #include "amxasm.h" MacroList::~MacroList() +{ + Clear(); +} + +void MacroList::Clear() { std::vector::iterator i; diff --git a/compiler/scasm/amx_macro.h b/compiler/scasm/amx_macro.h index 029a6859..3e04fdbc 100755 --- a/compiler/scasm/amx_macro.h +++ b/compiler/scasm/amx_macro.h @@ -40,6 +40,7 @@ public: MacroList(); MacroList(void *c); ~MacroList(); + void Clear(); MacroList::Macro *AddMacroBegin(std::string &symbol, std::string &mac); void AddMacroArgument(MacroList::Macro *m, std::string &arg); void AddMacroEnd(MacroList::Macro *m); diff --git a/compiler/scasm/amx_nametable.h b/compiler/scasm/amx_nametable.h new file mode 100755 index 00000000..97ee85a3 --- /dev/null +++ b/compiler/scasm/amx_nametable.h @@ -0,0 +1,40 @@ +/* AMX Assembler + * Copyright (C)2004 David "BAILOPAN" Anderson + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * Version: $Id$ + */ + +#ifndef _INCLUDE_NAMETABLE_H +#define _INCLUDE_NAMETABLE_H + +class NameRecord +{ +public: + const char *Name; + int32_t offset; +}; + +class AddrTable +{ +public: + int32_t addr; + int32_t offset; +}; + +#endif //_INCLUDE_NAMETABLE_H \ No newline at end of file diff --git a/compiler/scasm/amx_natives.cpp b/compiler/scasm/amx_natives.cpp index 2b5ce754..6c369ce7 100755 --- a/compiler/scasm/amx_natives.cpp +++ b/compiler/scasm/amx_natives.cpp @@ -23,6 +23,11 @@ #include "amxasm.h" NativeMngr::~NativeMngr() +{ + Clear(); +} + +void NativeMngr::Clear() { std::vector::iterator i; @@ -75,4 +80,14 @@ NativeMngr::Native *NativeMngr::FindNative(std::string &sym) } return NULL; +} + +void NativeMngr::GetNatives(std::vector &nList) +{ + std::vector::iterator i; + + for (i=List.begin(); i!=List.end(); i++) + { + nList.push_back( (*i) ); + } } \ No newline at end of file diff --git a/compiler/scasm/amx_natives.h b/compiler/scasm/amx_natives.h index bb6d6715..653dc90e 100755 --- a/compiler/scasm/amx_natives.h +++ b/compiler/scasm/amx_natives.h @@ -36,8 +36,10 @@ public: public: ~NativeMngr(); void AddNative(SymbolList::Symbol *S); + void Clear(); NativeMngr::Native *FindNative(std::string &sym); int GetNativeId(std::string &sym); + void GetNatives(std::vector &nList); public: static const int ncip = -1; private: diff --git a/compiler/scasm/amx_proc.cpp b/compiler/scasm/amx_proc.cpp index 085f8968..732d1ed0 100755 --- a/compiler/scasm/amx_proc.cpp +++ b/compiler/scasm/amx_proc.cpp @@ -23,6 +23,11 @@ #include "amxasm.h" ProcMngr::~ProcMngr() +{ + Clear(); +} + +void ProcMngr::Clear() { std::vector::iterator i; diff --git a/compiler/scasm/amx_proc.h b/compiler/scasm/amx_proc.h index 2704f077..4a58d8d7 100755 --- a/compiler/scasm/amx_proc.h +++ b/compiler/scasm/amx_proc.h @@ -40,10 +40,11 @@ public: int GetCip(std::string &sym); bool SetPublic(std::string &sym); void GetPublics(std::vector &pbList); + void Clear(); private: std::vector List; public: static const int ncip = -1; }; -#endif //_INCLUDE_AMXPROC_H \ No newline at end of file +#endif //_INCLUDE_AMXPROC_H diff --git a/compiler/scasm/amx_symbol.cpp b/compiler/scasm/amx_symbol.cpp index 289932aa..40c9fe4f 100755 --- a/compiler/scasm/amx_symbol.cpp +++ b/compiler/scasm/amx_symbol.cpp @@ -51,7 +51,7 @@ bool IsValidSymbol(std::string &text) return true; } -SymbolList::~SymbolList() +void SymbolList::Clear() { std::vector::iterator i; @@ -64,23 +64,38 @@ SymbolList::~SymbolList() List.clear(); } -SymbolList::Symbol::Symbol(SymbolType t, const char *s, int l) +SymbolList::~SymbolList() { - line = l; - sym.assign(s); - type = t; + Clear(); } -int SymbolList::Symbol::IsEqual(std::string &s) +bool SymbolList::Symbol::IsEqual(std::string &s) { return (sym.compare(s)==0); } -SymbolList::Symbol *SymbolList::AddSymbol(const char *s, SymbolType type, int line) +SymbolList::Symbol* SymbolList::AddSymbol(const char *szSym, SymbolType type, int line) { - Symbol *sym = new Symbol(type, s, line); - List.push_back(sym); - return sym; + SymbolList::Symbol *S = new SymbolList::Symbol; + + S->line = line; + S->type = type; + S->sym.assign(szSym); + + List.push_back(S); + return S; +} + +SymbolList::Symbol *SymbolList::AddSymbol(std::string &sym, SymbolType type, int line) +{ + SymbolList::Symbol *S = new SymbolList::Symbol; + + S->line = line; + S->type = type; + S->sym.assign(sym); + + List.push_back(S); + return S; } SymbolList::Symbol* SymbolList::FindSymbol(std::string &sym) @@ -100,6 +115,6 @@ void SymbolList::PrintTable() std::vector::iterator i; for (i=List.begin(); i!=List.end(); i++) { - printf("Symbol \"%s\" defined on line %d\n", (*i)->GetSymbol(), (*i)->GetLine()); + printf("Symbol \"%s\" defined on line %d\n", (*i)->sym.c_str(), (*i)->line); } -} \ No newline at end of file +} diff --git a/compiler/scasm/amx_symbol.h b/compiler/scasm/amx_symbol.h index 3fff7f0a..3b7cb2b7 100755 --- a/compiler/scasm/amx_symbol.h +++ b/compiler/scasm/amx_symbol.h @@ -43,12 +43,7 @@ public: class Symbol { public: - Symbol(SymbolType t, const char *s, int l); - const char *GetSymbol() { return sym.c_str(); } - SymbolType GetType() { return type; } - int GetLine() { return line; } - int IsEqual(std::string &s); - private: + bool IsEqual(std::string &s); SymbolType type; std::string sym; int line; @@ -56,9 +51,11 @@ public: public: ~SymbolList(); - SymbolList::Symbol* AddSymbol(const char *s, SymbolType type, int line); + SymbolList::Symbol* AddSymbol(std::string &sym, SymbolType type, int line); + SymbolList::Symbol* AddSymbol(const char *szSym, SymbolType type, int line); SymbolList::Symbol* FindSymbol(std::string &sym); void PrintTable(); + void Clear(); private: std::vector List; }; diff --git a/compiler/scasm/amxasm.cpp b/compiler/scasm/amxasm.cpp index 7f1a5d9d..78a5e01f 100755 --- a/compiler/scasm/amxasm.cpp +++ b/compiler/scasm/amxasm.cpp @@ -35,7 +35,7 @@ int main(int argc, char **argv) Program.Load(filename); Program.Parse(); - Program.PrintCodeList(); + Program.Compile(); exit(0); } diff --git a/compiler/scasm/amxasm.h b/compiler/scasm/amxasm.h index 0282c10e..052d49b9 100755 --- a/compiler/scasm/amxasm.h +++ b/compiler/scasm/amxasm.h @@ -57,6 +57,7 @@ public: #include "amx_proc.h" #include "amx_label.h" #include "amx_natives.h" +#include "amx_nametable.h" #include "amx_compiler.h" //This should be last! #define SMALL_CELL_SIZE 32 diff --git a/compiler/scasm/assembler.vcproj b/compiler/scasm/assembler.vcproj index 6f5a2e0e..332e6f3b 100755 --- a/compiler/scasm/assembler.vcproj +++ b/compiler/scasm/assembler.vcproj @@ -174,6 +174,9 @@ + + diff --git a/compiler/scasm/cexpr.cpp b/compiler/scasm/cexpr.cpp index 8007a3d2..a92ca6f1 100755 --- a/compiler/scasm/cexpr.cpp +++ b/compiler/scasm/cexpr.cpp @@ -235,6 +235,9 @@ cExprType CExpr::Evaluate() } else { /* STRING DISCOVERED */ t = Val_String; + /* Erase literals */ + data.erase(0, 1); + data.erase(data.size()-1, 1); numVal = (int)(data.size()+1); break; } diff --git a/compiler/scasm/cexpr.h b/compiler/scasm/cexpr.h index b72d5eec..b27666d0 100755 --- a/compiler/scasm/cexpr.h +++ b/compiler/scasm/cexpr.h @@ -68,4 +68,4 @@ private: ErrorMngr *CError; }; -#endif //_INCLUDE_CEXPR_H \ No newline at end of file +#endif //_INCLUDE_CEXPR_H diff --git a/compiler/scasm/plugin.asm b/compiler/scasm/plugin.asm new file mode 100755 index 00000000..7db0ed2e --- /dev/null +++ b/compiler/scasm/plugin.asm @@ -0,0 +1,79 @@ +;(C)2004 David "BAILOPAN" Anderson +; Demonstration of AMX Mod X plugin writing in assembly. +#define VERSION "1.00" +#define AUTHOR "BAILOPAN" +#define PLUGIN "Asm Test" +#define CELL 4 +#macro ARGN(argc) (12+(argc*CELL)) + +.CODE + halt 0 ;Return point for end + +.NATIVE + get_user_name + register_plugin + register_concmd + server_print + +.DATA +Plugin db PLUGIN +Version db VERSION +Author db AUTHOR +Cmd db "amx_asmtest" +Callback db "cmdCallback" +Descr db "Test" + +.CODE +;Technically PROC could simply be "proc" +; this is more for reasons of readability. +; feel free to use "proc" and omit ENDP +; if you would like to code one huge list of instructions. +PROC plugin_init + push.c Author ;push the plugin name + push.c Version ;push the plugin version + push.c Plugin ;push the plugin author + push.c CELL*3 ;push 3 arguments + sysreq.c register_plugin ;call register_plugin + stack CELL*4 ;clean up the stack + push.c Callback ;push string + push.c CELL ;push one argument + sysreq.c server_print ;call server_print + stack CELL*2 ;clean up the stack + push.c Descr ;push the description + push.c 0 ;push the access level + push.c Callback ;push callback + push.c Cmd ;push the command + push.c CELL*4 ;push 4 arguments + sysreq.c register_concmd ;call register_concmd + stack CELL*5 ;cleanup + retn ;return + cleanup +ENDP + +.DATA +HELLO db "Hello, %s!" + +.CODE +PROC cmdCallback + stack -128*CELL ;new memory + zero.pri ;zero out pri + addr.alt -128 ;alt points to new variable + fill -128*CELL ;zero out new variable + push.c 127 ;push bytecount arg to get_user_name + push.alt ;push the value of alt (which is name) + push.s ARG(1) ;push the first argument onto the stack + push.c 3*CELL ;push 3 arguments + sysreq.c get_user_name ;call get_user_name(); + stack 4*CELL ;clean up stack + pushaddr -128 ;push the name + push.c HELLO ;push the message + push.c 2*CELL ;push 2 arguments + sysreq.c server_print ;call server_print + stack 3*CELL ;clean up the stack + stack 128*CELL ;clean up the name variable + zero.pri ;zero out pri + retn +ENDP + +.PUBLIC + cmdCallback + plugin_init \ No newline at end of file