Added bytecode output.

This commit is contained in:
David Anderson 2004-08-08 10:15:08 +00:00
parent 023f9b43ea
commit 7b111a179e
25 changed files with 534 additions and 59 deletions

View File

@ -26,11 +26,14 @@ Compiler::Compiler()
{ {
curLine = -1; curLine = -1;
cellsize = 4; cellsize = 4;
Output = 0;
stacksize = cellsize * 4096;
Init(); Init();
} }
Compiler::~Compiler() Compiler::~Compiler()
{ {
Clear();
delete CDefines; delete CDefines;
delete CError; delete CError;
delete CLabels; delete CLabels;
@ -43,10 +46,12 @@ Compiler::~Compiler()
Compiler::Compiler(std::string &f) Compiler::Compiler(std::string &f)
{ {
Init();
filename.assign(f);
curLine = -1; curLine = -1;
cellsize = 4; cellsize = 4;
Output = 0;
filename.assign(f);
stacksize = cellsize * 4096;
Init();
} }
void Compiler::Load(std::string &f) void Compiler::Load(std::string &f)
@ -77,13 +82,241 @@ void Compiler::Init()
InitOpcodes(); InitOpcodes();
} }
int Compiler::CipCount()
{
std::vector<Asm *>::iterator i;
std::vector<int>::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<ProcMngr::AsmProc *> ProcList;
std::vector<ProcMngr::AsmProc *>::iterator pl;
std::vector<NativeMngr::Native *> NativeList;
std::vector<NativeMngr::Native *>::iterator nl;
std::map<int,int> NameMap;
/* Tables */
std::vector<NameRecord> Nametbl;
std::vector<AddrTable> PublicsTable;
std::vector<AddrTable> NativesTable;
std::vector<AddrTable>::iterator ai;
std::vector<NameRecord>::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<Asm *>::iterator ci;
std::vector<int>::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<DataMngr::Datum *> dm;
std::vector<DataMngr::Datum *>::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() bool Compiler::Parse()
{ {
std::ifstream fp(filename.c_str()); std::ifstream fp(filename.c_str());
char buffer[256] = {0}; char buffer[256] = {0};
curLine = 0; curLine = 0;
AsmSection sec = Asm_None; AsmSection sec = Asm_None;
lastCip = -1; lastCip = 0-cellsize;
if (!fp.is_open()) if (!fp.is_open())
{ {
@ -157,7 +390,7 @@ bool Compiler::Parse()
SymbolList::Symbol *S = NULL; SymbolList::Symbol *S = NULL;
if ((S = CSymbols->FindSymbol(symbol)) != 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; continue;
} }
@ -174,7 +407,7 @@ bool Compiler::Parse()
/* Add into the DAT section */ /* Add into the DAT section */
DAT->Add(symbol, e, (fmt.compare("db")==0)?true:false); 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) { } else if (sec == Asm_Public) {
if (!IsValidSymbol(line)) if (!IsValidSymbol(line))
{ {
@ -187,9 +420,9 @@ bool Compiler::Parse()
CError->ErrorMsg(Err_Unknown_Symbol, line.c_str()); CError->ErrorMsg(Err_Unknown_Symbol, line.c_str());
continue; 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; continue;
} }
if (!PROC->SetPublic(line)) if (!PROC->SetPublic(line))
@ -206,10 +439,10 @@ bool Compiler::Parse()
SymbolList::Symbol *S = NULL; SymbolList::Symbol *S = NULL;
if ( (S = CSymbols->FindSymbol(line)) != 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; continue;
} }
S = CSymbols->AddSymbol(line.c_str(), Sym_Native, CurLine()); S = CSymbols->AddSymbol(line, Sym_Native, CurLine());
CNatives->AddNative(S); CNatives->AddNative(S);
} else if (sec == Asm_Code) { } else if (sec == Asm_Code) {
std::string code; std::string code;
@ -229,15 +462,16 @@ bool Compiler::Parse()
/* 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->GetLine()); CError->ErrorMsg(Err_Invalid_Symbol, params.c_str(), S->line);
continue; continue;
} }
/* Create instruction */ /* Create instruction */
Asm *ASM = new Asm; Asm *ASM = new Asm;
ASM->cip = ++lastCip; ASM->cip = lastCip + cellsize;
ASM->op = OpCodes["proc"]; ASM->op = OpCodes["proc"];
lastCip += cellsize;
/* Add symbol */ /* Add symbol */
S = CSymbols->AddSymbol(params.c_str(), Sym_Proc, CurLine()); S = CSymbols->AddSymbol(params, Sym_Proc, CurLine());
/* Add to code list */ /* Add to code list */
CodeList.push_back(ASM); CodeList.push_back(ASM);
/* Add to PROC list */ /* Add to PROC list */
@ -255,11 +489,11 @@ bool Compiler::Parse()
/* Check if the symbol is already used */ /* Check if the symbol is already used */
if ( (S = CSymbols->FindSymbol(code)) != NULL) 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; continue;
} }
S = CSymbols->AddSymbol(code.c_str(), Sym_Label, CurLine()); S = CSymbols->AddSymbol(code, Sym_Label, CurLine());
CLabels->AddLabel(S, lastCip+1); 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];
@ -283,8 +517,9 @@ bool Compiler::Parse()
} }
} }
ASM->cip = ++lastCip; ASM->cip = (lastCip+cellsize);
ASM->op = op; ASM->op = op;
lastCip += cellsize;
switch (op) switch (op)
{ {
@ -1072,8 +1307,10 @@ bool Compiler::Parse()
CodeList.push_back(ASM); CodeList.push_back(ASM);
} /* Asm_Code */ } /* Asm_Code */
} /* Section If */ } /* Section If */
} } /* Line processing */
} } /* While */
CError->PrintReport();
return true; return true;
} }
@ -1432,7 +1669,7 @@ void Compiler::ProcessDirective(std::string &text)
SymbolList::Symbol *S; SymbolList::Symbol *S;
if ((S = CSymbols->FindSymbol(symbol)) != NULL) 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 */ /* Store the argstring, which is the rest of the data */
std::string argstring; std::string argstring;
@ -1455,7 +1692,7 @@ void Compiler::ProcessDirective(std::string &text)
} }
CMacros->AddMacroEnd(m); CMacros->AddMacroEnd(m);
/* Make sure to add the symbol */ /* Make sure to add the symbol */
CSymbols->AddSymbol(symbol.c_str(), Sym_Macro, curLine); CSymbols->AddSymbol(symbol, Sym_Macro, curLine);
//TODO: ClearList(ArgList); //TODO: ClearList(ArgList);
} }
} else if (!directive.compare("stacksize")) { } else if (!directive.compare("stacksize")) {
@ -1467,11 +1704,11 @@ void Compiler::ProcessDirective(std::string &text)
SymbolList::Symbol *S; SymbolList::Symbol *S;
if ((S = CSymbols->FindSymbol(symbol)) != NULL) 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) if (def.size() < 1)
def.assign("1"); def.assign("1");
CSymbols->AddSymbol(symbol.c_str(), Sym_Define, curLine); CSymbols->AddSymbol(symbol, Sym_Define, curLine);
CDefines->AddDefine(symbol, def); CDefines->AddDefine(symbol, def);
} }
} }
@ -1531,13 +1768,13 @@ int Compiler::Eval(std::string &str, SymbolType sym)
assert(0); assert(0);
return 0; return 0;
} }
if (sym != Sym_Dat && S->GetType() != sym) if (sym != Sym_Dat && S->type != sym)
{ {
assert(0); assert(0);
CError->ErrorMsg(Err_Invalid_Symbol); CError->ErrorMsg(Err_Invalid_Symbol);
return 0; return 0;
} }
switch (S->GetType()) switch (S->type)
{ {
case Sym_Proc: case Sym_Proc:
{ {
@ -1624,13 +1861,13 @@ int Compiler::Eval(std::string &str, SymbolType sym)
assert(0); assert(0);
return 0; return 0;
} }
if (sym != Sym_Dat && S->GetType() != sym) if (sym != Sym_Dat && S->type != sym)
{ {
assert(0); assert(0);
CError->ErrorMsg(Err_Invalid_Symbol); CError->ErrorMsg(Err_Invalid_Symbol);
return 0; return 0;
} }
switch (S->GetType()) switch (S->type)
{ {
case Sym_Proc: case Sym_Proc:
{ {
@ -1712,13 +1949,13 @@ int Compiler::Eval(std::string &str, SymbolType sym)
assert(0); assert(0);
return 0; return 0;
} }
if (sym != Sym_Dat && S->GetType() != sym) if (sym != Sym_Dat && S->type != sym)
{ {
assert(0); assert(0);
CError->ErrorMsg(Err_Invalid_Symbol); CError->ErrorMsg(Err_Invalid_Symbol);
return 0; return 0;
} }
switch (S->GetType()) switch (S->type)
{ {
case Sym_Proc: case Sym_Proc:
{ {
@ -1810,13 +2047,13 @@ int Compiler::Eval(std::string &str, SymbolType sym)
assert(0); assert(0);
return 0; return 0;
} }
if (sym != Sym_Dat && S->GetType() != sym) if (sym != Sym_Dat && S->type != sym)
{ {
assert(0); assert(0);
CError->ErrorMsg(Err_Invalid_Symbol); CError->ErrorMsg(Err_Invalid_Symbol);
return 0; return 0;
} }
switch (S->GetType()) switch (S->type)
{ {
case Sym_Proc: case Sym_Proc:
{ {

View File

@ -37,7 +37,7 @@
if (paramList.size() >= n) \ if (paramList.size() >= n) \
{ \ { \
ASM->params.push_back(Eval(*(paramList[n-1]), sym)); \ ASM->params.push_back(Eval(*(paramList[n-1]), sym)); \
lastCip++; \ lastCip+=cellsize; \
} }
typedef enum typedef enum
@ -80,6 +80,8 @@ public:
void PrintCodeList(); void PrintCodeList();
public: public:
int FindArguments(std::string &text, std::vector<std::string*> &List, int &end, bool simple = false); int FindArguments(std::string &text, std::vector<std::string*> &List, int &end, bool simple = false);
void Clear();
int CipCount();
private: private:
void ProcessDirective(std::string &text); void ProcessDirective(std::string &text);
void Init(); void Init();
@ -91,6 +93,7 @@ private:
private: private:
std::vector<Asm *> CodeList; std::vector<Asm *> CodeList;
std::map<std::string,int> OpCodes; std::map<std::string,int> OpCodes;
char *Output;
ErrorMngr *CError; ErrorMngr *CError;
SymbolList *CSymbols; SymbolList *CSymbols;
DefineMngr *CDefines; DefineMngr *CDefines;
@ -103,6 +106,7 @@ private:
int curLine; int curLine;
int lastCip; int lastCip;
int cellsize; int cellsize;
int stacksize;
}; };
#endif //_INCLUDE_AMXCOMPILER_H #endif //_INCLUDE_AMXCOMPILER_H

View File

@ -23,6 +23,11 @@
#include "amxasm.h" #include "amxasm.h"
DataMngr::~DataMngr() DataMngr::~DataMngr()
{
Clear();
}
void DataMngr::Clear()
{ {
std::vector<DataMngr::Datum *>::iterator i; std::vector<DataMngr::Datum *>::iterator i;
@ -48,6 +53,9 @@ void DataMngr::Add(std::string &s, CExpr &expr, bool db)
D->symbol.assign(s); D->symbol.assign(s);
D->e = expr; D->e = expr;
int size = ((D->e.GetType() == Val_Number) ?
cellsize : D->e.Size() * cellsize);
if (List.size() == 0) if (List.size() == 0)
{ {
D->offset = 0; D->offset = 0;
@ -58,6 +66,8 @@ void DataMngr::Add(std::string &s, CExpr &expr, bool db)
cellsize : p->e.Size() * cellsize); cellsize : p->e.Size() * cellsize);
} }
cursize += size;
List.push_back(D); List.push_back(D);
} }
@ -87,3 +97,18 @@ int DataMngr::GetOffset(std::string &sym)
return D->offset; return D->offset;
} }
int DataMngr::GetSize()
{
return cursize;
}
void DataMngr::GetData(std::vector<DataMngr::Datum *> &dList)
{
std::vector<DataMngr::Datum *>::iterator i;
for (i=List.begin(); i!=List.end(); i++)
{
dList.push_back( (*i) );
}
}

View File

@ -37,15 +37,19 @@ public:
}; };
public: public:
~DataMngr(); ~DataMngr();
DataMngr() { cellsize = 4; lastOffset = 0; } DataMngr() { cellsize = 4; lastOffset = 0; cursize = 0; }
DataMngr(int cell) { lastOffset = 0; cellsize = cell; } 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);
DataMngr::Datum *FindData(std::string &sym); DataMngr::Datum *FindData(std::string &sym);
void GetData(std::vector<DataMngr::Datum *> &dList);
int GetOffset(std::string &sym); int GetOffset(std::string &sym);
int GetSize();
void Clear();
private: private:
std::vector<DataMngr::Datum *> List; std::vector<DataMngr::Datum *> List;
int lastOffset; int lastOffset;
int cellsize; int cellsize;
int cursize;
public: public:
static const int nof = -1; static const int nof = -1;
}; };

View File

@ -23,6 +23,11 @@
#include "amxasm.h" #include "amxasm.h"
DefineMngr::~DefineMngr() DefineMngr::~DefineMngr()
{
Clear();
}
void DefineMngr::Clear()
{ {
std::vector<DefineMngr::Define *>::iterator i; std::vector<DefineMngr::Define *>::iterator i;

View File

@ -40,6 +40,7 @@ private:
std::vector<Define *> List; std::vector<Define *> List;
public: public:
~DefineMngr(); ~DefineMngr();
void Clear();
DefineMngr::Define *AddDefine(std::string &sym, std::string &def); DefineMngr::Define *AddDefine(std::string &sym, std::string &def);
DefineMngr::Define *FindDefine(std::string &sym); DefineMngr::Define *FindDefine(std::string &sym);
void SearchAndReplace(std::string &text); void SearchAndReplace(std::string &text);

View File

@ -25,7 +25,17 @@
ErrorMngr::ErrorMngr() ErrorMngr::ErrorMngr()
{ {
printf("Not instantiated with a compiler."); 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) ErrorMngr::ErrorMngr(void *c)
@ -36,6 +46,7 @@ ErrorMngr::ErrorMngr(void *c)
Totals[1] = 0; Totals[1] = 0;
Totals[2] = 0; Totals[2] = 0;
Totals[3] = 0; Totals[3] = 0;
HighestError = Err_None;
} }
ErrorType ErrorMngr::GetErrorType(ErrorCode id) 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_MacroParamCount) = "Parameter count for macro \"%s\" incorrect";
List.at(Err_FatalTokenError) = "Fatal token error encountered"; List.at(Err_FatalTokenError) = "Fatal token error encountered";
List.at(Err_Invalid_Section) = "Section identifier \"%s\" is not valid, ignoring section."; 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, ...) void ErrorMngr::ErrorMsg(ErrorCode error, ...)

View File

@ -87,8 +87,10 @@ private:
public: public:
ErrorMngr(); ErrorMngr();
ErrorMngr(void *c); ErrorMngr(void *c);
void Clear();
void ErrorMsg(ErrorCode error, ...); void ErrorMsg(ErrorCode error, ...);
ErrorType GetStatus() { return HighestError; } ErrorType GetStatus() { return HighestError; }
void PrintReport();
}; };
#endif //_INCLUDE_AMX_ERROR #endif //_INCLUDE_AMX_ERROR

View File

@ -23,6 +23,11 @@
#include "amxasm.h" #include "amxasm.h"
LabelMngr::~LabelMngr() LabelMngr::~LabelMngr()
{
Clear();
}
void LabelMngr::Clear()
{ {
std::vector<LabelMngr::Label *>::iterator i; std::vector<LabelMngr::Label *>::iterator i;

View File

@ -37,6 +37,7 @@ public:
void AddLabel(SymbolList::Symbol *sym, int cip); void 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();
private: private:
std::vector<LabelMngr::Label *> List; std::vector<LabelMngr::Label *> List;
public: public:

View File

@ -23,6 +23,11 @@
#include "amxasm.h" #include "amxasm.h"
MacroList::~MacroList() MacroList::~MacroList()
{
Clear();
}
void MacroList::Clear()
{ {
std::vector<MacroList::Macro *>::iterator i; std::vector<MacroList::Macro *>::iterator i;

View File

@ -40,6 +40,7 @@ public:
MacroList(); MacroList();
MacroList(void *c); MacroList(void *c);
~MacroList(); ~MacroList();
void Clear();
MacroList::Macro *AddMacroBegin(std::string &symbol, std::string &mac); MacroList::Macro *AddMacroBegin(std::string &symbol, std::string &mac);
void AddMacroArgument(MacroList::Macro *m, std::string &arg); void AddMacroArgument(MacroList::Macro *m, std::string &arg);
void AddMacroEnd(MacroList::Macro *m); void AddMacroEnd(MacroList::Macro *m);

40
compiler/scasm/amx_nametable.h Executable file
View File

@ -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

View File

@ -23,6 +23,11 @@
#include "amxasm.h" #include "amxasm.h"
NativeMngr::~NativeMngr() NativeMngr::~NativeMngr()
{
Clear();
}
void NativeMngr::Clear()
{ {
std::vector<NativeMngr::Native *>::iterator i; std::vector<NativeMngr::Native *>::iterator i;
@ -76,3 +81,13 @@ NativeMngr::Native *NativeMngr::FindNative(std::string &sym)
return NULL; return NULL;
} }
void NativeMngr::GetNatives(std::vector<NativeMngr::Native *> &nList)
{
std::vector<NativeMngr::Native *>::iterator i;
for (i=List.begin(); i!=List.end(); i++)
{
nList.push_back( (*i) );
}
}

View File

@ -36,8 +36,10 @@ public:
public: public:
~NativeMngr(); ~NativeMngr();
void AddNative(SymbolList::Symbol *S); void AddNative(SymbolList::Symbol *S);
void Clear();
NativeMngr::Native *FindNative(std::string &sym); NativeMngr::Native *FindNative(std::string &sym);
int GetNativeId(std::string &sym); int GetNativeId(std::string &sym);
void GetNatives(std::vector<NativeMngr::Native *> &nList);
public: public:
static const int ncip = -1; static const int ncip = -1;
private: private:

View File

@ -23,6 +23,11 @@
#include "amxasm.h" #include "amxasm.h"
ProcMngr::~ProcMngr() ProcMngr::~ProcMngr()
{
Clear();
}
void ProcMngr::Clear()
{ {
std::vector<ProcMngr::AsmProc *>::iterator i; std::vector<ProcMngr::AsmProc *>::iterator i;

View File

@ -40,6 +40,7 @@ public:
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 Clear();
private: private:
std::vector<ProcMngr::AsmProc *> List; std::vector<ProcMngr::AsmProc *> List;
public: public:

View File

@ -51,7 +51,7 @@ bool IsValidSymbol(std::string &text)
return true; return true;
} }
SymbolList::~SymbolList() void SymbolList::Clear()
{ {
std::vector<SymbolList::Symbol *>::iterator i; std::vector<SymbolList::Symbol *>::iterator i;
@ -64,23 +64,38 @@ SymbolList::~SymbolList()
List.clear(); List.clear();
} }
SymbolList::Symbol::Symbol(SymbolType t, const char *s, int l) SymbolList::~SymbolList()
{ {
line = l; Clear();
sym.assign(s);
type = t;
} }
int SymbolList::Symbol::IsEqual(std::string &s) bool SymbolList::Symbol::IsEqual(std::string &s)
{ {
return (sym.compare(s)==0); 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); SymbolList::Symbol *S = new SymbolList::Symbol;
List.push_back(sym);
return sym; 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) SymbolList::Symbol* SymbolList::FindSymbol(std::string &sym)
@ -100,6 +115,6 @@ void SymbolList::PrintTable()
std::vector<Symbol*>::iterator i; std::vector<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)->GetSymbol(), (*i)->GetLine()); printf("Symbol \"%s\" defined on line %d\n", (*i)->sym.c_str(), (*i)->line);
} }
} }

