Fixed some more bugs, added #if/#else/#endif and more opcodes, and .DATA stat

This commit is contained in:
David Anderson 2004-08-09 05:23:32 +00:00
parent 1dc16b835e
commit b14708d6f2
9 changed files with 215 additions and 51 deletions

View File

@ -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;
@ -279,6 +290,8 @@ bool Compiler::Compile()
int val = 0;
const char *s = 0;
for (dmi = dm.begin(); dmi != dm.end(); dmi++)
{
if ( (*dmi)->db )
{
if ( (*dmi)->e.GetType() == Val_Number )
{
@ -292,6 +305,13 @@ bool Compiler::Compile()
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);
}
}
}
fclose(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;
@ -333,8 +354,66 @@ bool Compiler::Parse()
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 */
@ -400,13 +479,35 @@ bool Compiler::Parse()
continue;
}
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, (fmt.compare("db")==0)?true:false);
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:

View File

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

View File

@ -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) ?
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];
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;

View File

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

View File

@ -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\"";

View File

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

View File

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

View File

@ -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);
}

View File

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