From 21da3e7536582a95a4be0f00e3931579dac41bcf Mon Sep 17 00:00:00 2001 From: marketideas Date: Thu, 21 Nov 2019 08:47:03 -0800 Subject: [PATCH 1/2] more macros and vars --- asm.cpp | 80 ++++++++++++++++++------------ asm.h | 40 +++++++++------ opcodes.cpp | 1 + psuedo.cpp | 138 ++++++++++++++++++++++++++++++++-------------------- 4 files changed, 161 insertions(+), 98 deletions(-) diff --git a/asm.cpp b/asm.cpp index 2bbe76f..cfce539 100644 --- a/asm.cpp +++ b/asm.cpp @@ -1191,7 +1191,7 @@ out: return (res); } -TSymbol * CLASS::addVariable(std::string symname, std::string val, variable_t &vars, bool replace) +TSymbol * CLASS::addVariable(std::string symname, std::string val, TVariable &vars, bool replace) { TSymbol *res = NULL; TSymbol *fnd = NULL; @@ -1230,18 +1230,27 @@ TSymbol * CLASS::addVariable(std::string symname, std::string val, variable_t &v //printf("addvariable: %s %s\n", s.name.c_str(), s.text.c_str()); std::pair p(sym, s); - vars.insert(p); + vars.vars.insert(p); res = findVariable(sym, vars); return (res); } -TSymbol * CLASS::findVariable(std::string symname, variable_t &vars) +TSymbol * CLASS::findVariable(std::string symname, TVariable &vars) { TSymbol *res = NULL; + if ((expand_macrostack.size() > 0) && (vars.id != expand_macro.variables.id)) + { + res = findVariable(symname, expand_macro.variables); + if (res != NULL) + { + return (res); + } + } + //printf("finding: %s\n",symname.c_str()); - auto itr = vars.find(symname); - if (itr != vars.end()) + auto itr = vars.vars.find(symname); + if (itr != vars.vars.end()) { //printf("Found: %s 0x%08X\n",itr->second.name.c_str(),itr->second.value); res = &itr->second; @@ -1251,13 +1260,13 @@ TSymbol * CLASS::findVariable(std::string symname, variable_t &vars) return (res); } -void CLASS::showVariables(variable_t &vars) +void CLASS::showVariables(TVariable &vars) { - if (variables.size() > 0) + if (vars.vars.size() > 0) { printf("\nVariables:\n"); - for (auto itr = vars.begin(); itr != vars.end(); ++itr) + for (auto itr = vars.vars.begin(); itr != vars.vars.end(); ++itr) { printf("%-16s %s\n", itr->first.c_str(), itr->second.var_text.c_str()); } @@ -1626,7 +1635,7 @@ void CLASS::initpass(void) dumstartaddr = 0; dumstart = 0; truncdata = 0; - variables.clear(); // clear the variables for each pass + variables.vars.clear(); // clear the variables for each pass while (!macrostack.empty()) { @@ -2164,30 +2173,41 @@ void CLASS::process(void) x = 0; if (op.length() > 0) { - TMacro *mac = findMacro(op); - if (mac == NULL) + TMacro *mac = NULL; + if (macrostack.size() == 0) { - x = callOpCode(op, line); - } - else - { - 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++) + mac = findMacro(op); + if (mac == NULL) { - //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); + + if (op == ">>>") // specal merlin way of calling a macro + { + mac = findMacro(operand); + } + else + { + x = callOpCode(op, line); + } + } + 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()); + 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 + expand_macro.currentline = 0; } - expand_macro.running = true; - expand_macro.sourceline = lineno; - expand_macro.variables.clear(); - // set the variables for the macro here SGQ - expand_macro.currentline = 0; - x = 0; } } diff --git a/asm.h b/asm.h index 6565c8e..338d5c2 100644 --- a/asm.h +++ b/asm.h @@ -347,16 +347,28 @@ public: } }; -typedef Poco::HashMap variable_t; +//typedef Poco::HashMap variable_t; + +class TVariable +{ +public: + uint32_t id; + Poco::HashMap vars; + TVariable() + { + // SGQ - must fix this so it is guaranteed unique for each one + id=rand(); + } +}; class TMacro { public: std::string name; std::string lcname; - variable_t variables; + TVariable variables; std::vector lines; - uint32_t start,end,currentline,len; + uint32_t start, end, currentline, len; uint32_t sourceline; bool running; @@ -366,15 +378,15 @@ public: } void clear(void) { - name=""; - lcname=""; - variables.clear(); + name = ""; + lcname = ""; + variables.vars.clear(); lines.clear(); - sourceline=0; - currentline=0; - len=0; + sourceline = 0; + currentline = 0; + len = 0; start = 0; - end=0; + end = 0; running = false; } }; @@ -410,7 +422,7 @@ public: Poco::HashMap macros; Poco::HashMap opcodes; Poco::HashMap symbols; - variable_t variables; + TVariable variables; TOriginSection PC; TLUPstruct curLUP; @@ -447,15 +459,15 @@ public: TSymbol *findSymbol(std::string sym); TSymbol *addSymbol(std::string sym, uint32_t val, bool replace); - TSymbol *findVariable(std::string sym, variable_t &vars); - TSymbol *addVariable(std::string sym, std::string val, variable_t &vars,bool replace); + TSymbol *findVariable(std::string sym, TVariable &vars); + TSymbol *addVariable(std::string sym, std::string val, TVariable &vars, bool replace); void initpass(void); void showSymbolTable(bool alpha); void showMacros(bool alpha); - void showVariables(variable_t &vars); + void showVariables(TVariable &vars); int evaluate(MerlinLine &line, std::string expr, int64_t &value); int substituteVariables(MerlinLine & line, std::string &outop); diff --git a/opcodes.cpp b/opcodes.cpp index 6909fb2..e77cea7 100644 --- a/opcodes.cpp +++ b/opcodes.cpp @@ -888,6 +888,7 @@ void CLASS::insertOpcodes(void) pushopcode("MAC", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("EOM", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("<<<", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); + pushopcode(">>>", P_MAC, OP_PSUEDO, OPHANDLER(&CLASS::doPSEUDO)); pushopcode("ADC", 0x03, OP_STD | OP_A, OPHANDLER(&CLASS::doBase6502)); diff --git a/psuedo.cpp b/psuedo.cpp index e8d4a45..d8eb9e5 100644 --- a/psuedo.cpp +++ b/psuedo.cpp @@ -35,6 +35,14 @@ int CLASS::doDO(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) { UNUSED(opinfo); + + if (a.macrostack.size()>0) + { + // if defining a macro, do nothing with this + return(0); + } + + TEvaluator eval(a); int64_t eval_value = 0; @@ -165,6 +173,10 @@ int CLASS::doMAC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) // don't need to do anything on pass > 0 } } + else if (op==">>>") + { + // don't do anything here, let the macro call handler stuff do ths (asm.cpp) + } else // it is EOM or <<< { if (a.macrostack.size() > 0) @@ -211,78 +223,96 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) std::string op = Poco::toUpper(line.opcode); - if (op == "LUP") + if (a.macrostack.size() == 0) // if defining a macro (size>0), don't process here { - line.flags |= FLAG_NOLINEPRINT; - len = line.lineno - 1; // MerlinLine line numbers are +1 from actual array idx - if (len >= 0) + if (op == "LUP") { - - shift = 0; - eval_value = 0; - int x = eval.evaluate(line.operand_expr, eval_value, shift); - - a.LUPstack.push(a.curLUP); - - a.curLUP.lupoffset = len; - a.curLUP.lupct = eval_value & 0xFFFF; // evaluate here - a.curLUP.luprunning++; - - if ((x < 0) || (eval_value <= 0) || (eval_value > 0x8000)) + line.flags |= FLAG_NOLINEPRINT; + len = line.lineno - 1; // MerlinLine line numbers are +1 from actual array idx + if (len >= 0) { - // merlin just ignores LUP if the value is out of range - a.curLUP.lupct = 0; - a.curLUP.lupskip = true; - } - } - else - { - err = errUnexpectedOp; - } - } - if (op == "--^") - { - line.flags |= FLAG_NOLINEPRINT; + shift = 0; + eval_value = 0; + int x = eval.evaluate(line.operand_expr, eval_value, shift); - if (a.curLUP.luprunning > 0) - { - lidx = line.lineno - 1; - len = lidx - a.curLUP.lupoffset - 1; + a.LUPstack.push(a.curLUP); - if (a.curLUP.lupct > 0) - { - a.curLUP.lupct--; - if (a.curLUP.lupct != 0) + if (a.expand_macrostack.size() > 0) { - a.lineno = a.curLUP.lupoffset; - goto out; + a.curLUP.lupoffset = a.expand_macro.currentline; } - } - // kind of a silent error here, just make sure we reinitialize - a.curLUP.luprunning = 0; - a.curLUP.lupct = 0; - a.curLUP.lupskip = false; + else + { + a.curLUP.lupoffset = len; + } + a.curLUP.lupct = eval_value & 0xFFFF; // evaluate here + a.curLUP.luprunning++; - //printf("start=%d end=%d len=%d\n", a.curLUP.lupoffset, lidx, len); - if (a.LUPstack.size() > 0) - { - a.curLUP = a.LUPstack.top(); - a.LUPstack.pop(); + if ((x < 0) || (eval_value <= 0) || (eval_value > 0x8000)) + { + // merlin just ignores LUP if the value is out of range + a.curLUP.lupct = 0; + a.curLUP.lupskip = true; + } } else { err = errUnexpectedOp; } } - else + + if (op == "--^") { - a.curLUP.lupskip = false; - // SGQ - found a '--^' without a LUP, should we just ignore? - //err = errUnexpectedOp; + line.flags |= FLAG_NOLINEPRINT; + + if (a.curLUP.luprunning > 0) + { + + + lidx = line.lineno - 1; + len = lidx - a.curLUP.lupoffset - 1; + + if (a.curLUP.lupct > 0) + { + a.curLUP.lupct--; + if (a.curLUP.lupct != 0) + { + if (a.expand_macrostack.size() > 0) + { + a.expand_macro.currentline=a.curLUP.lupoffset; + } + else + { + a.lineno = a.curLUP.lupoffset; + } + goto out; + } + } + // kind of a silent error here, just make sure we reinitialize + a.curLUP.luprunning = 0; + a.curLUP.lupct = 0; + a.curLUP.lupskip = false; + + //printf("start=%d end=%d len=%d\n", a.curLUP.lupoffset, lidx, len); + if (a.LUPstack.size() > 0) + { + a.curLUP = a.LUPstack.top(); + a.LUPstack.pop(); + } + else + { + err = errUnexpectedOp; + } + } + else + { + a.curLUP.lupskip = false; + // SGQ - found a '--^' without a LUP, should we just ignore? + //err = errUnexpectedOp; + } } } - out: if (err > 0) { From d86bd06e8e2c8f83d27c34f57b3fcec26a37f018 Mon Sep 17 00:00:00 2001 From: marketideas Date: Thu, 21 Nov 2019 18:14:30 -0800 Subject: [PATCH 2/2] macros with vars now working --- asm.cpp | 115 +++++++++++++++++++++++++++++----------- psuedo.cpp | 151 +++++++++++++++++++++++++---------------------------- 2 files changed, 154 insertions(+), 112 deletions(-) diff --git a/asm.cpp b/asm.cpp index cfce539..85cc331 100644 --- a/asm.cpp +++ b/asm.cpp @@ -1371,6 +1371,17 @@ int CLASS::callOpCode(std::string op, MerlinLine &line) char c; std::string s; +// during MACRO definition no opcodes are called (except for MAC, EOM, <<) + if (macrostack.size() > 0) + { + // if something on the macro stack, then a macro is being defined + std::string upop = Poco::toUpper(op); + if (!((upop == "MAC") || (upop == "EOM") || (upop == "<<<"))) + { + return 0; + } + } + if (op.length() == 4) // check for 4 digit 'L' opcodes { c = op[3] & 0x7F; @@ -1966,7 +1977,16 @@ restart: off = mVec[0].offset; len = mVec[0].length; s = oper.substr(off, len); - sym = findVariable(s, variables); + + sym = NULL; + if (expand_macrostack.size() > 0) + { + sym = findVariable(s, expand_macro.variables); + } + if (sym == NULL) + { + sym = findVariable(s, variables); + } if (sym != NULL) { //printf("match |%s|\n",sym->var_text.c_str()); @@ -2001,7 +2021,7 @@ restart: done = true; } } - //printf("inoper=|%s| outoper=|%s|\n",operin.c_str(),oper.c_str()); +//printf("inoper=|%s| outoper=|%s|\n",operin.c_str(),oper.c_str()); if (ct > 0) { outop = oper; @@ -2148,6 +2168,7 @@ void CLASS::process(void) x = substituteVariables(line, outop); if (x > 0) { + line.printoperand = outop; line.operand = outop; } x = parseOperand(line); @@ -2174,41 +2195,73 @@ void CLASS::process(void) if (op.length() > 0) { TMacro *mac = NULL; - if (macrostack.size() == 0) + bool inoperand = false; + mac = findMacro(op); + if (mac == NULL) { - mac = findMacro(op); - if (mac == NULL) + if (op == ">>>") // specal merlin way of calling a macro { - - if (op == ">>>") // specal merlin way of calling a macro + Poco::StringTokenizer tok(operand, ", ", Poco::StringTokenizer::TOK_TRIM | + Poco::StringTokenizer::TOK_IGNORE_EMPTY); + std::string s=""; + if (tok.count()>0) { - mac = findMacro(operand); + s=tok[0]; } - else - { - x = callOpCode(op, line); - } - } - 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()); - 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 - expand_macro.currentline = 0; + mac = findMacro(s); + inoperand = true; } } + if (mac == NULL) + { + x = callOpCode(op, line); + } + 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()); + 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; + } + //} } if ((x > 0) && (codeSkipped())) // has a psuedo-op turned off code generation? (LUP, IF, etc) diff --git a/psuedo.cpp b/psuedo.cpp index d8eb9e5..9f17d6d 100644 --- a/psuedo.cpp +++ b/psuedo.cpp @@ -35,14 +35,6 @@ int CLASS::doDO(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) { UNUSED(opinfo); - - if (a.macrostack.size()>0) - { - // if defining a macro, do nothing with this - return(0); - } - - TEvaluator eval(a); int64_t eval_value = 0; @@ -173,7 +165,7 @@ int CLASS::doMAC(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) // don't need to do anything on pass > 0 } } - else if (op==">>>") + else if (op == ">>>") { // don't do anything here, let the macro call handler stuff do ths (asm.cpp) } @@ -223,94 +215,91 @@ int CLASS::doLUP(T65816Asm &a, MerlinLine &line, TSymbol &opinfo) std::string op = Poco::toUpper(line.opcode); - if (a.macrostack.size() == 0) // if defining a macro (size>0), don't process here + if (op == "LUP") { - if (op == "LUP") + line.flags |= FLAG_NOLINEPRINT; + len = line.lineno - 1; // MerlinLine line numbers are +1 from actual array idx + if (len >= 0) { - line.flags |= FLAG_NOLINEPRINT; - len = line.lineno - 1; // MerlinLine line numbers are +1 from actual array idx - if (len >= 0) + + shift = 0; + eval_value = 0; + int x = eval.evaluate(line.operand_expr, eval_value, shift); + + a.LUPstack.push(a.curLUP); + + if (a.expand_macrostack.size() > 0) { + a.curLUP.lupoffset = a.expand_macro.currentline; + } + else + { + a.curLUP.lupoffset = len; + } + a.curLUP.lupct = eval_value & 0xFFFF; // evaluate here + a.curLUP.luprunning++; - shift = 0; - eval_value = 0; - int x = eval.evaluate(line.operand_expr, eval_value, shift); + if ((x < 0) || (eval_value <= 0) || (eval_value > 0x8000)) + { + // merlin just ignores LUP if the value is out of range + a.curLUP.lupct = 0; + a.curLUP.lupskip = true; + } + } + else + { + err = errUnexpectedOp; + } + } - a.LUPstack.push(a.curLUP); + if (op == "--^") + { + line.flags |= FLAG_NOLINEPRINT; - if (a.expand_macrostack.size() > 0) + if (a.curLUP.luprunning > 0) + { + + + lidx = line.lineno - 1; + len = lidx - a.curLUP.lupoffset - 1; + + if (a.curLUP.lupct > 0) + { + a.curLUP.lupct--; + if (a.curLUP.lupct != 0) { - a.curLUP.lupoffset = a.expand_macro.currentline; + if (a.expand_macrostack.size() > 0) + { + a.expand_macro.currentline = a.curLUP.lupoffset; + } + else + { + a.lineno = a.curLUP.lupoffset; + } + goto out; } - else - { - a.curLUP.lupoffset = len; - } - a.curLUP.lupct = eval_value & 0xFFFF; // evaluate here - a.curLUP.luprunning++; + } + // kind of a silent error here, just make sure we reinitialize + a.curLUP.luprunning = 0; + a.curLUP.lupct = 0; + a.curLUP.lupskip = false; - if ((x < 0) || (eval_value <= 0) || (eval_value > 0x8000)) - { - // merlin just ignores LUP if the value is out of range - a.curLUP.lupct = 0; - a.curLUP.lupskip = true; - } + //printf("start=%d end=%d len=%d\n", a.curLUP.lupoffset, lidx, len); + if (a.LUPstack.size() > 0) + { + a.curLUP = a.LUPstack.top(); + a.LUPstack.pop(); } else { err = errUnexpectedOp; } } - - if (op == "--^") + else { - line.flags |= FLAG_NOLINEPRINT; - - if (a.curLUP.luprunning > 0) - { - - - lidx = line.lineno - 1; - len = lidx - a.curLUP.lupoffset - 1; - - if (a.curLUP.lupct > 0) - { - a.curLUP.lupct--; - if (a.curLUP.lupct != 0) - { - if (a.expand_macrostack.size() > 0) - { - a.expand_macro.currentline=a.curLUP.lupoffset; - } - else - { - a.lineno = a.curLUP.lupoffset; - } - goto out; - } - } - // kind of a silent error here, just make sure we reinitialize - a.curLUP.luprunning = 0; - a.curLUP.lupct = 0; - a.curLUP.lupskip = false; - - //printf("start=%d end=%d len=%d\n", a.curLUP.lupoffset, lidx, len); - if (a.LUPstack.size() > 0) - { - a.curLUP = a.LUPstack.top(); - a.LUPstack.pop(); - } - else - { - err = errUnexpectedOp; - } - } - else - { - a.curLUP.lupskip = false; - // SGQ - found a '--^' without a LUP, should we just ignore? - //err = errUnexpectedOp; - } + a.curLUP.lupskip = false; + // SGQ - found a '--^' without a LUP, should we just ignore? + //err = errUnexpectedOp; } } out: