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 */
PROC = new ProcMngr;
/* Load Label management */
CLabels = new LabelMngr;
CLabels = new LabelMngr(CError);
/* Load Native management */
CNatives = new NativeMngr;
/* Load the default symbols + opcodes */
@ -155,7 +155,6 @@ bool Compiler::Compile()
AddrTable a;
n.Name = (*pl)->Symbol->sym.c_str();
a.addr = (*pl)->ASM->cip;
printf("%s cip = %d\n", n.Name, a.addr);
a.offset = (int)Nametbl.size();
Nametbl.push_back(n);
PublicsTable.push_back(a);
@ -582,6 +581,7 @@ bool Compiler::Parse()
} else if (params.size() < 1 && code[code.size()-1] == ':') {
/* Label! */
/* Check if symbol is valid */
code.erase(code.size()-1, 1);
if (!IsValidSymbol(code))
{
CError->ErrorMsg(Err_Invalid_Symbol);
@ -590,7 +590,17 @@ bool Compiler::Parse()
/* Check if the symbol is already used */
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;
}
S = CSymbols->AddSymbol(code, Sym_Label, CurLine());
@ -620,6 +630,8 @@ bool Compiler::Parse()
ASM = new Asm;
curAsm = ASM;
std::vector<std::string *> paramList;
if (params.size() > 0)
@ -1419,6 +1431,9 @@ bool Compiler::Parse()
} /* Line processing */
} /* While */
/* We're not done! Check the label Queue */
CLabels->CompleteQueue();
CError->PrintReport();
return true;
@ -1574,6 +1589,13 @@ void Compiler::InitOpcodes()
CSymbols->AddSymbol("PROC", Sym_Reserved, 0);
CSymbols->AddSymbol("ENDP", 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)
@ -1813,7 +1835,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);
}
if (def.size() < 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)))
{
bpstr.assign(str.substr(pos, i-pos));
Strip(bpstr);
e.Set(bpstr);
val = 0;
if (!e.Analyze() && IsValidSymbol(bpstr))
{
SymbolList::Symbol *S = NULL;
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;
}
}
val = DerefSymbol(bpstr, sym);
} else if (e.Analyze() && (e.Evaluate() == Val_Number)) {
val = e.GetNumber();
} else {
assert(0);
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
@ -1959,81 +1915,15 @@ int Compiler::Eval(std::string &str, SymbolType sym)
if (pos < i)
{
bpstr.assign(str.substr(pos, i-pos));
Strip(bpstr);
e.Set(bpstr);
val = 0;
if (!e.Analyze() && IsValidSymbol(bpstr))
{
SymbolList::Symbol *S = NULL;
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;
}
}
val = DerefSymbol(bpstr, sym);
} else if (e.Analyze() && (e.Evaluate() == Val_Number)) {
val = e.GetNumber();
} else {
assert(0);
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
@ -2047,78 +1937,15 @@ int Compiler::Eval(std::string &str, SymbolType sym)
if (pos < i)
{
bpstr.assign(str.substr(pos, i-pos));
Strip(bpstr);
e.Set(bpstr);
val = 0;
if (!e.Analyze() && IsValidSymbol(bpstr))
{
SymbolList::Symbol *S = NULL;
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;
}
}
val = DerefSymbol(bpstr, sym);
} else if (e.Analyze() && (e.Evaluate() == Val_Number)) {
val = e.GetNumber();
} else {
assert(0);
CError->ErrorMsg(Err_Invalid_Symbol);
return 0;
}
@ -2128,7 +1955,12 @@ int Compiler::Eval(std::string &str, SymbolType sym)
delete r;
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]);
return 0;
}
@ -2145,81 +1977,16 @@ int Compiler::Eval(std::string &str, SymbolType sym)
}
if (pos < i || pos == i)
{
Strip(bpstr);
e.Set(bpstr);
val = 0;
if (!e.Analyze() && IsValidSymbol(bpstr))
{
SymbolList::Symbol *S = NULL;
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;
}
}
val = DerefSymbol(bpstr, sym);
} else if (e.Analyze() && (e.Evaluate() == Val_Number)) {
val = e.GetNumber();
} else {
CError->ErrorMsg(Err_Invalid_Symbol);
assert(0);
return 0;
}
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();
int CipCount();
int CurCip() { return lastCip; }
Asm *CurAsm() { return curAsm; }
bool SetDebug();
public: //private
int DerefSymbol(std::string &str, SymbolType sym = Sym_None);
void ProcessDirective(std::string &text);
void Init();
void InitOpcodes();
@ -110,6 +112,7 @@ private:
int cellsize;
int stacksize;
bool debug;
Asm *curAsm;
};
#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->e = expr;
D->fill = fill;
D->db = db;
int size = 0;

View File

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

View File

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

View File

@ -27,6 +27,12 @@ LabelMngr::~LabelMngr()
Clear();
}
LabelMngr::Label::Label()
{
cip = -1;
sym = 0;
}
void LabelMngr::Clear()
{
std::vector<LabelMngr::Label *>::iterator i;
@ -65,6 +71,54 @@ LabelMngr::Label *LabelMngr::FindLabel(std::string &sym)
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)
{
LabelMngr::Label *p = NULL;

View File

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

View File

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

View File

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

View File

@ -28,6 +28,8 @@ int main(int argc, char **argv)
{
Compiler Program;
getchar();
get_options(argc, argv, Program);
if (filename.size() < 1)

View File

@ -188,6 +188,10 @@ int CExpr::Analyze()
{
size_t pos = 0, xc = 0, xpos = 0;
/* run through the characters */
if (data.compare("$") == 0)
{
return 1;
}
for (pos = 0; pos < data.size(); pos++)
{
if (data[pos] == 'x')
@ -215,12 +219,48 @@ cExprType CExpr::Evaluate()
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)
{
/* STRESS TEST */
for (i=0; i<data.size(); 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 (litc == IsLiteral(c))
@ -267,6 +307,7 @@ cExprType CExpr::Evaluate()
numVal++;
}
} else {
/* Just get the number */
t = Val_Number;
numVal = DeHex(data);