mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-25 06:15:37 +03:00
Added Compact Encoding (-c)
Added second pass optimization (-h)
This commit is contained in:
parent
c9a0a3f9be
commit
81b3e662cf
@ -29,6 +29,8 @@ Compiler::Compiler()
|
|||||||
Output = 0;
|
Output = 0;
|
||||||
stacksize = cellsize * 4096;
|
stacksize = cellsize * 4096;
|
||||||
debug = false;
|
debug = false;
|
||||||
|
pack = false;
|
||||||
|
dopt = false;
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,9 +55,20 @@ Compiler::Compiler(std::string &f)
|
|||||||
filename.assign(f);
|
filename.assign(f);
|
||||||
stacksize = cellsize * 4096;
|
stacksize = cellsize * 4096;
|
||||||
debug = false;
|
debug = false;
|
||||||
|
pack = false;
|
||||||
|
dopt = false;
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Compiler::SetDOpt()
|
||||||
|
{
|
||||||
|
bool state = dopt;
|
||||||
|
|
||||||
|
dopt = dopt ? false : true;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
bool Compiler::SetDebug()
|
bool Compiler::SetDebug()
|
||||||
{
|
{
|
||||||
bool state = debug;
|
bool state = debug;
|
||||||
@ -65,6 +78,15 @@ bool Compiler::SetDebug()
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Compiler::SetPack()
|
||||||
|
{
|
||||||
|
bool state = pack;
|
||||||
|
|
||||||
|
pack = pack ? false : true;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
void Compiler::Load(std::string &f)
|
void Compiler::Load(std::string &f)
|
||||||
{
|
{
|
||||||
filename.assign(f);
|
filename.assign(f);
|
||||||
@ -111,6 +133,49 @@ int Compiler::CipCount()
|
|||||||
return cipc;
|
return cipc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Compiler::WriteCell(FILE *fp, ucell *c, int repeat)
|
||||||
|
{
|
||||||
|
unsigned char T[5] = {0,0,0,0,0};
|
||||||
|
unsigned char code = 0;
|
||||||
|
int index = 0;
|
||||||
|
ucell p = (*c);
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (i=1; i<=repeat; i++)
|
||||||
|
{
|
||||||
|
if (pack)
|
||||||
|
{
|
||||||
|
for (index=0;index<5;index++)
|
||||||
|
{
|
||||||
|
T[index]=(unsigned char)(p & 0x7f);
|
||||||
|
p>>=7;
|
||||||
|
}
|
||||||
|
while (index>1 && T[index-1]==0 && (T[index-2] & 0x40)==0)
|
||||||
|
{
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
if (index==5 && T[index-1]==0x0f && (T[index-2] & 0x40)!=0)
|
||||||
|
{
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
while (index>1 && T[index-1]==0x7f && (T[index-2] & 0x40)!=0)
|
||||||
|
{
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
assert(index>0);
|
||||||
|
while (index-->0)
|
||||||
|
{
|
||||||
|
code=(unsigned char)((index==0)?T[index]:(T[index]|0x80));
|
||||||
|
fwrite((void*)&code, sizeof(unsigned char), 1, fp);
|
||||||
|
bitsOut += sizeof(unsigned char);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fwrite((void*)c, sizeof(ucell), 1, fp);
|
||||||
|
bitsOut += sizeof(ucell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Compiler::Compile(std::string &out)
|
bool Compiler::Compile(std::string &out)
|
||||||
{
|
{
|
||||||
if (CodeList.size() < 1 || !CError || CError->GetStatus() >= Err_Error)
|
if (CodeList.size() < 1 || !CError || CError->GetStatus() >= Err_Error)
|
||||||
@ -118,6 +183,7 @@ bool Compiler::Compile(std::string &out)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bitsOut = 0;
|
||||||
int32_t fileSize = 0;
|
int32_t fileSize = 0;
|
||||||
int16_t magic = (int16_t)AMX_MAGIC;
|
int16_t magic = (int16_t)AMX_MAGIC;
|
||||||
char file_version = CUR_FILE_VERSION;
|
char file_version = CUR_FILE_VERSION;
|
||||||
@ -127,6 +193,15 @@ bool Compiler::Compile(std::string &out)
|
|||||||
int32_t cod, dat, hea, stp, cip, publics, natives, libraries;
|
int32_t cod, dat, hea, stp, cip, publics, natives, libraries;
|
||||||
int32_t pubvars, tags, names;
|
int32_t pubvars, tags, names;
|
||||||
int hdrEnd = sizeof(AMX_HEADER);
|
int hdrEnd = sizeof(AMX_HEADER);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
flags |= AMX_FLAG_DEBUG;
|
||||||
|
}
|
||||||
|
if (pack)
|
||||||
|
{
|
||||||
|
flags |= AMX_FLAG_COMPACT;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<ProcMngr::AsmProc *> ProcList;
|
std::vector<ProcMngr::AsmProc *> ProcList;
|
||||||
std::vector<ProcMngr::AsmProc *>::iterator pl;
|
std::vector<ProcMngr::AsmProc *>::iterator pl;
|
||||||
@ -195,6 +270,7 @@ bool Compiler::Compile(std::string &out)
|
|||||||
cOffset += (int)strlen(Nametbl.at(off).Name) + 1;
|
cOffset += (int)strlen(Nametbl.at(off).Name) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bitsOut = cOffset;
|
||||||
cod = cOffset;
|
cod = cOffset;
|
||||||
dat = cod + CipCount();
|
dat = cod + CipCount();
|
||||||
hea = dat + DAT->GetSize();
|
hea = dat + DAT->GetSize();
|
||||||
@ -267,15 +343,15 @@ bool Compiler::Compile(std::string &out)
|
|||||||
|
|
||||||
std::vector<Asm *>::iterator ci;
|
std::vector<Asm *>::iterator ci;
|
||||||
std::vector<int>::iterator di;
|
std::vector<int>::iterator di;
|
||||||
int cop = 0;
|
ucell cop = 0;
|
||||||
for (ci = CodeList.begin(); ci != CodeList.end(); ci++)
|
for (ci = CodeList.begin(); ci != CodeList.end(); ci++)
|
||||||
{
|
{
|
||||||
cop = (*ci)->op;
|
cop = (*ci)->op;
|
||||||
fwrite((void *)&cop, sizeof(int32_t), 1, fp);
|
WriteCell(fp, &cop, 1);
|
||||||
for (di = (*ci)->params.begin(); di != (*ci)->params.end(); di++)
|
for (di = (*ci)->params.begin(); di != (*ci)->params.end(); di++)
|
||||||
{
|
{
|
||||||
cop = (*di);
|
cop = (*di);
|
||||||
fwrite((void *)&cop, sizeof(int32_t), 1, fp);
|
WriteCell(fp, &cop, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,7 +359,7 @@ bool Compiler::Compile(std::string &out)
|
|||||||
std::vector<DataMngr::Datum *>::iterator dmi;
|
std::vector<DataMngr::Datum *>::iterator dmi;
|
||||||
DAT->GetData(dm);
|
DAT->GetData(dm);
|
||||||
|
|
||||||
int val = 0;
|
ucell val = 0;
|
||||||
const char *s = 0;
|
const char *s = 0;
|
||||||
for (dmi = dm.begin(); dmi != dm.end(); dmi++)
|
for (dmi = dm.begin(); dmi != dm.end(); dmi++)
|
||||||
{
|
{
|
||||||
@ -298,18 +374,25 @@ bool Compiler::Compile(std::string &out)
|
|||||||
for (int q = 0; q < (*dmi)->e.Size(); q++)
|
for (int q = 0; q < (*dmi)->e.Size(); q++)
|
||||||
{
|
{
|
||||||
val = s[q];
|
val = s[q];
|
||||||
fwrite((void*)&val, sizeof(int32_t), 1, fp);
|
WriteCell(fp, &val, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
char c = (*dmi)->fill;
|
if (DAT->IsOptimized())
|
||||||
for (int iter=0; iter<=(*dmi)->e.GetNumber(); iter++)
|
break;
|
||||||
{
|
ucell c = (*dmi)->fill;
|
||||||
fwrite((void*)&c, sizeof(int32_t), 1, fp);
|
WriteCell(fp, &c, (*dmi)->e.GetNumber());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Was packing enabled? Re-output the actual size */
|
||||||
|
if (pack)
|
||||||
|
{
|
||||||
|
fseek(fp, 0, SEEK_SET);
|
||||||
|
fwrite((void *)&bitsOut, sizeof(int32_t), 1, fp);
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -326,32 +409,44 @@ void Compiler::Clear()
|
|||||||
CSymbols->Clear();
|
CSymbols->Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Two pass parser.
|
||||||
|
* The first pass applies macros + defines + directives
|
||||||
|
* natives, and data.
|
||||||
|
* The second pass eats up everything else (code, publics)
|
||||||
|
*/
|
||||||
bool Compiler::Parse()
|
bool Compiler::Parse()
|
||||||
{
|
{
|
||||||
std::ifstream fp(filename.c_str());
|
FILE *fp = 0;
|
||||||
char buffer[256] = {0};
|
char buffer[256] = {0};
|
||||||
std::stack<int> DefStack;
|
std::stack<int> DefStack;
|
||||||
std::stack<std::string> LabelStack;
|
std::stack<std::string> LabelStack;
|
||||||
curLine = 0;
|
curLine = 0;
|
||||||
AsmSection sec = Asm_None;
|
AsmSection sec = Asm_None;
|
||||||
lastCip = 0-cellsize;
|
lastCip = 0-cellsize;
|
||||||
|
int pass = 0;
|
||||||
|
|
||||||
if (!fp.is_open())
|
Start:
|
||||||
|
fp = fopen(filename.c_str(), "rt");
|
||||||
|
curLine = 0;
|
||||||
|
sec = Asm_None;
|
||||||
|
lastCip = 0-cellsize;
|
||||||
|
|
||||||
|
if (!fp)
|
||||||
{
|
{
|
||||||
CError->ErrorMsg(Err_FileOpen, filename.c_str());
|
CError->ErrorMsg(Err_FileOpen, filename.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!fp.eof())
|
while (!feof(fp))
|
||||||
{
|
{
|
||||||
fp.getline(buffer, 255);
|
fgets(buffer, 255, fp);
|
||||||
curLine+=1;
|
curLine+=1;
|
||||||
|
|
||||||
/* Check for preprocessor directives */
|
/* Check for preprocessor directives */
|
||||||
if (buffer[0] == '#')
|
if (buffer[0] == '#')
|
||||||
{
|
{
|
||||||
std::string procline(buffer);
|
std::string procline(buffer);
|
||||||
if (procline.substr(0, 3).compare("#if") == 0)
|
if (procline.substr(0, 6).compare("#ifdef") == 0)
|
||||||
{
|
{
|
||||||
std::string def;
|
std::string def;
|
||||||
std::string temp;
|
std::string temp;
|
||||||
@ -359,16 +454,37 @@ bool Compiler::Parse()
|
|||||||
StringBreak(procline, def, temp);
|
StringBreak(procline, def, temp);
|
||||||
StringBreak(temp, def, comp);
|
StringBreak(temp, def, comp);
|
||||||
DefineMngr::Define *D = 0;
|
DefineMngr::Define *D = 0;
|
||||||
if ((D = CDefines->FindDefine(def)) == 0)
|
if ( (D = CDefines->FindDefine(def)) == NULL)
|
||||||
{
|
{
|
||||||
DefStack.push(0);
|
DefStack.push(0);
|
||||||
} else if (D->GetDefine()->compare(comp) == 0) {
|
} else {
|
||||||
|
if (D->GetDefine()->compare("0") == 0)
|
||||||
|
{
|
||||||
|
DefStack.push(0);
|
||||||
|
} else {
|
||||||
|
DefStack.push(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (procline.substr(0, 7).compare("#ifndef") == 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)) == NULL)
|
||||||
|
{
|
||||||
DefStack.push(1);
|
DefStack.push(1);
|
||||||
} else {
|
} else {
|
||||||
DefStack.push(0);
|
if (D->GetDefine()->compare("0") == 0)
|
||||||
|
{
|
||||||
|
DefStack.push(1);
|
||||||
|
} else {
|
||||||
|
DefStack.push(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (procline.substr(0, 5).compare("#else") == 0) {
|
} else if (procline.substr(0, 5).compare("#else") == 0) {
|
||||||
if (DefStack.size())
|
if (!DefStack.empty())
|
||||||
{
|
{
|
||||||
if (DefStack.top() == 1)
|
if (DefStack.top() == 1)
|
||||||
{
|
{
|
||||||
@ -383,7 +499,7 @@ bool Compiler::Parse()
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
} else if (procline.substr(0, 6).compare("#endif") == 0) {
|
} else if (procline.substr(0, 6).compare("#endif") == 0) {
|
||||||
if (DefStack.size())
|
if (!DefStack.empty())
|
||||||
{
|
{
|
||||||
DefStack.pop();
|
DefStack.pop();
|
||||||
} else {
|
} else {
|
||||||
@ -399,7 +515,11 @@ bool Compiler::Parse()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ProcessDirective(procline);
|
// only process directives on pass one
|
||||||
|
if (pass == 0)
|
||||||
|
{
|
||||||
|
ProcessDirective(procline);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -428,7 +548,7 @@ bool Compiler::Parse()
|
|||||||
if (line.compare(".DATA") == 0)
|
if (line.compare(".DATA") == 0)
|
||||||
{
|
{
|
||||||
sec = Asm_Data;
|
sec = Asm_Data;
|
||||||
} else if (line.compare(".CODE") == 0) {
|
} else if (line.compare(".CODE") == 0) {;
|
||||||
sec = Asm_Code;
|
sec = Asm_Code;
|
||||||
} else if (line.compare(".PUBLIC") == 0) {
|
} else if (line.compare(".PUBLIC") == 0) {
|
||||||
sec = Asm_Public;
|
sec = Asm_Public;
|
||||||
@ -438,13 +558,16 @@ bool Compiler::Parse()
|
|||||||
sec = Asm_Invalid;
|
sec = Asm_Invalid;
|
||||||
CError->ErrorMsg(Err_Invalid_Section, buffer);
|
CError->ErrorMsg(Err_Invalid_Section, buffer);
|
||||||
}
|
}
|
||||||
/* Update the labels */
|
if (pass == 1)
|
||||||
CLabels->CompleteQueue(true);
|
|
||||||
while (!LabelStack.empty())
|
|
||||||
{
|
{
|
||||||
CLabels->EraseLabel(LabelStack.top());
|
/* Update the labels */
|
||||||
CSymbols->EraseSymbol(LabelStack.top());
|
CLabels->CompleteQueue(true);
|
||||||
LabelStack.pop();
|
while (!LabelStack.empty())
|
||||||
|
{
|
||||||
|
CLabels->EraseLabel(LabelStack.top());
|
||||||
|
CSymbols->EraseSymbol(LabelStack.top());
|
||||||
|
LabelStack.pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Do pre-processing */
|
/* Do pre-processing */
|
||||||
@ -461,6 +584,8 @@ bool Compiler::Parse()
|
|||||||
} else if (sec == Asm_Invalid) {
|
} else if (sec == Asm_Invalid) {
|
||||||
/* Just ignore it */
|
/* Just ignore it */
|
||||||
} else if (sec == Asm_Data) {
|
} else if (sec == Asm_Data) {
|
||||||
|
if (pass == 1)
|
||||||
|
continue;
|
||||||
/* Format is Symbol, [db|stat], Data */
|
/* Format is Symbol, [db|stat], Data */
|
||||||
std::string symbol;
|
std::string symbol;
|
||||||
std::string data;
|
std::string data;
|
||||||
@ -505,17 +630,17 @@ bool Compiler::Parse()
|
|||||||
CExpr t(CError);
|
CExpr t(CError);
|
||||||
t.Set(fill);
|
t.Set(fill);
|
||||||
t.Evaluate();
|
t.Evaluate();
|
||||||
e.Set(amt);
|
e = EvalE(amt, Sym_None);
|
||||||
e.Evaluate();
|
|
||||||
DAT->Add(symbol, e, false, t.GetNumber());
|
DAT->Add(symbol, e, false, t.GetNumber());
|
||||||
} else {
|
} else {
|
||||||
e.Set(data);
|
e = EvalE(data, Sym_None);
|
||||||
e.Evaluate();
|
|
||||||
DAT->Add(symbol, e, false, 0);
|
DAT->Add(symbol, e, false, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CSymbols->AddSymbol(symbol, Sym_Dat, CurLine());
|
CSymbols->AddSymbol(symbol, Sym_Dat, CurLine());
|
||||||
} else if (sec == Asm_Public) {
|
} else if (sec == Asm_Public) {
|
||||||
|
if (pass == 0)
|
||||||
|
continue;
|
||||||
if (!IsValidSymbol(line))
|
if (!IsValidSymbol(line))
|
||||||
{
|
{
|
||||||
CError->ErrorMsg(Err_Invalid_Symbol);
|
CError->ErrorMsg(Err_Invalid_Symbol);
|
||||||
@ -538,6 +663,8 @@ bool Compiler::Parse()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (sec == Asm_Native) {
|
} else if (sec == Asm_Native) {
|
||||||
|
if (pass == 1)
|
||||||
|
continue;
|
||||||
if (!IsValidSymbol(line))
|
if (!IsValidSymbol(line))
|
||||||
{
|
{
|
||||||
CError->ErrorMsg(Err_Invalid_Symbol);
|
CError->ErrorMsg(Err_Invalid_Symbol);
|
||||||
@ -552,6 +679,8 @@ bool Compiler::Parse()
|
|||||||
S = CSymbols->AddSymbol(line, 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) {
|
||||||
|
if (pass == 0)
|
||||||
|
continue;
|
||||||
std::string code;
|
std::string code;
|
||||||
std::string params;
|
std::string params;
|
||||||
SymbolList::Symbol *S;
|
SymbolList::Symbol *S;
|
||||||
@ -1454,12 +1583,25 @@ bool Compiler::Parse()
|
|||||||
} /* Line processing */
|
} /* Line processing */
|
||||||
} /* While */
|
} /* While */
|
||||||
|
|
||||||
|
// go for second pass
|
||||||
|
if (pass == 0)
|
||||||
|
{
|
||||||
|
pass = 1;
|
||||||
|
fclose(fp);
|
||||||
|
if (dopt)
|
||||||
|
DAT->Optimize();
|
||||||
|
goto Start;
|
||||||
|
}
|
||||||
|
|
||||||
/* We're not done! Check the label Queue */
|
/* We're not done! Check the label Queue */
|
||||||
CLabels->CompleteQueue();
|
CLabels->CompleteQueue();
|
||||||
|
|
||||||
CError->PrintReport();
|
CError->PrintReport();
|
||||||
|
|
||||||
if (CError->GetStatus() >= Err_Error)
|
if (CError->GetStatus() >= Err_Error)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1882,13 +2024,22 @@ void Compiler::ProcessDirective(std::string &text)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Compiler::Eval(std::string &str, SymbolType sym)
|
||||||
|
{
|
||||||
|
CExpr e(CError);
|
||||||
|
|
||||||
|
e = EvalE(str, sym);
|
||||||
|
|
||||||
|
return e.GetNumber();
|
||||||
|
}
|
||||||
|
|
||||||
/* The evaluator works by storing expressions on a stack.
|
/* The evaluator works by storing expressions on a stack.
|
||||||
Each expression is an RPN-ordered pair of lists for ops and values
|
Each expression is an RPN-ordered pair of lists for ops and values
|
||||||
Every time the stack is popped, the expression is evaluated by searching
|
Every time the stack is popped, the expression is evaluated by searching
|
||||||
for the highest operators and evaluating them.
|
for the highest operators and evaluating them.
|
||||||
Note that string literals are not allowed here yet.
|
Note that string literals are not allowed here yet.
|
||||||
*/
|
*/
|
||||||
int Compiler::Eval(std::string &str, SymbolType sym)
|
CExpr Compiler::EvalE(std::string &str, SymbolType sym)
|
||||||
{
|
{
|
||||||
std::stack<rpn *> Stack;
|
std::stack<rpn *> Stack;
|
||||||
std::string bpstr;
|
std::string bpstr;
|
||||||
@ -2025,7 +2176,7 @@ int Compiler::Eval(std::string &str, SymbolType sym)
|
|||||||
delete r;
|
delete r;
|
||||||
r = 0;
|
r = 0;
|
||||||
|
|
||||||
return final.GetNumber();
|
return final;
|
||||||
}
|
}
|
||||||
|
|
||||||
CExpr Compiler::EvalRpn(rpn *r, SymbolType sym)
|
CExpr Compiler::EvalRpn(rpn *r, SymbolType sym)
|
||||||
|
@ -68,16 +68,20 @@ public:
|
|||||||
int CurCip() { return lastCip; }
|
int CurCip() { return lastCip; }
|
||||||
Asm *CurAsm() { return curAsm; }
|
Asm *CurAsm() { return curAsm; }
|
||||||
bool SetDebug();
|
bool SetDebug();
|
||||||
public: //private
|
bool SetPack();
|
||||||
|
bool SetDOpt();
|
||||||
int DerefSymbol(std::string &str, SymbolType sym = Sym_None);
|
int DerefSymbol(std::string &str, SymbolType sym = Sym_None);
|
||||||
|
bool IsSymbol(std::string &str);
|
||||||
|
private:
|
||||||
void ProcessDirective(std::string &text);
|
void ProcessDirective(std::string &text);
|
||||||
void Init();
|
void Init();
|
||||||
void InitOpcodes();
|
void InitOpcodes();
|
||||||
int Eval(std::string &str, SymbolType sym = Sym_None);
|
int Eval(std::string &str, SymbolType sym = Sym_None);
|
||||||
|
CExpr EvalE(std::string &str, SymbolType sym = Sym_None);
|
||||||
CExpr EvalRpn(rpn *r, SymbolType sym);
|
CExpr EvalRpn(rpn *r, SymbolType sym);
|
||||||
OpToken OperToken(char c);
|
OpToken OperToken(char c);
|
||||||
char OperChar(OpToken c);
|
char OperChar(OpToken c);
|
||||||
bool IsSymbol(std::string &str);
|
void WriteCell(FILE *fp, ucell *c, int repeat);
|
||||||
private:
|
private:
|
||||||
std::vector<Asm *> CodeList;
|
std::vector<Asm *> CodeList;
|
||||||
std::map<std::string,int> OpCodes;
|
std::map<std::string,int> OpCodes;
|
||||||
@ -96,6 +100,9 @@ private:
|
|||||||
int cellsize;
|
int cellsize;
|
||||||
int stacksize;
|
int stacksize;
|
||||||
bool debug;
|
bool debug;
|
||||||
|
bool pack;
|
||||||
|
bool dopt;
|
||||||
|
int bitsOut;
|
||||||
Asm *curAsm;
|
Asm *curAsm;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ DataMngr::Datum::Datum()
|
|||||||
db = false;
|
db = false;
|
||||||
offset = -1;
|
offset = -1;
|
||||||
fill = 0;
|
fill = 0;
|
||||||
|
zeroed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataMngr::Add(std::string &s, CExpr &expr, bool db, int fill)
|
void DataMngr::Add(std::string &s, CExpr &expr, bool db, int fill)
|
||||||
@ -128,3 +129,68 @@ void DataMngr::GetData(std::vector<DataMngr::Datum *> &dList)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DataMngr::PrintTable()
|
||||||
|
{
|
||||||
|
std::vector<DataMngr::Datum *>::iterator i;
|
||||||
|
DataMngr::Datum *p = 0;
|
||||||
|
|
||||||
|
printf("Symbol\tSize\n");
|
||||||
|
for (i=List.begin(); i!=List.end(); i++)
|
||||||
|
{
|
||||||
|
p = (*i);
|
||||||
|
printf("%s\t%d\n", p->symbol.c_str(), p->offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Rewrite the DAT section so empties are at the end
|
||||||
|
void DataMngr::Optimize()
|
||||||
|
{
|
||||||
|
std::vector<DataMngr::Datum *> DbList;
|
||||||
|
std::vector<DataMngr::Datum *> MtList;
|
||||||
|
std::vector<DataMngr::Datum *>::iterator i;
|
||||||
|
|
||||||
|
for (i=List.begin(); i!=List.end(); i++)
|
||||||
|
{
|
||||||
|
if ( (*i)->db )
|
||||||
|
{
|
||||||
|
DbList.push_back( (*i) );
|
||||||
|
} else if ( (*i)->fill == 0 ) {
|
||||||
|
MtList.push_back( (*i) );
|
||||||
|
} else {
|
||||||
|
DbList.push_back( (*i) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List.clear();
|
||||||
|
|
||||||
|
lastOffset = 0;
|
||||||
|
cursize = 0;
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
|
for (i=DbList.begin(); i!=DbList.end(); i++)
|
||||||
|
{
|
||||||
|
size = (( (*i)->e.GetType() == Val_Number
|
||||||
|
|| (*i)->e.GetType() == Val_Float ) ?
|
||||||
|
cellsize : (*i)->e.Size() * cellsize);
|
||||||
|
(*i)->offset = lastOffset;
|
||||||
|
lastOffset += size;
|
||||||
|
(*i)->zeroed = false;
|
||||||
|
List.push_back( (*i) );
|
||||||
|
}
|
||||||
|
|
||||||
|
cursize = lastOffset;
|
||||||
|
DbList.clear();
|
||||||
|
|
||||||
|
for (i=MtList.begin(); i!=MtList.end(); i++)
|
||||||
|
{
|
||||||
|
size = ( (*i)->e.GetNumber() * cellsize );
|
||||||
|
(*i)->offset = lastOffset;
|
||||||
|
lastOffset += size;
|
||||||
|
(*i)->zeroed = true;
|
||||||
|
List.push_back( (*i) );
|
||||||
|
}
|
||||||
|
|
||||||
|
MtList.clear();
|
||||||
|
|
||||||
|
optimized = true;
|
||||||
|
}
|
||||||
|
@ -35,22 +35,27 @@ public:
|
|||||||
bool db;
|
bool db;
|
||||||
int offset;
|
int offset;
|
||||||
int fill;
|
int fill;
|
||||||
|
bool zeroed;
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
~DataMngr();
|
~DataMngr();
|
||||||
DataMngr() { cellsize = 4; lastOffset = 0; cursize = 0; }
|
DataMngr() { cellsize = 4; lastOffset = 0; cursize = 0; optimized = false; }
|
||||||
DataMngr(int cell) { lastOffset = 0; cellsize = cell; cursize = 0; }
|
DataMngr(int cell) { lastOffset = 0; cellsize = cell; cursize = 0; optimized = false; }
|
||||||
void Add(std::string &s, CExpr &expr, bool db = false, int fill = 0);
|
void Add(std::string &s, CExpr &expr, bool db = false, int fill = 0);
|
||||||
DataMngr::Datum *FindData(std::string &sym);
|
DataMngr::Datum *FindData(std::string &sym);
|
||||||
void GetData(std::vector<DataMngr::Datum *> &dList);
|
void GetData(std::vector<DataMngr::Datum *> &dList);
|
||||||
int GetOffset(std::string &sym);
|
int GetOffset(std::string &sym);
|
||||||
int GetSize();
|
int GetSize();
|
||||||
void Clear();
|
void Clear();
|
||||||
|
void PrintTable();
|
||||||
|
void Optimize();
|
||||||
|
bool IsOptimized() { return optimized; }
|
||||||
private:
|
private:
|
||||||
std::vector<DataMngr::Datum *> List;
|
std::vector<DataMngr::Datum *> List;
|
||||||
int lastOffset;
|
int lastOffset;
|
||||||
int cellsize;
|
int cellsize;
|
||||||
int cursize;
|
int cursize;
|
||||||
|
bool optimized;
|
||||||
public:
|
public:
|
||||||
static const int nof = -1;
|
static const int nof = -1;
|
||||||
};
|
};
|
||||||
|
@ -24,11 +24,10 @@
|
|||||||
|
|
||||||
std::string filename;
|
std::string filename;
|
||||||
std::string output_name;
|
std::string output_name;
|
||||||
|
Compiler Program;
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
Compiler Program;
|
|
||||||
|
|
||||||
get_options(argc, argv, Program);
|
get_options(argc, argv, Program);
|
||||||
|
|
||||||
if (filename.size() < 1)
|
if (filename.size() < 1)
|
||||||
@ -76,6 +75,12 @@ void get_options(int argc, char **argv, Compiler &Prog)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'c':
|
||||||
|
{
|
||||||
|
Program.SetPack();
|
||||||
|
opt_flag = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'v':
|
case 'v':
|
||||||
{
|
{
|
||||||
opt_flag = 0; /* no options expected */
|
opt_flag = 0; /* no options expected */
|
||||||
@ -89,6 +94,18 @@ void get_options(int argc, char **argv, Compiler &Prog)
|
|||||||
Prog.SetDebug();
|
Prog.SetDebug();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'h':
|
||||||
|
{
|
||||||
|
opt_flag = 0;
|
||||||
|
Prog.SetDOpt();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'f':
|
||||||
|
{
|
||||||
|
opt_flag = 0;
|
||||||
|
Prog.SetDOpt();
|
||||||
|
Prog.SetPack();
|
||||||
|
}
|
||||||
} /* switch */
|
} /* switch */
|
||||||
} else { /* - */
|
} else { /* - */
|
||||||
if (!opt_flag)
|
if (!opt_flag)
|
||||||
@ -110,7 +127,7 @@ void get_options(int argc, char **argv, Compiler &Prog)
|
|||||||
|
|
||||||
void print_version()
|
void print_version()
|
||||||
{
|
{
|
||||||
printf("Small/AMX Assembler 1.00\n");
|
printf("Small/AMX Assembler 1.01\n");
|
||||||
printf("(C)2004 David 'BAILOPAN' Anderson\n");
|
printf("(C)2004 David 'BAILOPAN' Anderson\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,5 +137,8 @@ void print_options()
|
|||||||
printf("\t-d\t\t- Add debug opcodes (will double file size)\n");
|
printf("\t-d\t\t- Add debug opcodes (will double file size)\n");
|
||||||
printf("\t-v\t\t- Output version and exit\n");
|
printf("\t-v\t\t- Output version and exit\n");
|
||||||
printf("\t-o\t\t- Specify file to write\n");
|
printf("\t-o\t\t- Specify file to write\n");
|
||||||
|
printf("\t-c\t\t- Enable compact encoding\n");
|
||||||
|
printf("\t-h\t\t- Optimize DAT section\n");
|
||||||
|
printf("\t-f\t\t- Optimal Build\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user