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:
parent
74d278d1c6
commit
7acc70ee62
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user