Fixed labels so they can be referenced before creation.

Cleaned up symbol parsing code.
Reversed order of public table.
Fixed bug with macro arguments.
This commit is contained in:
David Anderson 2004-08-09 08:43:27 +00:00
parent b14708d6f2
commit 85afb2a823
11 changed files with 238 additions and 275 deletions

View File

@ -86,7 +86,7 @@ void Compiler::Init()
/* Load Proc management */ /* Load Proc management */
PROC = new ProcMngr; PROC = new ProcMngr;
/* Load Label management */ /* Load Label management */
CLabels = new LabelMngr; CLabels = new LabelMngr(CError);
/* Load Native management */ /* Load Native management */
CNatives = new NativeMngr; CNatives = new NativeMngr;
/* Load the default symbols + opcodes */ /* Load the default symbols + opcodes */
@ -155,7 +155,6 @@ bool Compiler::Compile()
AddrTable a; AddrTable a;
n.Name = (*pl)->Symbol->sym.c_str(); n.Name = (*pl)->Symbol->sym.c_str();
a.addr = (*pl)->ASM->cip; a.addr = (*pl)->ASM->cip;
printf("%s cip = %d\n", n.Name, a.addr);
a.offset = (int)Nametbl.size(); a.offset = (int)Nametbl.size();
Nametbl.push_back(n); Nametbl.push_back(n);
PublicsTable.push_back(a); PublicsTable.push_back(a);
@ -582,6 +581,7 @@ bool Compiler::Parse()
} 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 */
code.erase(code.size()-1, 1);
if (!IsValidSymbol(code)) if (!IsValidSymbol(code))
{ {
CError->ErrorMsg(Err_Invalid_Symbol); CError->ErrorMsg(Err_Invalid_Symbol);
@ -590,7 +590,17 @@ bool Compiler::Parse()
/* Check if the symbol is already used */ /* Check if the symbol is already used */
if ( (S = CSymbols->FindSymbol(code)) != NULL) if ( (S = CSymbols->FindSymbol(code)) != NULL)
{ {
CError->ErrorMsg(Err_Invalid_Symbol, code.c_str(), S->line); if (S->type == Sym_Label)
{
LabelMngr::Label *p = CLabels->FindLabel(code);
if (p == NULL)
CError->ErrorMsg(Err_Invalid_Symbol);
else
p->cip = lastCip+cellsize;
continue;
} else {
CError->ErrorMsg(Err_Symbol_Reuse, code.c_str(), S->line);
}
continue; continue;
} }
S = CSymbols->AddSymbol(code, Sym_Label, CurLine()); S = CSymbols->AddSymbol(code, Sym_Label, CurLine());
@ -620,6 +630,8 @@ bool Compiler::Parse()
ASM = new Asm; ASM = new Asm;
curAsm = ASM;
std::vector<std::string *> paramList; std::vector<std::string *> paramList;
if (params.size() > 0) if (params.size() > 0)
@ -1419,6 +1431,9 @@ bool Compiler::Parse()
} /* Line processing */ } /* Line processing */
} /* While */ } /* While */
/* We're not done! Check the label Queue */
CLabels->CompleteQueue();
CError->PrintReport(); CError->PrintReport();
return true; return true;
@ -1574,6 +1589,13 @@ void Compiler::InitOpcodes()
CSymbols->AddSymbol("PROC", Sym_Reserved, 0); CSymbols->AddSymbol("PROC", Sym_Reserved, 0);
CSymbols->AddSymbol("ENDP", Sym_Reserved, 0); CSymbols->AddSymbol("ENDP", Sym_Reserved, 0);
CSymbols->AddSymbol("stat", Sym_Reserved, 0); CSymbols->AddSymbol("stat", Sym_Reserved, 0);
char buf[24];
sprintf(buf, "%d", cellsize?cellsize:4);
std::string CellDef("CELL");
std::string Cell(buf);
CDefines->AddDefine(CellDef, Cell);
CSymbols->AddSymbol("CELL", Sym_Define, 0);
} }
char Compiler::OperChar(OpToken c) char Compiler::OperChar(OpToken c)
@ -1813,7 +1835,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);
} }
if (def.size() < 1) if (def.size() < 1)
def.assign("1"); def.assign("1");
@ -1866,81 +1888,15 @@ int Compiler::Eval(std::string &str, SymbolType sym)
if (pos < i || (pos == i && (OperToken(str[i]) == Token_Sub))) if (pos < i || (pos == i && (OperToken(str[i]) == Token_Sub)))
{ {
bpstr.assign(str.substr(pos, i-pos)); bpstr.assign(str.substr(pos, i-pos));
Strip(bpstr);
e.Set(bpstr); e.Set(bpstr);
val = 0; val = 0;
if (!e.Analyze() && IsValidSymbol(bpstr)) if (!e.Analyze() && IsValidSymbol(bpstr))
{ {
SymbolList::Symbol *S = NULL; val = DerefSymbol(bpstr, sym);
if ( (S = CSymbols->FindSymbol(bpstr)) == NULL)
{
CError->ErrorMsg(Err_Unknown_Symbol, bpstr.c_str());
assert(0);
return 0;
}
if (sym != Sym_Dat && S->type != sym)
{
assert(0);
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
switch (S->type)
{
case Sym_Proc:
{
val = PROC->GetCip(bpstr);
if (val == ProcMngr::ncip)
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
}
break;
}
case Sym_Native:
{
val = CNatives->GetNativeId(bpstr);
if (val == NativeMngr::ncip)
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
}
break;
}
case Sym_Dat:
{
val = DAT->GetOffset(bpstr);
if (val == DataMngr::nof)
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
}
break;
}
case Sym_Label:
{
val = CLabels->GetCip(bpstr);
if (val == LabelMngr::ncip)
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
}
break;
}
default:
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
break;
}
}
} else if (e.Analyze() && (e.Evaluate() == Val_Number)) { } else if (e.Analyze() && (e.Evaluate() == Val_Number)) {
val = e.GetNumber(); val = e.GetNumber();
} else { } else {
assert(0);
CError->ErrorMsg(Err_Invalid_Symbol); CError->ErrorMsg(Err_Invalid_Symbol);
return 0; return 0;
} }
@ -1959,81 +1915,15 @@ int Compiler::Eval(std::string &str, SymbolType sym)
if (pos < i) if (pos < i)
{ {
bpstr.assign(str.substr(pos, i-pos)); bpstr.assign(str.substr(pos, i-pos));
Strip(bpstr);
e.Set(bpstr); e.Set(bpstr);
val = 0; val = 0;
if (!e.Analyze() && IsValidSymbol(bpstr)) if (!e.Analyze() && IsValidSymbol(bpstr))
{ {
SymbolList::Symbol *S = NULL; val = DerefSymbol(bpstr, sym);
if ( (S = CSymbols->FindSymbol(bpstr)) == NULL)
{
CError->ErrorMsg(Err_Unknown_Symbol, bpstr.c_str());
assert(0);
return 0;
}
if (sym != Sym_Dat && S->type != sym)
{
assert(0);
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
switch (S->type)
{
case Sym_Proc:
{
val = PROC->GetCip(bpstr);
if (val == ProcMngr::ncip)
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
}
break;
}
case Sym_Native:
{
val = CNatives->GetNativeId(bpstr);
if (val == NativeMngr::ncip)
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
}
break;
}
case Sym_Dat:
{
val = DAT->GetOffset(bpstr);
if (val == DataMngr::nof)
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
}
break;
}
case Sym_Label:
{
val = CLabels->GetCip(bpstr);
if (val == LabelMngr::ncip)
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
}
break;
}
default:
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
break;
}
}
} else if (e.Analyze() && (e.Evaluate() == Val_Number)) { } else if (e.Analyze() && (e.Evaluate() == Val_Number)) {
val = e.GetNumber(); val = e.GetNumber();
} else { } else {
assert(0);
CError->ErrorMsg(Err_Invalid_Symbol); CError->ErrorMsg(Err_Invalid_Symbol);
return 0; return 0;
} }
@ -2047,78 +1937,15 @@ int Compiler::Eval(std::string &str, SymbolType sym)
if (pos < i) if (pos < i)
{ {
bpstr.assign(str.substr(pos, i-pos)); bpstr.assign(str.substr(pos, i-pos));
Strip(bpstr);
e.Set(bpstr); e.Set(bpstr);
val = 0; val = 0;
if (!e.Analyze() && IsValidSymbol(bpstr)) if (!e.Analyze() && IsValidSymbol(bpstr))
{ {
SymbolList::Symbol *S = NULL; val = DerefSymbol(bpstr, sym);
if ( (S = CSymbols->FindSymbol(bpstr)) == NULL)
{
CError->ErrorMsg(Err_Unknown_Symbol, bpstr.c_str());
assert(0);
return 0;
}
if (sym != Sym_Dat && S->type != sym)
{
assert(0);
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
switch (S->type)
{
case Sym_Proc:
{
val = PROC->GetCip(bpstr);
if (val == ProcMngr::ncip)
{
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
break;
}
case Sym_Native:
{
val = CNatives->GetNativeId(bpstr);
if (val == NativeMngr::ncip)
{
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
break;
}
case Sym_Dat:
{
val = DAT->GetOffset(bpstr);
if (val == DataMngr::nof)
{
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
break;
}
case Sym_Label:
{
val = CLabels->GetCip(bpstr);
if (val == LabelMngr::ncip)
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
}
break;
}
default:
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
break;
}
}
} else if (e.Analyze() && (e.Evaluate() == Val_Number)) { } else if (e.Analyze() && (e.Evaluate() == Val_Number)) {
val = e.GetNumber(); val = e.GetNumber();
} else { } else {
assert(0);
CError->ErrorMsg(Err_Invalid_Symbol); CError->ErrorMsg(Err_Invalid_Symbol);
return 0; return 0;
} }
@ -2128,7 +1955,12 @@ int Compiler::Eval(std::string &str, SymbolType sym)
delete r; delete r;
if (Stack.size() < 2) if (Stack.size() < 2)
{ {
//TODO: Clear memory while (Stack.size())
{
if (Stack.top())
delete Stack.top();
Stack.pop();
}
CError->ErrorMsg(Err_Unmatched_Token, str[i]); CError->ErrorMsg(Err_Unmatched_Token, str[i]);
return 0; return 0;
} }
@ -2145,81 +1977,16 @@ int Compiler::Eval(std::string &str, SymbolType sym)
} }
if (pos < i || pos == i) if (pos < i || pos == i)
{ {
Strip(bpstr);
e.Set(bpstr); e.Set(bpstr);
val = 0; val = 0;
if (!e.Analyze() && IsValidSymbol(bpstr)) if (!e.Analyze() && IsValidSymbol(bpstr))
{ {
SymbolList::Symbol *S = NULL; val = DerefSymbol(bpstr, sym);
if ( (S = CSymbols->FindSymbol(bpstr)) == NULL)
{
CError->ErrorMsg(Err_Unknown_Symbol, bpstr.c_str());
assert(0);
return 0;
}
if (sym != Sym_Dat && S->type != sym)
{
assert(0);
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
switch (S->type)
{
case Sym_Proc:
{
val = PROC->GetCip(bpstr);
if (val == ProcMngr::ncip)
{
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
break;
}
case Sym_Native:
{
val = CNatives->GetNativeId(bpstr);
if (val == NativeMngr::ncip)
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
}
break;
}
case Sym_Dat:
{
val = DAT->GetOffset(bpstr);
if (val == DataMngr::nof)
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
}
break;
}
case Sym_Label:
{
val = CLabels->GetCip(bpstr);
if (val == LabelMngr::ncip)
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
}
break;
}
default:
{
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
break;
}
}
} else if (e.Analyze() && (e.Evaluate() == Val_Number)) { } else if (e.Analyze() && (e.Evaluate() == Val_Number)) {
val = e.GetNumber(); val = e.GetNumber();
} else { } else {
CError->ErrorMsg(Err_Invalid_Symbol); CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0; return 0;
} }
r->vals.push_back(val); r->vals.push_back(val);
@ -2389,3 +2156,79 @@ void Compiler::PrintCodeList()
} }
} }
} }
int Compiler::DerefSymbol(std::string &str, SymbolType sym)
{
int val = 0;
SymbolList::Symbol *S = NULL;
if ( ((S = CSymbols->FindSymbol(str)) == NULL) )
{
if (sym == Sym_Label)
{
S = CSymbols->AddSymbol(str, Sym_Label, -1);
} else {
CError->ErrorMsg(Err_Unknown_Symbol, str.c_str());
return 0;
}
}
if (sym != Sym_Dat && S->type != sym)
{
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
switch (S->type)
{
case Sym_Proc:
{
val = PROC->GetCip(str);
if (val == ProcMngr::ncip)
{
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
break;
}
case Sym_Native:
{
val = CNatives->GetNativeId(str);
if (val == NativeMngr::ncip)
{
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
break;
}
case Sym_Dat:
{
val = DAT->GetOffset(str);
if (val == DataMngr::nof)
{
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
break;
}
case Sym_Label:
{
val = CLabels->GetCip(str);
if (val == LabelMngr::ncip)
{
/* Labels we handle differently.
Add it to the label queue
*/
CLabels->AddLabel(S, LabelMngr::ncip);
CLabels->QueueLabel(str, CurAsm());
}
break;
}
default:
{
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
break;
}
}
return val;
}

View File

@ -83,8 +83,10 @@ public:
void Clear(); void Clear();
int CipCount(); int CipCount();
int CurCip() { return lastCip; } int CurCip() { return lastCip; }
Asm *CurAsm() { return curAsm; }
bool SetDebug(); bool SetDebug();
public: //private public: //private
int DerefSymbol(std::string &str, SymbolType sym = Sym_None);
void ProcessDirective(std::string &text); void ProcessDirective(std::string &text);
void Init(); void Init();
void InitOpcodes(); void InitOpcodes();
@ -110,6 +112,7 @@ private:
int cellsize; int cellsize;
int stacksize; int stacksize;
bool debug; bool debug;
Asm *curAsm;
}; };
#endif //_INCLUDE_AMXCOMPILER_H #endif //_INCLUDE_AMXCOMPILER_H

View File

@ -54,6 +54,7 @@ void DataMngr::Add(std::string &s, CExpr &expr, bool db, char fill)
D->symbol.assign(s); D->symbol.assign(s);
D->e = expr; D->e = expr;
D->fill = fill; D->fill = fill;
D->db = db;
int size = 0; int size = 0;

View File

@ -93,7 +93,8 @@ void ErrorMngr::DefineErrors()
List.at(Err_Unmatched_Token) = "Unmatched token '%c'"; List.at(Err_Unmatched_Token) = "Unmatched token '%c'";
List.at(Err_Param_Count) = "Expected %d parameters, found %d"; List.at(Err_Param_Count) = "Expected %d parameters, found %d";
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_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\"";

View File

@ -59,6 +59,7 @@ typedef enum
Err_Param_Count, Err_Param_Count,
Err_Unknown_Define, Err_Unknown_Define,
Err_Misplaced_Directive, Err_Misplaced_Directive,
Err_Bad_Label,
errors_end, errors_end,
fatals_start, fatals_start,

View File

@ -27,6 +27,12 @@ LabelMngr::~LabelMngr()
Clear(); Clear();
} }
LabelMngr::Label::Label()
{
cip = -1;
sym = 0;
}
void LabelMngr::Clear() void LabelMngr::Clear()
{ {
std::vector<LabelMngr::Label *>::iterator i; std::vector<LabelMngr::Label *>::iterator i;
@ -65,6 +71,54 @@ LabelMngr::Label *LabelMngr::FindLabel(std::string &sym)
return NULL; return NULL;
} }
bool LabelMngr::SetCip(std::string &sym, int cip)
{
LabelMngr::Label *p = NULL;
p = FindLabel(sym);
if (p == NULL)
return false;
p->cip = cip;
return true;
}
void LabelMngr::QueueLabel(std::string &sym, Asm *ASM)
{
std::string d(sym);
LQ[d].push(ASM);
}
void LabelMngr::CompleteQueue()
{
std::map<std::string,std::stack<Asm *> >::iterator i;
std::stack<Asm *> *stk = 0;
std::string search;
Asm *ASM = 0;
LabelMngr::Label *p = 0;
for (i=LQ.begin(); i!=LQ.end(); i++)
{
search.assign( (*i).first );
p = FindLabel(search);
stk = &((*i).second);
if (p == NULL || p->cip == LabelMngr::ncip)
{
CError->ErrorMsg(Err_Bad_Label);
}
while (!stk->empty())
{
ASM = stk->top();
ASM->params[0] = p->cip;
stk->pop();
}
}
LQ.clear();
}
int LabelMngr::GetCip(std::string &sym) int LabelMngr::GetCip(std::string &sym)
{ {
LabelMngr::Label *p = NULL; LabelMngr::Label *p = NULL;

View File

@ -29,17 +29,25 @@ public:
class Label class Label
{ {
public: public:
Label();
SymbolList::Symbol *sym; SymbolList::Symbol *sym;
int cip; int cip;
}; };
public: public:
~LabelMngr(); ~LabelMngr();
LabelMngr() { CError = NULL; assert(CError!=NULL); }
LabelMngr(ErrorMngr *e) { CError = e; }
void AddLabel(SymbolList::Symbol *sym, int cip); void AddLabel(SymbolList::Symbol *sym, int cip);
LabelMngr::Label *FindLabel(std::string &sym); LabelMngr::Label *FindLabel(std::string &sym);
int GetCip(std::string &sym); int GetCip(std::string &sym);
void Clear(); void Clear();
bool SetCip(std::string &sym, int cip);
void QueueLabel(std::string &sym, Asm *ASM);
void CompleteQueue();
private: private:
std::vector<LabelMngr::Label *> List; std::vector<LabelMngr::Label *> List;
std::map<std::string, std::stack<Asm *> > LQ;
ErrorMngr *CError;
public: public:
static const int ncip = -1; static const int ncip = -1;
}; };

View File

@ -152,7 +152,7 @@ void MacroList::SearchAndReplace(std::string &text)
symPos = pos + (int)m->symbol.size(); symPos = pos + (int)m->symbol.size();
argstring.assign(text.substr(symPos+1, text.size()-symPos)); argstring.assign(text.substr(symPos+1, text.size()-symPos));
std::vector<std::string *> argList; std::vector<std::string *> argList;
((Compiler *)Cmp)->FindArguments(argstring, argList, bPos); ((Compiler *)Cmp)->FindArguments(argstring, argList, bPos, true);
/* Build the macro */ /* Build the macro */
std::string *ms; std::string *ms;
ms = BeginReplacement(m); ms = BeginReplacement(m);

View File

@ -111,6 +111,15 @@ void Strip(std::string &text)
{ {
int i = 0; int i = 0;
if (text.size() == 1)
{
if (isspace(text[0]))
{
text.clear();
return;
}
}
for (i=0; i<(int)text.size(); i++) for (i=0; i<(int)text.size(); i++)
{ {
if (!isspace(text[i])) if (!isspace(text[i]))

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)

View File

@ -188,6 +188,10 @@ int CExpr::Analyze()
{ {
size_t pos = 0, xc = 0, xpos = 0; size_t pos = 0, xc = 0, xpos = 0;
/* run through the characters */ /* run through the characters */
if (data.compare("$") == 0)
{
return 1;
}
for (pos = 0; pos < data.size(); pos++) for (pos = 0; pos < data.size(); pos++)
{ {
if (data[pos] == 'x') if (data[pos] == 'x')
@ -215,12 +219,48 @@ cExprType CExpr::Evaluate()
block = new char[2]; block = new char[2];
if (data.compare("$") == 0)
{
t = Val_Number;
numVal = CError->CurCip();
char buf[32];
sprintf(buf, "%d", numVal);
data.assign(buf);
}
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)
{ {
/* STRESS TEST */ /* STRESS TEST */
for (i=0; i<data.size(); i++) for (i=0; i<data.size(); i++)
{ {
c = data[i]; c = data[i];
if (c == '\\')
{
if (i == data.size() - 1)
{
if (CError)
CError->ErrorMsg(Err_String_Terminate);
t = Val_Error;
} else {
char cp = data[i+1];
char *nc = 0;
if (cp == 't')
nc = "\t";
else if (cp == 'n')
nc = "\n";
else if (cp == '\\')
nc = "\\";
else if (cp == '"')
nc = "\"";
else if (cp == '\'')
nc = "'";
if (nc)
{
data.replace(i, 2, nc);
continue;
}
}
}
if (IsLiteral(c) != 0) if (IsLiteral(c) != 0)
{ {
if (litc == IsLiteral(c)) if (litc == IsLiteral(c))
@ -267,6 +307,7 @@ cExprType CExpr::Evaluate()
numVal++; numVal++;
} }
} else { } else {
/* Just get the number */ /* Just get the number */
t = Val_Number; t = Val_Number;
numVal = DeHex(data); numVal = DeHex(data);