Rewrote core algebraic parser

Added trivial float support
Added local labels and vastly improved label support
Fixed some crash bugs
This commit is contained in:
David Anderson 2004-08-11 08:14:54 +00:00
parent 74d278d1c6
commit 7acc70ee62
15 changed files with 444 additions and 185 deletions

View File

@ -308,7 +308,7 @@ bool Compiler::Compile()
char c = (*dmi)->fill; char c = (*dmi)->fill;
for (int iter=0; iter<=(*dmi)->e.GetNumber(); iter++) for (int iter=0; iter<=(*dmi)->e.GetNumber(); iter++)
{ {
fwrite((void*)&c, sizeof(char), 1, fp); fwrite((void*)&c, sizeof(int32_t), 1, fp);
} }
} }
} }
@ -334,6 +334,7 @@ bool Compiler::Parse()
std::ifstream fp(filename.c_str()); std::ifstream fp(filename.c_str());
char buffer[256] = {0}; char buffer[256] = {0};
std::stack<int> DefStack; std::stack<int> DefStack;
std::stack<std::string> LabelStack;
curLine = 0; curLine = 0;
AsmSection sec = Asm_None; AsmSection sec = Asm_None;
lastCip = 0-cellsize; lastCip = 0-cellsize;
@ -347,7 +348,7 @@ bool Compiler::Parse()
while (!fp.eof()) while (!fp.eof())
{ {
fp.getline(buffer, 255); fp.getline(buffer, 255);
curLine++; curLine+=1;
/* Check for preprocessor directives */ /* Check for preprocessor directives */
if (buffer[0] == '#') if (buffer[0] == '#')
@ -440,6 +441,14 @@ bool Compiler::Parse()
sec = Asm_Invalid; sec = Asm_Invalid;
CError->ErrorMsg(Err_Invalid_Section, buffer); CError->ErrorMsg(Err_Invalid_Section, buffer);
} }
/* Update the labels */
CLabels->CompleteQueue(true);
while (!LabelStack.empty())
{
CLabels->EraseLabel(LabelStack.top());
CSymbols->EraseSymbol(LabelStack.top());
LabelStack.pop();
}
} else { } else {
/* Do pre-processing */ /* Do pre-processing */
CMacros->SearchAndReplace(line); CMacros->SearchAndReplace(line);
@ -501,7 +510,7 @@ bool Compiler::Parse()
t.Evaluate(); t.Evaluate();
e.Set(amt); e.Set(amt);
e.Evaluate(); e.Evaluate();
DAT->Add(symbol, e, false, (char)t.GetNumber()); DAT->Add(symbol, e, false, t.GetNumber());
} else { } else {
e.Set(data); e.Set(data);
e.Evaluate(); e.Evaluate();
@ -570,6 +579,7 @@ bool Compiler::Parse()
Asm *ASM = new Asm; Asm *ASM = new Asm;
ASM->cip = lastCip + cellsize; ASM->cip = lastCip + cellsize;
ASM->op = OpCodes["proc"]; ASM->op = OpCodes["proc"];
ASM->line = curLine;
lastCip += cellsize; lastCip += cellsize;
/* Add symbol */ /* Add symbol */
S = CSymbols->AddSymbol(params, Sym_Proc, CurLine()); S = CSymbols->AddSymbol(params, Sym_Proc, CurLine());
@ -578,7 +588,16 @@ bool Compiler::Parse()
/* Add to PROC list */ /* Add to PROC list */
PROC->AddProc(S, ASM); PROC->AddProc(S, ASM);
} else if (code.compare("ENDP") == 0) { } else if (code.compare("ENDP") == 0) {
/* This is, in theory, not needed */ /* This is, in theory, not needed
* Nonetheless, we check labels here
*/
CLabels->CompleteQueue(true);
while (!LabelStack.empty())
{
CLabels->EraseLabel(LabelStack.top());
CSymbols->EraseSymbol(LabelStack.top());
LabelStack.pop();
}
} else if (params.size() < 1 && code[code.size()-1] == ':') { } else if (params.size() < 1 && code[code.size()-1] == ':') {
/* Label! */ /* Label! */
/* Check if symbol is valid */ /* Check if symbol is valid */
@ -604,6 +623,10 @@ bool Compiler::Parse()
} }
continue; continue;
} }
if (code[0] == '_')
{
LabelStack.push(code);
}
S = CSymbols->AddSymbol(code, Sym_Label, CurLine()); S = CSymbols->AddSymbol(code, Sym_Label, CurLine());
CLabels->AddLabel(S, lastCip+cellsize); CLabels->AddLabel(S, lastCip+cellsize);
} else { } else {
@ -623,6 +646,7 @@ bool Compiler::Parse()
ASM = new Asm; ASM = new Asm;
ASM->cip = lastCip+cellsize; ASM->cip = lastCip+cellsize;
ASM->op = OP_LINE; ASM->op = OP_LINE;
ASM->line = curLine;
ASM->params.push_back(curLine); ASM->params.push_back(curLine);
ASM->params.push_back(0); ASM->params.push_back(0);
CodeList.push_back(ASM); CodeList.push_back(ASM);
@ -647,6 +671,7 @@ bool Compiler::Parse()
ASM->cip = (lastCip+cellsize); ASM->cip = (lastCip+cellsize);
ASM->op = op; ASM->op = op;
ASM->line = curLine;
lastCip += cellsize; lastCip += cellsize;
switch (op) switch (op)
@ -1801,7 +1826,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->sym.c_str(), S->line); CError->ErrorMsg(Err_SymbolRedef, 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;
@ -1827,8 +1852,22 @@ void Compiler::ProcessDirective(std::string &text)
CSymbols->AddSymbol(symbol, Sym_Macro, curLine); CSymbols->AddSymbol(symbol, Sym_Macro, curLine);
//TODO: ClearList(ArgList); //TODO: ClearList(ArgList);
} }
} else if (!directive.compare("stacksize")) { } else if (!directive.compare("pragma")) {
std::string pragma;
std::string entry;
StringBreak(definition, pragma, entry);
if (pragma.compare("stacksize") == 0)
{
int stksz = atoi(entry.c_str());
if (stksz < 100)
{
CError->ErrorMsg(Err_Invalid_Pragma);
} else {
stacksize = stksz;
}
} else {
CError->ErrorMsg(Err_Invalid_Pragma);
}
} else if (!directive.compare("define")) { } else if (!directive.compare("define")) {
std::string symbol; std::string symbol;
std::string def; std::string def;
@ -1859,8 +1898,6 @@ int Compiler::Eval(std::string &str, SymbolType sym)
int i = 0; int i = 0;
rpn *r = new rpn; rpn *r = new rpn;
int pos = 0; int pos = 0;
int val = 0;
CExpr e;
Stack.push(r); Stack.push(r);
@ -1890,18 +1927,10 @@ int Compiler::Eval(std::string &str, SymbolType sym)
{ {
bpstr.assign(str.substr(pos, i-pos)); bpstr.assign(str.substr(pos, i-pos));
Strip(bpstr); Strip(bpstr);
CExpr e(CError);
e.Set(bpstr); e.Set(bpstr);
val = 0; e.Evaluate(sym);
if (!e.Analyze() && IsValidSymbol(bpstr)) r->vals.push_back(e);
{
val = DerefSymbol(bpstr, sym);
} else if (e.Analyze() && (e.Evaluate() == Val_Number)) {
val = e.GetNumber();
} else {
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
r->vals.push_back(val);
} }
r->ops.push_back(str[i]); r->ops.push_back(str[i]);
if (str[i] == '>' || str[i] == '<') if (str[i] == '>' || str[i] == '<')
@ -1917,18 +1946,10 @@ int Compiler::Eval(std::string &str, SymbolType sym)
{ {
bpstr.assign(str.substr(pos, i-pos)); bpstr.assign(str.substr(pos, i-pos));
Strip(bpstr); Strip(bpstr);
CExpr e(CError);
e.Set(bpstr); e.Set(bpstr);
val = 0; e.Evaluate(sym);
if (!e.Analyze() && IsValidSymbol(bpstr)) r->vals.push_back(e);
{
val = DerefSymbol(bpstr, sym);
} else if (e.Analyze() && (e.Evaluate() == Val_Number)) {
val = e.GetNumber();
} else {
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
r->vals.push_back(val);
} }
r = new rpn; r = new rpn;
Stack.push(r); Stack.push(r);
@ -1939,20 +1960,13 @@ int Compiler::Eval(std::string &str, SymbolType sym)
{ {
bpstr.assign(str.substr(pos, i-pos)); bpstr.assign(str.substr(pos, i-pos));
Strip(bpstr); Strip(bpstr);
CExpr e(CError);
e.Set(bpstr); e.Set(bpstr);
val = 0; e.Evaluate(sym);
if (!e.Analyze() && IsValidSymbol(bpstr)) r->vals.push_back(e);
{
val = DerefSymbol(bpstr, sym);
} else if (e.Analyze() && (e.Evaluate() == Val_Number)) {
val = e.GetNumber();
} else {
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
} }
r->vals.push_back(val); CExpr t;
} t = EvalRpn(r, sym);
val = EvalRpn(r, sym);
delete r; delete r;
if (Stack.size() < 2) if (Stack.size() < 2)
{ {
@ -1967,7 +1981,7 @@ int Compiler::Eval(std::string &str, SymbolType sym)
} }
Stack.pop(); Stack.pop();
r = Stack.top(); r = Stack.top();
r->vals.push_back(val); r->vals.push_back(t);
pos = i + 1; pos = i + 1;
} else if (i == (int)(str.size() - 1)) { } else if (i == (int)(str.size() - 1)) {
if (pos < i) if (pos < i)
@ -1979,18 +1993,10 @@ int Compiler::Eval(std::string &str, SymbolType sym)
if (pos < i || pos == i) if (pos < i || pos == i)
{ {
Strip(bpstr); Strip(bpstr);
CExpr e(CError);
e.Set(bpstr); e.Set(bpstr);
val = 0; e.Evaluate(sym);
if (!e.Analyze() && IsValidSymbol(bpstr)) r->vals.push_back(e);
{
val = DerefSymbol(bpstr, sym);
} else if (e.Analyze() && (e.Evaluate() == Val_Number)) {
val = e.GetNumber();
} else {
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
r->vals.push_back(val);
} }
} }
} }
@ -2009,19 +2015,18 @@ int Compiler::Eval(std::string &str, SymbolType sym)
rpn *r2 = Stack.top(); rpn *r2 = Stack.top();
Stack.pop(); Stack.pop();
val = EvalRpn(r, sym); CExpr final;
final = EvalRpn(r, sym);
return val; return final.GetNumber();
} }
int Compiler::EvalRpn(rpn *r, SymbolType sym) CExpr Compiler::EvalRpn(rpn *r, SymbolType sym)
{ {
int i = 0, j = 0; int i = 0, j = 0;
char c = 0; char c = 0;
int lval = 0; CExpr er, el;
int rval = 0; std::vector<CExpr>::iterator Q;
int nval = 0;
std::vector<int>::iterator Q;
std::vector<char>::iterator R; std::vector<char>::iterator R;
while (r->ops.size()) while (r->ops.size())
@ -2035,77 +2040,17 @@ int Compiler::EvalRpn(rpn *r, SymbolType sym)
{ {
if ((int)r->vals.size() <= j) if ((int)r->vals.size() <= j)
assert(0);// Can't have more ops than values assert(0);// Can't have more ops than values
lval = r->vals[j]; el = r->vals[j];
if (i != Token_Not) if (i != Token_Not)
{ {
if ((int)r->vals.size() <= j+1) if ((int)r->vals.size() <= j+1)
{ {
assert(0); assert(0);
} }
rval = r->vals[j+1]; er = r->vals[j+1];
} el.Oper((OpToken)i, er);
switch (i) } else {
{ el.Not();
case Token_Xor:
{
nval = lval ^ rval;
break;
}
case Token_Shr:
{
nval = lval >> rval;
break;
}
case Token_Sub:
{
nval = lval - rval;
break;
}
case Token_Mod:
{
nval = lval % rval;
break;
}
case Token_Mul:
{
nval = lval * rval;
break;
}
case Token_Div:
{
nval = (int)(lval / rval);
break;
}
case Token_Shl:
{
nval = lval << rval;
break;
}
case Token_And:
{
nval = lval & rval;
break;
}
case Token_Or:
{
nval = lval | rval;
break;
}
case Token_Add:
{
nval = lval + rval;
break;
}
case Token_Not:
{
nval = ~lval;
break;
}
default:
{
nval = 0;
break;
}
} }
R = r->ops.begin(); R = r->ops.begin();
Q = r->vals.begin(); Q = r->vals.begin();
@ -2114,13 +2059,13 @@ int Compiler::EvalRpn(rpn *r, SymbolType sym)
R += j; R += j;
Q += j; Q += j;
r->ops.erase(R); r->ops.erase(R);
r->vals[j+1] = nval; r->vals[j+1] = el;
r->vals.erase(Q); r->vals.erase(Q);
j--; j--;
} else { } else {
R += j; R += j;
r->ops.erase(R); r->ops.erase(R);
r->vals[j] = nval; r->vals[j] = el;
} }
} }
} }
@ -2233,3 +2178,13 @@ int Compiler::DerefSymbol(std::string &str, SymbolType sym)
return val; return val;
} }
bool Compiler::IsSymbol(std::string &str)
{
SymbolList::Symbol *S = 0;
if ( (S = CSymbols->FindSymbol(str)) == NULL )
return false;
return true;
}

