mirror of https://github.com/marketideas/qasm.git
fixes for nested DO/IF/ELSE/FIN
This commit is contained in:
parent
d86bd06e8e
commit
b154efff36
153
asm.cpp
153
asm.cpp
|
@ -2030,13 +2030,38 @@ restart:
|
||||||
return (res);
|
return (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CLASS::doOFF(void)
|
||||||
|
{
|
||||||
|
bool res=curDO.doskip;
|
||||||
|
std::stack<TDOstruct> tmpstack;
|
||||||
|
TDOstruct doitem;
|
||||||
|
|
||||||
|
uint32_t ct=DOstack.size();
|
||||||
|
if (ct>0)
|
||||||
|
{
|
||||||
|
tmpstack=DOstack;
|
||||||
|
}
|
||||||
|
while(ct>0)
|
||||||
|
{
|
||||||
|
doitem=tmpstack.top();
|
||||||
|
tmpstack.pop();
|
||||||
|
if (doitem.doskip)
|
||||||
|
{
|
||||||
|
res=true;
|
||||||
|
}
|
||||||
|
ct--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(res);
|
||||||
|
}
|
||||||
|
|
||||||
// this function determines if code generation is turned off (IF,DO,LUP,MAC, etc
|
// this function determines if code generation is turned off (IF,DO,LUP,MAC, etc
|
||||||
bool CLASS::codeSkipped(void)
|
bool CLASS::codeSkipped(void)
|
||||||
{
|
{
|
||||||
bool res = false;
|
bool res = false;
|
||||||
|
|
||||||
res = (curLUP.lupskip) ? true : res;
|
res = (curLUP.lupskip) ? true : res;
|
||||||
res = (curDO.doskip) ? true : res;
|
res = doOFF() ? true : res;
|
||||||
res = currentmacro.running ? true : res;
|
res = currentmacro.running ? true : res;
|
||||||
|
|
||||||
//printf("codeskip: %d\n",res);
|
//printf("codeskip: %d\n",res);
|
||||||
|
@ -2062,7 +2087,7 @@ void CLASS::process(void)
|
||||||
char c;
|
char c;
|
||||||
char buff[256];
|
char buff[256];
|
||||||
MerlinLine errLine;
|
MerlinLine errLine;
|
||||||
std::string op, operand, ls;
|
std::string op, realop, operand, ls;
|
||||||
|
|
||||||
pass = 0;
|
pass = 0;
|
||||||
while (pass < 2)
|
while (pass < 2)
|
||||||
|
@ -2116,6 +2141,7 @@ void CLASS::process(void)
|
||||||
//printf("lineno: %d %d |%s|\n",lineno,l,line.operand.c_str());
|
//printf("lineno: %d %d |%s|\n",lineno,l,line.operand.c_str());
|
||||||
|
|
||||||
op = Poco::toLower(line.opcode);
|
op = Poco::toLower(line.opcode);
|
||||||
|
realop = line.opcode;
|
||||||
operand = Poco::toLower(line.operand);
|
operand = Poco::toLower(line.operand);
|
||||||
line.startpc = PC.currentpc;
|
line.startpc = PC.currentpc;
|
||||||
line.linemx = mx;
|
line.linemx = mx;
|
||||||
|
@ -2194,74 +2220,85 @@ void CLASS::process(void)
|
||||||
x = 0;
|
x = 0;
|
||||||
if (op.length() > 0)
|
if (op.length() > 0)
|
||||||
{
|
{
|
||||||
TMacro *mac = NULL;
|
bool skipop = false;
|
||||||
bool inoperand = false;
|
if (doOFF())
|
||||||
mac = findMacro(op);
|
|
||||||
if (mac == NULL)
|
|
||||||
{
|
{
|
||||||
if (op == ">>>") // specal merlin way of calling a macro
|
skipop = true;
|
||||||
|
if ((op == "fin") || (op == "else") || (op == "do") || (op == "if"))
|
||||||
{
|
{
|
||||||
Poco::StringTokenizer tok(operand, ", ", Poco::StringTokenizer::TOK_TRIM |
|
skipop = false;
|
||||||
Poco::StringTokenizer::TOK_IGNORE_EMPTY);
|
|
||||||
std::string s="";
|
|
||||||
if (tok.count()>0)
|
|
||||||
{
|
|
||||||
s=tok[0];
|
|
||||||
}
|
|
||||||
mac = findMacro(s);
|
|
||||||
inoperand = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mac == NULL)
|
if (!skipop)
|
||||||
{
|
{
|
||||||
x = callOpCode(op, line);
|
TMacro *mac = NULL;
|
||||||
}
|
bool inoperand = false;
|
||||||
if (mac != NULL)
|
mac = findMacro(realop);
|
||||||
{
|
if (mac == NULL)
|
||||||
expand_macrostack.push(expand_macro);
|
|
||||||
expand_macro = *mac;
|
|
||||||
|
|
||||||
expand_macro.lines.clear();
|
|
||||||
//printf("mac start=%u end=%u\n", expand_macro.start, expand_macro.end);
|
|
||||||
for (uint32_t lc = expand_macro.start; lc < expand_macro.end; lc++)
|
|
||||||
{
|
{
|
||||||
//printf("pushing %s\n", lines[lc].wholetext.c_str());
|
if (op == ">>>") // specal merlin way of calling a macro
|
||||||
MerlinLine nl(lines[lc].wholetext); // create a new clean line (without errors,data)
|
|
||||||
expand_macro.lines.push_back(nl);
|
|
||||||
}
|
|
||||||
expand_macro.running = true;
|
|
||||||
expand_macro.sourceline = lineno;
|
|
||||||
expand_macro.variables.vars.clear();
|
|
||||||
// set the variables for the macro here SGQ
|
|
||||||
|
|
||||||
std::string parms = line.operand;
|
|
||||||
if (inoperand)
|
|
||||||
{
|
|
||||||
Poco::StringTokenizer tok(parms, ", ", Poco::StringTokenizer::TOK_TRIM |
|
|
||||||
Poco::StringTokenizer::TOK_IGNORE_EMPTY);
|
|
||||||
parms = "";
|
|
||||||
if (tok.count() > 1)
|
|
||||||
{
|
{
|
||||||
parms = tok[1];
|
Poco::StringTokenizer tok(operand, ", ", Poco::StringTokenizer::TOK_TRIM |
|
||||||
|
Poco::StringTokenizer::TOK_IGNORE_EMPTY);
|
||||||
|
std::string s = "";
|
||||||
|
if (tok.count() > 0)
|
||||||
|
{
|
||||||
|
s = tok[0];
|
||||||
|
}
|
||||||
|
mac = findMacro(s);
|
||||||
|
inoperand = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Poco::StringTokenizer tok(parms, ",;", Poco::StringTokenizer::TOK_TRIM |
|
if (mac == NULL)
|
||||||
Poco::StringTokenizer::TOK_IGNORE_EMPTY);
|
|
||||||
|
|
||||||
uint32_t ct = 0;
|
|
||||||
for (auto itr = tok.begin(); itr != tok.end(); ++itr)
|
|
||||||
{
|
{
|
||||||
//evaluate each of these strings, check for errors on pass 2
|
x = callOpCode(op, line);
|
||||||
std::string expr = *itr;
|
}
|
||||||
std::string v = "]" + Poco::NumberFormatter::format(ct + 1);
|
if (mac != NULL)
|
||||||
//printf("var: %s %s\n", v.c_str(), expr.c_str());
|
{
|
||||||
addVariable(v, expr, expand_macro.variables, true);
|
expand_macrostack.push(expand_macro);
|
||||||
ct++;
|
expand_macro = *mac;
|
||||||
|
|
||||||
|
expand_macro.lines.clear();
|
||||||
|
//printf("mac start=%u end=%u\n", expand_macro.start, expand_macro.end);
|
||||||
|
for (uint32_t lc = expand_macro.start; lc < expand_macro.end; lc++)
|
||||||
|
{
|
||||||
|
//printf("pushing %s\n", lines[lc].wholetext.c_str());
|
||||||
|
MerlinLine nl(lines[lc].wholetext); // create a new clean line (without errors,data)
|
||||||
|
expand_macro.lines.push_back(nl);
|
||||||
|
}
|
||||||
|
expand_macro.running = true;
|
||||||
|
expand_macro.sourceline = lineno;
|
||||||
|
expand_macro.variables.vars.clear();
|
||||||
|
// set the variables for the macro here SGQ
|
||||||
|
|
||||||
|
std::string parms = line.operand;
|
||||||
|
if (inoperand)
|
||||||
|
{
|
||||||
|
Poco::StringTokenizer tok(parms, ", ", Poco::StringTokenizer::TOK_TRIM |
|
||||||
|
Poco::StringTokenizer::TOK_IGNORE_EMPTY);
|
||||||
|
parms = "";
|
||||||
|
if (tok.count() > 1)
|
||||||
|
{
|
||||||
|
parms = tok[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Poco::StringTokenizer tok(parms, ",;", Poco::StringTokenizer::TOK_TRIM |
|
||||||
|
Poco::StringTokenizer::TOK_IGNORE_EMPTY);
|
||||||
|
|
||||||
|
uint32_t ct = 0;
|
||||||
|
for (auto itr = tok.begin(); itr != tok.end(); ++itr)
|
||||||
|
{
|
||||||
|
//evaluate each of these strings, check for errors on pass 2
|
||||||
|
std::string expr = *itr;
|
||||||
|
std::string v = "]" + Poco::NumberFormatter::format(ct + 1);
|
||||||
|
//printf("var: %s %s\n", v.c_str(), expr.c_str());
|
||||||
|
addVariable(v, expr, expand_macro.variables, true);
|
||||||
|
ct++;
|
||||||
|
}
|
||||||
|
x = 0;
|
||||||
|
expand_macro.currentline = 0;
|
||||||
}
|
}
|
||||||
x = 0;
|
|
||||||
expand_macro.currentline = 0;
|
|
||||||
}
|
}
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((x > 0) && (codeSkipped())) // has a psuedo-op turned off code generation? (LUP, IF, etc)
|
if ((x > 0) && (codeSkipped())) // has a psuedo-op turned off code generation? (LUP, IF, etc)
|
||||||
|
|
2
asm.h
2
asm.h
|
@ -473,6 +473,8 @@ public:
|
||||||
int substituteVariables(MerlinLine & line, std::string &outop);
|
int substituteVariables(MerlinLine & line, std::string &outop);
|
||||||
|
|
||||||
bool codeSkipped(void);
|
bool codeSkipped(void);
|
||||||
|
bool doOFF(void);
|
||||||
|
|
||||||
|
|
||||||
int parseOperand(MerlinLine &line);
|
int parseOperand(MerlinLine &line);
|
||||||
int getAddrMode(MerlinLine &line);
|
int getAddrMode(MerlinLine &line);
|
||||||
|
|
31
eval.cpp
31
eval.cpp
|
@ -15,6 +15,7 @@ std::ostream& operator<<(std::ostream& os, const Token& token)
|
||||||
|
|
||||||
CLASS::CLASS(T65816Asm &_asm) : assembler(_asm)
|
CLASS::CLASS(T65816Asm &_asm) : assembler(_asm)
|
||||||
{
|
{
|
||||||
|
allowMX = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASS::~CLASS()
|
CLASS::~CLASS()
|
||||||
|
@ -232,20 +233,30 @@ std::deque<Token> CLASS::shuntingYard(const std::deque<Token>& tokens)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sym = assembler.findSymbol(token.str);
|
std::string tok = Poco::toUpper(token.str);
|
||||||
//printf("symbol find |%s| %p\n",token.str.c_str(),sym);
|
if ((tok == "MX") && (allowMX))
|
||||||
|
|
||||||
if (sym != NULL)
|
|
||||||
{
|
{
|
||||||
sym->used = true;
|
//printf("MX EVAL\n");
|
||||||
sprintf(buff, "$%X", sym->value);
|
sprintf(buff,"$%02X",assembler.mx&0x03);
|
||||||
token.str = buff;
|
token.str=buff;;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
setError(Token::unknownSymbolErr);
|
sym = assembler.findSymbol(token.str);
|
||||||
badsymbol = token.str;
|
//printf("symbol find |%s| %p\n",token.str.c_str(),sym);
|
||||||
token.str = "0";
|
|
||||||
|
if (sym != NULL)
|
||||||
|
{
|
||||||
|
sym->used = true;
|
||||||
|
sprintf(buff, "$%X", sym->value);
|
||||||
|
token.str = buff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setError(Token::unknownSymbolErr);
|
||||||
|
badsymbol = token.str;
|
||||||
|
token.str = "0";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
queue.push_back(token);
|
queue.push_back(token);
|
||||||
|
|
1
eval.h
1
eval.h
|
@ -68,6 +68,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
CLASS(T65816Asm &_asm);
|
CLASS(T65816Asm &_asm);
|
||||||
~CLASS();
|
~CLASS();
|
||||||
|
bool allowMX;
|
||||||
std::string badsymbol;
|
std::string badsymbol;
|
||||||
std::deque<Token> shuntingYard(const std::deque<Token>& tokens);
|
std::deque<Token> shuntingYard(const std::deque<Token>& tokens);
|
||||||
std::deque<Token> exprToTokens(const std::string& expr);
|
std::deque<Token> exprToTokens(const std::string& expr);
|
||||||
|
|
|
@ -36,6 +36,7 @@ int CLASS::doDO(T65816Asm &a, MerlinLine &line, TSymbol &opinfo)
|
||||||
UNUSED(opinfo);
|
UNUSED(opinfo);
|
||||||
|
|
||||||
TEvaluator eval(a);
|
TEvaluator eval(a);
|
||||||
|
eval.allowMX=true; // allow the built in MX symbol
|
||||||
|
|
||||||
int64_t eval_value = 0;
|
int64_t eval_value = 0;
|
||||||
uint8_t shift;
|
uint8_t shift;
|
||||||
|
|
Loading…
Reference in New Issue