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;
|
||||
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());
|
||||
char buffer[256] = {0};
|
||||
std::stack<int> DefStack;
|
||||
std::stack<std::string> LabelStack;
|
||||
curLine = 0;
|
||||
AsmSection sec = Asm_None;
|
||||
lastCip = 0-cellsize;
|
||||
|
@ -347,7 +348,7 @@ bool Compiler::Parse()
|
|||
while (!fp.eof())
|
||||
{
|
||||
fp.getline(buffer, 255);
|
||||
curLine++;
|
||||
curLine+=1;
|
||||
|
||||
/* Check for preprocessor directives */
|
||||
if (buffer[0] == '#')
|
||||
|
@ -440,6 +441,14 @@ bool Compiler::Parse()
|
|||
sec = Asm_Invalid;
|
||||
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 {
|
||||
/* Do pre-processing */
|
||||
CMacros->SearchAndReplace(line);
|
||||
|
@ -501,7 +510,7 @@ bool Compiler::Parse()
|
|||
t.Evaluate();
|
||||
e.Set(amt);
|
||||
e.Evaluate();
|
||||
DAT->Add(symbol, e, false, (char)t.GetNumber());
|
||||
DAT->Add(symbol, e, false, t.GetNumber());
|
||||
} else {
|
||||
e.Set(data);
|
||||
e.Evaluate();
|
||||
|
@ -570,6 +579,7 @@ bool Compiler::Parse()
|
|||
Asm *ASM = new Asm;
|
||||
ASM->cip = lastCip + cellsize;
|
||||
ASM->op = OpCodes["proc"];
|
||||
ASM->line = curLine;
|
||||
lastCip += cellsize;
|
||||
/* Add symbol */
|
||||
S = CSymbols->AddSymbol(params, Sym_Proc, CurLine());
|
||||
|
@ -578,7 +588,16 @@ bool Compiler::Parse()
|
|||
/* Add to PROC list */
|
||||
PROC->AddProc(S, ASM);
|
||||
} 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] == ':') {
|
||||
/* Label! */
|
||||
/* Check if symbol is valid */
|
||||
|
@ -604,6 +623,10 @@ bool Compiler::Parse()
|
|||
}
|
||||
continue;
|
||||
}
|
||||
if (code[0] == '_')
|
||||
{
|
||||
LabelStack.push(code);
|
||||
}
|
||||
S = CSymbols->AddSymbol(code, Sym_Label, CurLine());
|
||||
CLabels->AddLabel(S, lastCip+cellsize);
|
||||
} else {
|
||||
|
@ -623,6 +646,7 @@ bool Compiler::Parse()
|
|||
ASM = new Asm;
|
||||
ASM->cip = lastCip+cellsize;
|
||||
ASM->op = OP_LINE;
|
||||
ASM->line = curLine;
|
||||
ASM->params.push_back(curLine);
|
||||
ASM->params.push_back(0);
|
||||
CodeList.push_back(ASM);
|
||||
|
@ -647,6 +671,7 @@ bool Compiler::Parse()
|
|||
|
||||
ASM->cip = (lastCip+cellsize);
|
||||
ASM->op = op;
|
||||
ASM->line = curLine;
|
||||
lastCip += cellsize;
|
||||
|
||||
switch (op)
|
||||
|
@ -1801,7 +1826,7 @@ void Compiler::ProcessDirective(std::string &text)
|
|||
SymbolList::Symbol *S;
|
||||
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 */
|
||||
std::string argstring;
|
||||
|
@ -1827,8 +1852,22 @@ void Compiler::ProcessDirective(std::string &text)
|
|||
CSymbols->AddSymbol(symbol, Sym_Macro, curLine);
|
||||
//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")) {
|
||||
std::string symbol;
|
||||
std::string def;
|
||||
|
@ -1859,8 +1898,6 @@ int Compiler::Eval(std::string &str, SymbolType sym)
|
|||
int i = 0;
|
||||
rpn *r = new rpn;
|
||||
int pos = 0;
|
||||
int val = 0;
|
||||
CExpr e;
|
||||
|
||||
Stack.push(r);
|
||||
|
||||
|
@ -1890,18 +1927,10 @@ int Compiler::Eval(std::string &str, SymbolType sym)
|
|||
{
|
||||
bpstr.assign(str.substr(pos, i-pos));
|
||||
Strip(bpstr);
|
||||
CExpr e(CError);
|
||||
e.Set(bpstr);
|
||||
val = 0;
|
||||
if (!e.Analyze() && IsValidSymbol(bpstr))
|
||||
{
|
||||
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);
|
||||
e.Evaluate(sym);
|
||||
r->vals.push_back(e);
|
||||
}
|
||||
r->ops.push_back(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));
|
||||
Strip(bpstr);
|
||||
CExpr e(CError);
|
||||
e.Set(bpstr);
|
||||
val = 0;
|
||||
if (!e.Analyze() && IsValidSymbol(bpstr))
|
||||
{
|
||||
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);
|
||||
e.Evaluate(sym);
|
||||
r->vals.push_back(e);
|
||||
}
|
||||
r = new rpn;
|
||||
Stack.push(r);
|
||||
|
@ -1939,20 +1960,13 @@ int Compiler::Eval(std::string &str, SymbolType sym)
|
|||
{
|
||||
bpstr.assign(str.substr(pos, i-pos));
|
||||
Strip(bpstr);
|
||||
CExpr e(CError);
|
||||
e.Set(bpstr);
|
||||
val = 0;
|
||||
if (!e.Analyze() && IsValidSymbol(bpstr))
|
||||
{
|
||||
val = DerefSymbol(bpstr, sym);
|
||||
} else if (e.Analyze() && (e.Evaluate() == Val_Number)) {
|
||||
val = e.GetNumber();
|
||||
} else {
|
||||
CError->ErrorMsg(Err_Invalid_Symbol);
|
||||
return 0;
|
||||
e.Evaluate(sym);
|
||||
r->vals.push_back(e);
|
||||
}
|
||||
r->vals.push_back(val);
|
||||
}
|
||||
val = EvalRpn(r, sym);
|
||||
CExpr t;
|
||||
t = EvalRpn(r, sym);
|
||||
delete r;
|
||||
if (Stack.size() < 2)
|
||||
{
|
||||
|
@ -1967,7 +1981,7 @@ int Compiler::Eval(std::string &str, SymbolType sym)
|
|||
}
|
||||
Stack.pop();
|
||||
r = Stack.top();
|
||||
r->vals.push_back(val);
|
||||
r->vals.push_back(t);
|
||||
pos = i + 1;
|
||||
} else if (i == (int)(str.size() - 1)) {
|
||||
if (pos < i)
|
||||
|
@ -1979,18 +1993,10 @@ int Compiler::Eval(std::string &str, SymbolType sym)
|
|||
if (pos < i || pos == i)
|
||||
{
|
||||
Strip(bpstr);
|
||||
CExpr e(CError);
|
||||
e.Set(bpstr);
|
||||
val = 0;
|
||||
if (!e.Analyze() && IsValidSymbol(bpstr))
|
||||
{
|
||||
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);
|
||||
e.Evaluate(sym);
|
||||
r->vals.push_back(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2009,19 +2015,18 @@ int Compiler::Eval(std::string &str, SymbolType sym)
|
|||
|
||||
rpn *r2 = Stack.top();
|
||||
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;
|
||||
char c = 0;
|
||||
int lval = 0;
|
||||
int rval = 0;
|
||||
int nval = 0;
|
||||
std::vector<int>::iterator Q;
|
||||
CExpr er, el;
|
||||
std::vector<CExpr>::iterator Q;
|
||||
std::vector<char>::iterator R;
|
||||
|
||||
while (r->ops.size())
|
||||
|
@ -2035,77 +2040,17 @@ int Compiler::EvalRpn(rpn *r, SymbolType sym)
|
|||
{
|
||||
if ((int)r->vals.size() <= j)
|
||||
assert(0);// Can't have more ops than values
|
||||
lval = r->vals[j];
|
||||
el = r->vals[j];
|
||||
if (i != Token_Not)
|
||||
{
|
||||
if ((int)r->vals.size() <= j+1)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
rval = r->vals[j+1];
|
||||
}
|
||||
switch (i)
|
||||
{
|
||||
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;
|
||||
}
|
||||
er = r->vals[j+1];
|
||||
el.Oper((OpToken)i, er);
|
||||
} else {
|
||||
el.Not();
|
||||
}
|
||||
R = r->ops.begin();
|
||||
Q = r->vals.begin();
|
||||
|
@ -2114,13 +2059,13 @@ int Compiler::EvalRpn(rpn *r, SymbolType sym)
|
|||
R += j;
|
||||
Q += j;
|
||||
r->ops.erase(R);
|
||||
r->vals[j+1] = nval;
|
||||
r->vals[j+1] = el;
|
||||
r->vals.erase(Q);
|
||||
j--;
|
||||
} else {
|
||||
R += j;
|
||||
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;
|
||||
}
|
||||
|
||||
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; \
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
//TODO: use linked lists, but not std::list
|
||||
std::vector<char> ops;
|
||||
std::vector<int> vals;
|
||||
std::vector<CExpr> vals;
|
||||
};
|
||||
|
||||
class Compiler
|
||||
|
@ -91,9 +73,10 @@ public: //private
|
|||
void Init();
|
||||
void InitOpcodes();
|
||||
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);
|
||||
char OperChar(OpToken c);
|
||||
bool IsSymbol(std::string &str);
|
||||
private:
|
||||
std::vector<Asm *> CodeList;
|
||||
std::map<std::string,int> OpCodes;
|
||||
|
|
|
@ -47,7 +47,7 @@ DataMngr::Datum::Datum()
|
|||
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();
|
||||
|
||||
|
@ -63,7 +63,7 @@ void DataMngr::Add(std::string &s, CExpr &expr, bool db, char fill)
|
|||
size = ((D->e.GetType() == Val_Number) ?
|
||||
cellsize : D->e.Size() * cellsize);
|
||||
} else {
|
||||
size = D->e.GetNumber();
|
||||
size = (D->e.GetNumber() * cellsize);
|
||||
}
|
||||
|
||||
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) ?
|
||||
cellsize : p->e.Size() * cellsize);
|
||||
} else {
|
||||
D->offset = p->offset + p->e.GetNumber();
|
||||
D->offset = p->offset + (p->e.GetNumber() * cellsize);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,13 +34,13 @@ public:
|
|||
CExpr e;
|
||||
bool db;
|
||||
int offset;
|
||||
char fill;
|
||||
int fill;
|
||||
};
|
||||
public:
|
||||
~DataMngr();
|
||||
DataMngr() { cellsize = 4; lastOffset = 0; cursize = 0; }
|
||||
DataMngr(int cell) { lastOffset = 0; cellsize = cell; cursize = 0; }
|
||||
void Add(std::string &s, CExpr &expr, bool db = false, char fill = 0);
|
||||
void Add(std::string &s, CExpr &expr, bool db = false, int fill = 0);
|
||||
DataMngr::Datum *FindData(std::string &sym);
|
||||
void GetData(std::vector<DataMngr::Datum *> &dList);
|
||||
int GetOffset(std::string &sym);
|
||||
|
|
|
@ -26,6 +26,7 @@ ErrorMngr::ErrorMngr()
|
|||
{
|
||||
printf("Not instantiated with a compiler.");
|
||||
Cmp = NULL;
|
||||
line = -1;
|
||||
assert(Cmp);
|
||||
}
|
||||
|
||||
|
@ -56,6 +57,7 @@ ErrorMngr::ErrorMngr(void *c)
|
|||
Totals[1] = 0;
|
||||
Totals[2] = 0;
|
||||
Totals[3] = 0;
|
||||
line = -1;
|
||||
HighestError = Err_None;
|
||||
}
|
||||
|
||||
|
@ -95,6 +97,9 @@ void ErrorMngr::DefineErrors()
|
|||
List.at(Err_Unknown_Define) = "Unknown define referenced";
|
||||
List.at(Err_Misplaced_Directive) = "Misplaced preprocessor directive";
|
||||
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_FileOpen) = "Could not open file \"%s\"";
|
||||
|
@ -131,13 +136,23 @@ void ErrorMngr::ErrorMsg(ErrorCode error, ...)
|
|||
if (type == -1)
|
||||
return;
|
||||
|
||||
int curLine = 0;
|
||||
|
||||
if (line == -1)
|
||||
{
|
||||
curLine = ((Compiler *)Cmp)->CurLine();
|
||||
} else {
|
||||
curLine = line;
|
||||
line = -1;
|
||||
}
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, error);
|
||||
|
||||
if (((Compiler *)Cmp)->CurLine() == -1)
|
||||
sprintf(errbuf, "%s(%d): %s\n", ErrorSwi[type], error, GetError(error));
|
||||
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);
|
||||
|
||||
va_end(argptr);
|
||||
|
@ -164,3 +179,18 @@ const char *ErrorMngr::GetError(ErrorCode id)
|
|||
return NULL;
|
||||
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_Misplaced_Directive,
|
||||
Err_Bad_Label,
|
||||
Err_Bad_Not,
|
||||
Err_Invalid_Operator,
|
||||
Err_Invalid_Pragma,
|
||||
errors_end,
|
||||
|
||||
fatals_start,
|
||||
|
@ -87,6 +90,7 @@ private:
|
|||
ErrorType HighestError;
|
||||
void *Cmp;
|
||||
int Totals[4];
|
||||
int line;
|
||||
public:
|
||||
ErrorMngr();
|
||||
ErrorMngr(void *c);
|
||||
|
@ -96,6 +100,9 @@ public:
|
|||
void PrintReport();
|
||||
int CurLine();
|
||||
int CurCip();
|
||||
void SetLine(int ln);
|
||||
int DerefSymbol(std::string &str, int sym = 0);
|
||||
bool IsSymbol(std::string &str);
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_AMX_ERROR
|
||||
|
|
|
@ -91,7 +91,7 @@ void LabelMngr::QueueLabel(std::string &sym, Asm *ASM)
|
|||
LQ[d].push(ASM);
|
||||
}
|
||||
|
||||
void LabelMngr::CompleteQueue()
|
||||
void LabelMngr::CompleteQueue(bool isLocal)
|
||||
{
|
||||
std::map<std::string,std::stack<Asm *> >::iterator i;
|
||||
std::stack<Asm *> *stk = 0;
|
||||
|
@ -106,8 +106,16 @@ void LabelMngr::CompleteQueue()
|
|||
stk = &((*i).second);
|
||||
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())
|
||||
{
|
||||
ASM = stk->top();
|
||||
|
@ -115,6 +123,7 @@ void LabelMngr::CompleteQueue()
|
|||
stk->pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LQ.clear();
|
||||
}
|
||||
|
@ -130,3 +139,19 @@ int LabelMngr::GetCip(std::string &sym)
|
|||
|
||||
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();
|
||||
bool SetCip(std::string &sym, int cip);
|
||||
void QueueLabel(std::string &sym, Asm *ASM);
|
||||
void CompleteQueue();
|
||||
void CompleteQueue(bool isLocal = false);
|
||||
bool EraseLabel(std::string &sym);
|
||||
private:
|
||||
std::vector<LabelMngr::Label *> List;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -118,3 +118,18 @@ void SymbolList::PrintTable()
|
|||
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(const char *szSym, SymbolType type, int line);
|
||||
SymbolList::Symbol* FindSymbol(std::string &sym);
|
||||
bool EraseSymbol(std::string &sym);
|
||||
void PrintTable();
|
||||
void Clear();
|
||||
private:
|
||||
|
|
|
@ -28,6 +28,8 @@ int main(int argc, char **argv)
|
|||
{
|
||||
Compiler Program;
|
||||
|
||||
getchar();
|
||||
|
||||
get_options(argc, argv, Program);
|
||||
|
||||
if (filename.size() < 1)
|
||||
|
@ -38,8 +40,16 @@ int main(int argc, char **argv)
|
|||
|
||||
Program.Load(filename);
|
||||
if (Program.Parse())
|
||||
{
|
||||
//Program.PrintCodeList();
|
||||
if (Program.Compile())
|
||||
printf("Done.\n");
|
||||
}
|
||||
/*ErrorMngr CError(&Program);
|
||||
std::string f("232+4*4");
|
||||
int val = Program.Eval(f);
|
||||
|
||||
printf("Evaluation: %d\n", val);*/
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
int op;
|
||||
std::vector<int> params;
|
||||
int cip;
|
||||
int line;
|
||||
};
|
||||
|
||||
#include "amx.h"
|
||||
|
|
|
@ -28,6 +28,7 @@ CExpr::CExpr()
|
|||
numVal = 0;
|
||||
type = Val_None;
|
||||
block = 0;
|
||||
bDone = false;
|
||||
CError = NULL;
|
||||
}
|
||||
|
||||
|
@ -36,6 +37,7 @@ CExpr::CExpr(ErrorMngr *e)
|
|||
numVal = 0;
|
||||
type = Val_None;
|
||||
block = 0;
|
||||
bDone = false;
|
||||
CError = e;
|
||||
}
|
||||
|
||||
|
@ -45,6 +47,7 @@ CExpr::CExpr(ErrorMngr *e, std::string &text)
|
|||
type = Val_None;
|
||||
block = 0;
|
||||
CError = e;
|
||||
bDone = false;
|
||||
data.assign(text);
|
||||
}
|
||||
|
||||
|
@ -59,7 +62,7 @@ void CExpr::Clear()
|
|||
|
||||
CExpr::~CExpr()
|
||||
{
|
||||
if (block)
|
||||
if (block && type == Val_Block)
|
||||
delete [] block;
|
||||
}
|
||||
|
||||
|
@ -180,13 +183,17 @@ const char *CExpr::GetString(int *d)
|
|||
|
||||
int CExpr::GetNumber()
|
||||
{
|
||||
if (type == Val_Float)
|
||||
{
|
||||
memcpy((void*)&numVal, (void*)&fData, sizeof(float));
|
||||
}
|
||||
return numVal;
|
||||
}
|
||||
|
||||
/* Returns true if the expr can be evaluated */
|
||||
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 */
|
||||
if (data.compare("$") == 0)
|
||||
{
|
||||
|
@ -194,10 +201,14 @@ int CExpr::Analyze()
|
|||
}
|
||||
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++;
|
||||
if (xc > 1)
|
||||
if (xc > 1 || fd)
|
||||
return 0;
|
||||
xpos = pos;
|
||||
} else if (data[pos] != ' '
|
||||
|
@ -210,7 +221,7 @@ int CExpr::Analyze()
|
|||
return 1;
|
||||
}
|
||||
|
||||
cExprType CExpr::Evaluate()
|
||||
cExprType CExpr::Evaluate(int symNum)
|
||||
{
|
||||
size_t i = 0, blk = 0;
|
||||
char litc = 0, c = 0, csave = 0;
|
||||
|
@ -218,14 +229,22 @@ cExprType CExpr::Evaluate()
|
|||
std::string num;
|
||||
|
||||
block = new char[2];
|
||||
bDone = true;
|
||||
|
||||
if (data.compare("$") == 0)
|
||||
{
|
||||
t = Val_Number;
|
||||
type = Val_Number;
|
||||
numVal = CError->CurCip();
|
||||
char buf[32];
|
||||
sprintf(buf, "%d", numVal);
|
||||
data.assign(buf);
|
||||
Update();
|
||||
return t;
|
||||
} 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)
|
||||
|
@ -307,7 +326,13 @@ cExprType CExpr::Evaluate()
|
|||
numVal++;
|
||||
}
|
||||
} 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 */
|
||||
t = Val_Number;
|
||||
numVal = DeHex(data);
|
||||
|
@ -315,6 +340,7 @@ cExprType CExpr::Evaluate()
|
|||
sprintf(buf, "%d", numVal);
|
||||
data.assign(buf);
|
||||
}
|
||||
}
|
||||
|
||||
if (litc)
|
||||
{
|
||||
|
@ -326,3 +352,183 @@ cExprType CExpr::Evaluate()
|
|||
|
||||
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.
|
||||
*/
|
||||
|
||||
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
|
||||
{
|
||||
Val_None,
|
||||
|
@ -38,6 +56,7 @@ typedef enum
|
|||
Val_Number,
|
||||
Val_Block,
|
||||
Val_Hex,
|
||||
Val_Float,
|
||||
} cExprType;
|
||||
|
||||
class CExpr
|
||||
|
@ -49,13 +68,17 @@ public:
|
|||
void Set(std::string &text);
|
||||
const char *GetString(int *d=NULL);
|
||||
int Analyze();
|
||||
cExprType Evaluate();
|
||||
cExprType Evaluate(int symNum = 0);
|
||||
cExprType GetType();
|
||||
int GetNumber();
|
||||
float GetFloat() { return fData; }
|
||||
int Size();
|
||||
void Clear();
|
||||
void Not();
|
||||
void Oper(OpToken op, CExpr &e);
|
||||
~CExpr();
|
||||
private:
|
||||
void Update();
|
||||
char IsHex(char c);
|
||||
char IsLiteral(char c);
|
||||
int DeHex(std::string blk);
|
||||
|
@ -63,7 +86,9 @@ private:
|
|||
char *block;
|
||||
std::string data;
|
||||
cExprType type;
|
||||
float fData;
|
||||
int numVal;
|
||||
bool bDone;
|
||||
private:
|
||||
ErrorMngr *CError;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user