View File

@ -40,30 +40,12 @@
lastCip+=cellsize; \ lastCip+=cellsize; \
} }
typedef enum
{
Token_None,
Token_Or,
Token_Xor,
Token_And,
Token_Shr,
Token_Shl,
Token_Mod,
Token_Div,
Token_Mul,
Token_Sub,
Token_Add,
Token_Not,
/* End */
Tokens_Total,
} OpToken;
class rpn class rpn
{ {
public: public:
//TODO: use linked lists, but not std::list //TODO: use linked lists, but not std::list
std::vector<char> ops; std::vector<char> ops;
std::vector<int> vals; std::vector<CExpr> vals;
}; };
class Compiler class Compiler
@ -91,9 +73,10 @@ public: //private
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);
int 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);
private: private:
std::vector<Asm *> CodeList; std::vector<Asm *> CodeList;
std::map<std::string,int> OpCodes; std::map<std::string,int> OpCodes;

View File

@ -47,7 +47,7 @@ DataMngr::Datum::Datum()
fill = 0; fill = 0;
} }
void DataMngr::Add(std::string &s, CExpr &expr, bool db, char fill) void DataMngr::Add(std::string &s, CExpr &expr, bool db, int fill)
{ {
DataMngr::Datum *D = new DataMngr::Datum(); DataMngr::Datum *D = new DataMngr::Datum();
@ -63,7 +63,7 @@ void DataMngr::Add(std::string &s, CExpr &expr, bool db, char fill)
size = ((D->e.GetType() == Val_Number) ? size = ((D->e.GetType() == Val_Number) ?
cellsize : D->e.Size() * cellsize); cellsize : D->e.Size() * cellsize);
} else { } else {
size = D->e.GetNumber(); size = (D->e.GetNumber() * cellsize);
} }
if (List.size() == 0) if (List.size() == 0)
@ -77,7 +77,7 @@ void DataMngr::Add(std::string &s, CExpr &expr, bool db, char fill)
((p->e.GetType() == Val_Number) ? ((p->e.GetType() == Val_Number) ?
cellsize : p->e.Size() * cellsize); cellsize : p->e.Size() * cellsize);
} else { } else {
D->offset = p->offset + p->e.GetNumber(); D->offset = p->offset + (p->e.GetNumber() * cellsize);
} }
} }