View File

@ -43,12 +43,7 @@ public:
class Symbol class Symbol
{ {
public: public:
Symbol(SymbolType t, const char *s, int l); bool IsEqual(std::string &s);
const char *GetSymbol() { return sym.c_str(); }
SymbolType GetType() { return type; }
int GetLine() { return line; }
int IsEqual(std::string &s);
private:
SymbolType type; SymbolType type;
std::string sym; std::string sym;
int line; int line;
@ -56,9 +51,11 @@ public:
public: public:
~SymbolList(); ~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); SymbolList::Symbol* FindSymbol(std::string &sym);
void PrintTable(); void PrintTable();
void Clear();
private: private:
std::vector<Symbol*> List; std::vector<Symbol*> List;
}; };

View File

@ -35,7 +35,7 @@ int main(int argc, char **argv)
Program.Load(filename); Program.Load(filename);
Program.Parse(); Program.Parse();
Program.PrintCodeList(); Program.Compile();
exit(0); exit(0);
} }

View File

@ -57,6 +57,7 @@ public:
#include "amx_proc.h" #include "amx_proc.h"
#include "amx_label.h" #include "amx_label.h"
#include "amx_natives.h" #include "amx_natives.h"
#include "amx_nametable.h"
#include "amx_compiler.h" //This should be last! #include "amx_compiler.h" //This should be last!
#define SMALL_CELL_SIZE 32 #define SMALL_CELL_SIZE 32

View File

@ -174,6 +174,9 @@
<File <File
RelativePath=".\amx_macro.h"> RelativePath=".\amx_macro.h">
</File> </File>
<File
RelativePath=".\amx_nametable.h">
</File>
<File <File
RelativePath=".\amx_natives.h"> RelativePath=".\amx_natives.h">
</File> </File>

View File

@ -235,6 +235,9 @@ cExprType CExpr::Evaluate()
} else { } else {
/* STRING DISCOVERED */ /* STRING DISCOVERED */
t = Val_String; t = Val_String;
/* Erase literals */
data.erase(0, 1);
data.erase(data.size()-1, 1);
numVal = (int)(data.size()+1); numVal = (int)(data.size()+1);
break; break;
} }

79
compiler/scasm/plugin.asm Executable file
View File

@ -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