Fixed some more bugs, added #if/#else/#endif and more opcodes, and .DATA stat
This commit is contained in:
parent
1dc16b835e
commit
b14708d6f2
@ -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<int> 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<std::string *> 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:
|
||||
|
@ -82,7 +82,9 @@ public:
|
||||
int FindArguments(std::string &text, std::vector<std::string*> &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
|
@ -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;
|
||||
|
@ -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<DataMngr::Datum *> &dList);
|
||||
int GetOffset(std::string &sym);
|
||||
|
@ -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\"";
|
||||
|
@ -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
|
||||
|
@ -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<Source.size(); i++)
|
||||
{
|
||||
if (isspace(Source[i]) && !done_flag)
|
||||
|
@ -26,21 +26,25 @@ std::string filename;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
printf("debug clamp.\n");
|
||||
getchar();
|
||||
|
||||
get_options(argc, argv);
|
||||
|
||||
Compiler Program;
|
||||
|
||||
get_options(argc, argv, Program);
|
||||
|
||||
if (filename.size() < 1)
|
||||
{
|
||||
print_version();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
Program.Load(filename);
|
||||
Program.Parse();
|
||||
Program.Compile();
|
||||
if (Program.Parse())
|
||||
if (Program.Compile())
|
||||
printf("Done.\n");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void get_options(int argc, char **argv)
|
||||
void get_options(int argc, char **argv, Compiler &Prog)
|
||||
{
|
||||
int i = 0; /* index */
|
||||
int opt_flag = 0; /* flag for option detection */
|
||||
@ -56,9 +60,15 @@ void get_options(int argc, char **argv)
|
||||
case 'v':
|
||||
{
|
||||
opt_flag = 0; /* no options expected */
|
||||
//print_version();
|
||||
print_version();
|
||||
break;
|
||||
} /* case */
|
||||
case 'd':
|
||||
{
|
||||
opt_flag = 0;
|
||||
Prog.SetDebug();
|
||||
break;
|
||||
}
|
||||
} /* switch */
|
||||
} else { /* - */
|
||||
if (!opt_flag)
|
||||
@ -70,3 +80,10 @@ void get_options(int argc, char **argv)
|
||||
} /* if */
|
||||
}
|
||||
}
|
||||
|
||||
void print_version()
|
||||
{
|
||||
printf("AMX Assembler 1.00\n");
|
||||
printf("(C)2004 David 'BAILOPAN' Anderson\n");
|
||||
exit(0);
|
||||
}
|
@ -215,8 +215,9 @@ typedef enum {
|
||||
OP_NUM_OPCODES
|
||||
} OPCODE;
|
||||
|
||||
void get_options(int argc, char **argv);
|
||||
void get_options(int argc, char **argv, Compiler &Prog);
|
||||
void InitOpcodes();
|
||||
void DestroyArgList(std::vector<std::string *> &List);
|
||||
void print_version();
|
||||
|
||||
#endif //_INCLUDE_AMXASM_H
|
||||
|
Loading…
Reference in New Issue
Block a user