View File

@ -34,13 +34,13 @@ public:
CExpr e; CExpr e;
bool db; bool db;
int offset; int offset;
char fill; int fill;
}; };
public: public:
~DataMngr(); ~DataMngr();
DataMngr() { cellsize = 4; lastOffset = 0; cursize = 0; } DataMngr() { cellsize = 4; lastOffset = 0; cursize = 0; }
DataMngr(int cell) { lastOffset = 0; cellsize = cell; cursize = 0; } DataMngr(int cell) { lastOffset = 0; cellsize = cell; cursize = 0; }
void Add(std::string &s, CExpr &expr, bool db = false, char 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);

View File

@ -26,6 +26,7 @@ ErrorMngr::ErrorMngr()
{ {
printf("Not instantiated with a compiler."); printf("Not instantiated with a compiler.");
Cmp = NULL; Cmp = NULL;
line = -1;
assert(Cmp); assert(Cmp);
} }
@ -56,6 +57,7 @@ ErrorMngr::ErrorMngr(void *c)
Totals[1] = 0; Totals[1] = 0;
Totals[2] = 0; Totals[2] = 0;
Totals[3] = 0; Totals[3] = 0;
line = -1;
HighestError = Err_None; HighestError = Err_None;
} }
@ -95,6 +97,9 @@ void ErrorMngr::DefineErrors()
List.at(Err_Unknown_Define) = "Unknown define referenced"; List.at(Err_Unknown_Define) = "Unknown define referenced";
List.at(Err_Misplaced_Directive) = "Misplaced preprocessor directive"; List.at(Err_Misplaced_Directive) = "Misplaced preprocessor directive";
List.at(Err_Bad_Label) = "Label referenced without being created"; List.at(Err_Bad_Label) = "Label referenced without being created";
List.at(Err_Bad_Not) = "Wrong type argument to bit-complement";
List.at(Err_Invalid_Operator) = "Operator used on bad type";
List.at(Err_Invalid_Pragma) = "Invalid pragma";
List.at(Err_FileNone) = "No file specified"; List.at(Err_FileNone) = "No file specified";
List.at(Err_FileOpen) = "Could not open file \"%s\""; List.at(Err_FileOpen) = "Could not open file \"%s\"";
@ -131,13 +136,23 @@ void ErrorMngr::ErrorMsg(ErrorCode error, ...)
if (type == -1) if (type == -1)
return; return;
int curLine = 0;
if (line == -1)
{
curLine = ((Compiler *)Cmp)->CurLine();
} else {
curLine = line;
line = -1;
}
va_list argptr; va_list argptr;
va_start(argptr, error); va_start(argptr, error);
if (((Compiler *)Cmp)->CurLine() == -1) if (((Compiler *)Cmp)->CurLine() == -1)
sprintf(errbuf, "%s(%d): %s\n", ErrorSwi[type], error, GetError(error)); sprintf(errbuf, "%s(%d): %s\n", ErrorSwi[type], error, GetError(error));
else else
sprintf(errbuf, "%s(%d) on line %d: %s\n", ErrorSwi[type], error, ((Compiler *)Cmp)->CurLine(), GetError(error)); sprintf(errbuf, "%s(%d) on line %d: %s\n", ErrorSwi[type], error, curLine, GetError(error));
vprintf(errbuf, argptr); vprintf(errbuf, argptr);
va_end(argptr); va_end(argptr);
@ -164,3 +179,18 @@ const char *ErrorMngr::GetError(ErrorCode id)
return NULL; return NULL;
return List.at(id); return List.at(id);
} }
int ErrorMngr::DerefSymbol(std::string &str, int sym)
{
return ((Compiler *)Cmp)->DerefSymbol(str, (SymbolType)sym);
}
bool ErrorMngr::IsSymbol(std::string &str)
{
return ((Compiler *)Cmp)->IsSymbol(str);
}
void ErrorMngr::SetLine(int ln)
{
line = ln;
}

View File

@ -60,6 +60,9 @@ typedef enum
Err_Unknown_Define, Err_Unknown_Define,
Err_Misplaced_Directive, Err_Misplaced_Directive,
Err_Bad_Label, Err_Bad_Label,
Err_Bad_Not,
Err_Invalid_Operator,
Err_Invalid_Pragma,
errors_end, errors_end,
fatals_start, fatals_start,
@ -87,6 +90,7 @@ private:
ErrorType HighestError; ErrorType HighestError;
void *Cmp; void *Cmp;
int Totals[4]; int Totals[4];
int line;
public: public:
ErrorMngr(); ErrorMngr();
ErrorMngr(void *c); ErrorMngr(void *c);
@ -96,6 +100,9 @@ public:
void PrintReport(); void PrintReport();
int CurLine(); int CurLine();
int CurCip(); int CurCip();
void SetLine(int ln);
int DerefSymbol(std::string &str, int sym = 0);
bool IsSymbol(std::string &str);
}; };
#endif //_INCLUDE_AMX_ERROR #endif //_INCLUDE_AMX_ERROR

View File

@ -91,7 +91,7 @@ void LabelMngr::QueueLabel(std::string &sym, Asm *ASM)
LQ[d].push(ASM); LQ[d].push(ASM);
} }
void LabelMngr::CompleteQueue() void LabelMngr::CompleteQueue(bool isLocal)
{ {
std::map<std::string,std::stack<Asm *> >::iterator i; std::map<std::string,std::stack<Asm *> >::iterator i;
std::stack<Asm *> *stk = 0; std::stack<Asm *> *stk = 0;
@ -106,8 +106,16 @@ void LabelMngr::CompleteQueue()
stk = &((*i).second); stk = &((*i).second);
if (p == NULL || p->cip == LabelMngr::ncip) if (p == NULL || p->cip == LabelMngr::ncip)
{ {
CError->ErrorMsg(Err_Bad_Label); if ((!isLocal || (isLocal && search[0]=='_')) && CError)
{
while (!stk->empty())
{
CError->SetLine(stk->top()->line);
CError->ErrorMsg(Err_Bad_Lbel);
stk->pop();
} }
}
} else {
while (!stk->empty()) while (!stk->empty())
{ {
ASM = stk->top(); ASM = stk->top();
@ -115,6 +123,7 @@ void LabelMngr::CompleteQueue()
stk->pop(); stk->pop();
} }
} }
}
LQ.clear(); LQ.clear();
} }
@ -130,3 +139,19 @@ int LabelMngr::GetCip(std::string &sym)
return p->cip; return p->cip;
} }
bool LabelMngr::EraseLabel(std::string &sym)
{
std::vector<LabelMngr::Label *>::iterator i;
for (i=List.begin(); i!=List.end(); i++)
{
if ( (*i)->sym->IsEqual(sym) )
{
List.erase(i);
return true;
}
}
return false;
}

View File

@ -43,7 +43,8 @@ public:
void Clear(); void Clear();
bool SetCip(std::string &sym, int cip); bool SetCip(std::string &sym, int cip);
void QueueLabel(std::string &sym, Asm *ASM); void QueueLabel(std::string &sym, Asm *ASM);
void CompleteQueue(); void CompleteQueue(bool isLocal = false);
bool EraseLabel(std::string &sym);
private: private:
std::vector<LabelMngr::Label *> List; std::vector<LabelMngr::Label *> List;
std::map<std::string, std::stack<Asm *> > LQ; std::map<std::string, std::stack<Asm *> > LQ;

View File

@ -67,9 +67,9 @@ bool ProcMngr::SetPublic(std::string &sym)
void ProcMngr::GetPublics(std::vector<ProcMngr::AsmProc *> &pbList) void ProcMngr::GetPublics(std::vector<ProcMngr::AsmProc *> &pbList)
{ {
std::vector<ProcMngr::AsmProc *>::iterator i; std::vector<ProcMngr::AsmProc *>::reverse_iterator i;
for (i=List.begin(); i!=List.end(); i++) for (i=List.rbegin(); i!=List.rend(); i++)
{ {
if ((*i)->pb == true) if ((*i)->pb == true)
{ {

View File

@ -118,3 +118,18 @@ void SymbolList::PrintTable()
printf("Symbol \"%s\" defined on line %d\n", (*i)->sym.c_str(), (*i)->line); printf("Symbol \"%s\" defined on line %d\n", (*i)->sym.c_str(), (*i)->line);
} }
} }
bool SymbolList::EraseSymbol(std::string &sym)
{
std::vector<SymbolList::Symbol *>::iterator i;
for (i=List.begin(); i!=List.end(); i++)
{
if ( (*i)->IsEqual(sym) )
{
List.erase(i);
return true;
}
}
return false;
}

View File

@ -54,6 +54,7 @@ public:
SymbolList::Symbol* AddSymbol(std::string &sym, 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* AddSymbol(const char *szSym, SymbolType type, int line);
SymbolList::Symbol* FindSymbol(std::string &sym); SymbolList::Symbol* FindSymbol(std::string &sym);
bool EraseSymbol(std::string &sym);
void PrintTable(); void PrintTable();
void Clear(); void Clear();
private: private:

View File

@ -28,6 +28,8 @@ int main(int argc, char **argv)
{ {
Compiler Program; Compiler Program;
getchar();
get_options(argc, argv, Program); get_options(argc, argv, Program);
if (filename.size() < 1) if (filename.size() < 1)
@ -38,8 +40,16 @@ int main(int argc, char **argv)
Program.Load(filename); Program.Load(filename);
if (Program.Parse()) if (Program.Parse())
{
//Program.PrintCodeList();
if (Program.Compile()) if (Program.Compile())
printf("Done.\n"); printf("Done.\n");
}
/*ErrorMngr CError(&Program);
std::string f("232+4*4");
int val = Program.Eval(f);
printf("Evaluation: %d\n", val);*/
exit(0); exit(0);
} }

View File

@ -44,6 +44,7 @@ public:
int op; int op;
std::vector<int> params; std::vector<int> params;
int cip; int cip;
int line;
}; };
#include "amx.h" #include "amx.h"

View File

@ -28,6 +28,7 @@ CExpr::CExpr()
numVal = 0; numVal = 0;
type = Val_None; type = Val_None;
block = 0; block = 0;
bDone = false;
CError = NULL; CError = NULL;
} }
@ -36,6 +37,7 @@ CExpr::CExpr(ErrorMngr *e)
numVal = 0; numVal = 0;
type = Val_None; type = Val_None;
block = 0; block = 0;
bDone = false;
CError = e; CError = e;
} }
@ -45,6 +47,7 @@ CExpr::CExpr(ErrorMngr *e, std::string &text)
type = Val_None; type = Val_None;
block = 0; block = 0;
CError = e; CError = e;
bDone = false;
data.assign(text); data.assign(text);
} }
@ -59,7 +62,7 @@ void CExpr::Clear()
CExpr::~CExpr() CExpr::~CExpr()
{ {
if (block) if (block && type == Val_Block)
delete [] block; delete [] block;
} }
@ -180,13 +183,17 @@ const char *CExpr::GetString(int *d)
int CExpr::GetNumber() int CExpr::GetNumber()
{ {
if (type == Val_Float)
{
memcpy((void*)&numVal, (void*)&fData, sizeof(float));
}
return numVal; return numVal;
} }
/* Returns true if the expr can be evaluated */ /* Returns true if the expr can be evaluated */
int CExpr::Analyze() int CExpr::Analyze()
{ {
size_t pos = 0, xc = 0, xpos = 0; size_t pos = 0, xc = 0, xpos = 0, fd = 0;
/* run through the characters */ /* run through the characters */
if (data.compare("$") == 0) if (data.compare("$") == 0)
{ {
@ -194,10 +201,14 @@ int CExpr::Analyze()
} }
for (pos = 0; pos < data.size(); pos++) for (pos = 0; pos < data.size(); pos++)
{ {
if (data[pos] == 'x') if (data[pos] == '.')
{ {
fd++;
if (fd > 1 || xc)
return 0;
} else if (data[pos] == 'x') {
xc++; xc++;
if (xc > 1) if (xc > 1 || fd)
return 0; return 0;
xpos = pos; xpos = pos;
} else if (data[pos] != ' ' } else if (data[pos] != ' '
@ -210,7 +221,7 @@ int CExpr::Analyze()
return 1; return 1;
} }
cExprType CExpr::Evaluate() cExprType CExpr::Evaluate(int symNum)
{ {
size_t i = 0, blk = 0; size_t i = 0, blk = 0;
char litc = 0, c = 0, csave = 0; char litc = 0, c = 0, csave = 0;
@ -218,14 +229,22 @@ cExprType CExpr::Evaluate()
std::string num; std::string num;
block = new char[2]; block = new char[2];
bDone = true;
if (data.compare("$") == 0) if (data.compare("$") == 0)
{ {
t = Val_Number; type = Val_Number;
numVal = CError->CurCip(); numVal = CError->CurCip();
char buf[32]; Update();
sprintf(buf, "%d", numVal); return t;
data.assign(buf); } else {
if (CError->IsSymbol(data) || (IsValidSymbol(data) && symNum == Sym_Label))
{
type = Val_Number;
numVal = CError->DerefSymbol(data, symNum);
Update();
return t;
}
} }
if (data.find('\'', 0) != std::string::npos || data.find('"', 0) != std::string::npos) if (data.find('\'', 0) != std::string::npos || data.find('"', 0) != std::string::npos)
@ -307,7 +326,13 @@ cExprType CExpr::Evaluate()
numVal++; numVal++;
} }
} else { } else {
if (data.find('.', 0) != std::string::npos)
{
/* Get as a float */
fData = (float)atof(data.c_str());
t = Val_Float;
memcpy((void*)&numVal, (void*)&fData, sizeof(float));
} else {
/* Just get the number */ /* Just get the number */
t = Val_Number; t = Val_Number;
numVal = DeHex(data); numVal = DeHex(data);
@ -315,6 +340,7 @@ cExprType CExpr::Evaluate()
sprintf(buf, "%d", numVal); sprintf(buf, "%d", numVal);
data.assign(buf); data.assign(buf);
} }
}
if (litc) if (litc)
{ {
@ -326,3 +352,183 @@ cExprType CExpr::Evaluate()
return t; return t;
} }
void CExpr::Not()
{
if (type != Val_Number)
{
if (CError)
CError->ErrorMsg(Err_Bad_Not);
}
numVal = ~numVal;
}
void CExpr::Oper(OpToken op, CExpr &e)
{
switch (op)
{
case Token_Xor:
{
if (e.GetType() != Val_Number)
{
if (CError)
CError->ErrorMsg(Err_Invalid_Operator);
}
numVal = numVal ^ e.GetNumber();
break;
}
case Token_Shr:
{
if (e.GetType() != Val_Number)
{
if (CError)
CError->ErrorMsg(Err_Invalid_Operator);
}
numVal >>= e.GetNumber();
break;
}
case Token_Sub:
{
if (GetType() == Val_Number)
{
if (e.GetType() == Val_Number)
{
numVal -= e.GetNumber();
} else if (e.GetType() == Val_Float) {
numVal -= (int)e.GetFloat();
}
} else if (GetType() == Val_Float) {
if (e.GetType() == Val_Number)
{
fData -= (float)e.GetNumber();
} else if (e.GetType() == Val_Float) {
fData -= e.GetFloat();
}
}
break;
}
case Token_Mod:
{
if (e.GetType() != Val_Number)
{
if (CError)
CError->ErrorMsg(Err_Invalid_Operator);
}
numVal = numVal % e.GetNumber();
break;
}
case Token_Mul:
{
if (GetType() == Val_Number)
{
if (e.GetType() == Val_Number)
{
numVal *= e.GetNumber();
} else if (e.GetType() == Val_Float) {
numVal *= (int)e.GetFloat();
}
} else if (GetType() == Val_Float) {
if (e.GetType() == Val_Number)
{
fData *= (float)e.GetNumber();
} else if (e.GetType() == Val_Float) {
fData *= e.GetFloat();
}
}
break;
}
case Token_Div:
{
if (GetType() == Val_Number)
{
if (e.GetType() == Val_Number)
{
numVal /= e.GetNumber();
} else if (e.GetType() == Val_Float) {
numVal /= (int)e.GetFloat();
}
} else if (GetType() == Val_Float) {
if (e.GetType() == Val_Number)
{
fData /= (float)e.GetNumber();
} else if (e.GetType() == Val_Float) {
fData /= e.GetFloat();
}
}
break;
}
case Token_Shl:
{
if (e.GetType() != Val_Number)
{
if (CError)
CError->ErrorMsg(Err_Invalid_Operator);
}
numVal <<= e.GetNumber();
break;
}
case Token_And:
{
if (e.GetType() != Val_Number)
{
if (CError)
CError->ErrorMsg(Err_Invalid_Operator);
}
numVal &= e.GetNumber();
break;
}
case Token_Or:
{
if (e.GetType() != Val_Number)
{
if (CError)
CError->ErrorMsg(Err_Invalid_Operator);
}
numVal |= e.GetNumber();
break;
}
case Token_Add:
{
if (GetType() == Val_Number)
{
if (e.GetType() == Val_Number)
{
numVal += e.GetNumber();
} else if (e.GetType() == Val_Float) {
numVal += (int)e.GetFloat();
}
} else if (GetType() == Val_Float) {
if (e.GetType() == Val_Number)
{
fData += (float)e.GetNumber();
} else if (e.GetType() == Val_Float) {
fData += e.GetFloat();
}
}
break;
}
default:
{
numVal = 0;
break;
}
}
Update();
}
void CExpr::Update()
{
if (type == Val_Float)
{
numVal = (int)fData;
} else if (type == Val_Number) {
fData = (float)numVal;
}
if (type != Val_String && type != Val_Block)
{
char buf[24];
sprintf(buf, "%d", numVal);
data.assign(buf);
}
}

View File

@ -27,6 +27,24 @@
* It reads in a symbol and evaluates it. * It reads in a symbol and evaluates it.
*/ */
typedef enum
{
Token_None,
Token_Or,
Token_Xor,
Token_And,
Token_Shr,
Token_Shl,
Token_Mod,
Token_Div,
Token_Mul,
Token_Sub,
Token_Add,
Token_Not,
/* End */
Tokens_Total,
} OpToken;
typedef enum typedef enum
{ {
Val_None, Val_None,
@ -38,6 +56,7 @@ typedef enum
Val_Number, Val_Number,
Val_Block, Val_Block,
Val_Hex, Val_Hex,
Val_Float,
} cExprType; } cExprType;
class CExpr class CExpr
@ -49,13 +68,17 @@ public:
void Set(std::string &text); void Set(std::string &text);
const char *GetString(int *d=NULL); const char *GetString(int *d=NULL);
int Analyze(); int Analyze();
cExprType Evaluate(); cExprType Evaluate(int symNum = 0);
cExprType GetType(); cExprType GetType();
int GetNumber(); int GetNumber();
float GetFloat() { return fData; }
int Size(); int Size();
void Clear(); void Clear();
void Not();
void Oper(OpToken op, CExpr &e);
~CExpr(); ~CExpr();
private: private:
void Update();
char IsHex(char c); char IsHex(char c);
char IsLiteral(char c); char IsLiteral(char c);
int DeHex(std::string blk); int DeHex(std::string blk);
@ -63,7 +86,9 @@ private:
char *block; char *block;
std::string data; std::string data;
cExprType type; cExprType type;
float fData;
int numVal; int numVal;
bool bDone;
private: private:
ErrorMngr *CError; ErrorMngr *CError;
}; };