all tests assemble, ]vars seem to be working

This commit is contained in:
marketideas 2019-11-19 11:27:17 -08:00
parent 4fa1c51549
commit 2e6f8af54e
5 changed files with 134 additions and 61 deletions

173
asm.cpp
View File

@ -2,6 +2,9 @@
#include "asm.h" #include "asm.h"
#include "eval.h" #include "eval.h"
#include "psuedo.h" #include "psuedo.h"
#include <sys/ioctl.h>
#include <unistd.h>
#define CLASS MerlinLine #define CLASS MerlinLine
@ -99,7 +102,7 @@ void CLASS::print(uint32_t lineno)
} }
} }
bool empty = false; bool empty = false;
if ((printlable == "") && (opcode == "") && (operand == "")) if ((printlable == "") && (opcode == "") && (printoperand == ""))
{ {
empty = true; empty = true;
} }
@ -202,7 +205,7 @@ void CLASS::print(uint32_t lineno)
{ {
pcol += printf(" "); pcol += printf(" ");
} }
pcol += printf("%s ", operand.c_str()); pcol += printf("%s ", printoperand.c_str());
//pcol += printf("%-12s %-8s %-10s ", printlable.c_str(), opcode.c_str(), operand.c_str()); //pcol += printf("%-12s %-8s %-10s ", printlable.c_str(), opcode.c_str(), operand.c_str());
} }
if ((errorcode > 0) && (!merlinerrors)) if ((errorcode > 0) && (!merlinerrors))
@ -287,6 +290,7 @@ void CLASS::clear()
opcode = ""; opcode = "";
opcodelower = ""; opcodelower = "";
operand = ""; operand = "";
printoperand="";
comment = ""; comment = "";
operand_expr = ""; operand_expr = "";
operand_expr2 = ""; operand_expr2 = "";
@ -494,7 +498,7 @@ void CLASS::set(std::string line)
if (x > 1) if (x > 1)
{ {
// M32 syntax allows a colon after lable, and it is not part of the lable // M32 syntax allows a colon after lable, and it is not part of the lable
if ((syntax & SYNTAX_MERLIN32)==SYNTAX_MERLIN32) if ((syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32)
{ {
while ((x > 1) && (lable[x - 1] == ':')) while ((x > 1) && (lable[x - 1] == ':'))
{ {
@ -513,7 +517,20 @@ void CLASS::set(std::string line)
CLASS::CLASS() CLASS::CLASS()
{ {
int x;
errorct = 0; errorct = 0;
win_columns = -1;
win_rows = -1;
struct winsize w;
x = ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
if (x == 0)
{
win_columns = w.ws_col;
win_rows = w.ws_row;
}
//printf("cols=%d rows=%d\n",win_columns,win_rows);
} }
CLASS::~CLASS() CLASS::~CLASS()
@ -1158,7 +1175,7 @@ TSymbol * CLASS::addVariable(std::string symname, std::string val, bool replace)
if (fnd != NULL) if (fnd != NULL)
{ {
//printf("replacing symbol: %s %08X\n",sym.c_str(),val); //printf("replacing symbol: %s %08X\n",sym.c_str(),val);
fnd->text = val; fnd->var_text = val;
return (fnd); return (fnd);
} }
@ -1168,7 +1185,7 @@ TSymbol * CLASS::addVariable(std::string symname, std::string val, bool replace)
s.namelc = Poco::toLower(sym); s.namelc = Poco::toLower(sym);
s.stype = 0; s.stype = 0;
s.value = 0; s.value = 0;
s.text = val; s.var_text = val;
s.used = false; s.used = false;
s.cb = NULL; s.cb = NULL;
@ -1185,7 +1202,7 @@ TSymbol * CLASS::findVariable(std::string symname)
TSymbol *res = NULL; TSymbol *res = NULL;
//printf("finding: %s\n",symname.c_str()); //printf("finding: %s\n",symname.c_str());
auto itr = variables.find(Poco::toUpper(symname)); auto itr = variables.find(symname);
if (itr != variables.end()) if (itr != variables.end())
{ {
//printf("Found: %s 0x%08X\n",itr->second.name.c_str(),itr->second.value); //printf("Found: %s 0x%08X\n",itr->second.name.c_str(),itr->second.value);
@ -1204,7 +1221,7 @@ void CLASS::showVariables(void)
for (auto itr = variables.begin(); itr != variables.end(); ++itr) for (auto itr = variables.begin(); itr != variables.end(); ++itr)
{ {
printf("%-16s %s\n", itr->first.c_str(), itr->second.text.c_str()); printf("%-16s %s\n", itr->first.c_str(), itr->second.var_text.c_str());
} }
printf("\n"); printf("\n");
} }
@ -1310,12 +1327,23 @@ int CLASS::callOpCode(std::string op, MerlinLine &line)
case '>': case '>':
line.expr_value >>= 8; line.expr_value >>= 8;
line.expr_value &= 0xFFFF; line.expr_value &= 0xFFFF;
if ((line.syntax&SYNTAX_MERLIN32)==SYNTAX_MERLIN32)
{
line.flags |= FLAG_FORCEABS;
}
break; break;
case '^': case '^':
line.expr_value = (line.expr_value >> 16) & 0xFFFF; line.expr_value = (line.expr_value >> 16) & 0xFFFF;
if ((line.syntax&SYNTAX_MERLIN32)==SYNTAX_MERLIN32)
{
line.flags |= FLAG_FORCEABS;
}
break; break;
case '|': case '|':
line.flags |= FLAG_FORCELONG; if ((line.syntax&SYNTAX_MERLIN32)!=SYNTAX_MERLIN32)
{
line.flags |= FLAG_FORCELONG;
}
break; break;
} }
if (line.expr_value >= 0x100) if (line.expr_value >= 0x100)
@ -1496,7 +1524,7 @@ void CLASS::initpass(void)
lastcarry = false; lastcarry = false;
relocatable = false; relocatable = false;
currentsym = NULL; currentsym = NULL;
if ((syntax & SYNTAX_MERLIN32)==SYNTAX_MERLIN32) if ((syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32)
{ {
// M32 allows locals that don't have a global above. this is the catchall for that // M32 allows locals that don't have a global above. this is the catchall for that
currentsym = &topSymbol; // this is the default symbol for :locals without a global above; currentsym = &topSymbol; // this is the default symbol for :locals without a global above;
@ -1704,7 +1732,7 @@ int CLASS::getAddrMode(MerlinLine & line)
// symbol is defined later, we will generate different // symbol is defined later, we will generate different
// bytes on the next pass // bytes on the next pass
if ((line.syntax&SYNTAX_MERLIN32) == SYNTAX_MERLIN32) if ((line.syntax & SYNTAX_MERLIN32) == SYNTAX_MERLIN32)
{ {
if (Poco::toUpper(oper) == "A") // check the whole operand, not just the expression if (Poco::toUpper(oper) == "A") // check the whole operand, not just the expression
{ {
@ -1780,63 +1808,93 @@ int CLASS::parseOperand(MerlinLine & line)
return (res); return (res);
} }
int CLASS::substituteVariables(MerlinLine & line) int CLASS::substituteVariables(MerlinLine & line, std::string &outop)
{ {
int res = -1; int res = 0;
int x; int x;
std::string::size_type offset, slen; std::string::size_type offset, slen;
std::string oper = line.operand; std::string oper = line.operand;
std::string s; std::string s;
std::string operin;
TSymbol *sym; TSymbol *sym;
uint32_t len, off, ct; uint32_t len, off, ct;
slen = oper.length(); bool done = false;
if (slen > 0) operin=oper;
ct=0;
restart:
while (!done)
{ {
std::vector<std::string> groups;
offset = 0; slen = oper.length();
RegularExpression varEx(varExpression, Poco::RegularExpression::RE_EXTRA, true); if (slen > 0)
Poco::RegularExpression::MatchVec mVec;
//printf("|%s|%s|\n", varExpression.c_str(), oper.c_str());
groups.clear();
ct = 0;
while (offset < slen)
{ {
try std::vector<std::string> groups;
{
varEx.match(oper, offset, mVec, 0);
}
catch (...)
{
offset = slen;
}
x = mVec.size(); offset = 0;
if (x > 0) RegularExpression varEx(varExpression, 0, true);
Poco::RegularExpression::MatchVec mVec;
//printf("|%s|%s|\n", varExpression.c_str(), oper.c_str());
groups.clear();
while (offset < slen)
{ {
res = 0; try
off = mVec[0].offset;
len = mVec[0].length;
s = oper.substr(off, len);
sym = findVariable(s);
if (sym != NULL)
{ {
ct++; varEx.match(oper, offset, mVec, 0);
if (pass > 0) }
{ catch (...)
//printf("%d |%s|\n", ct, s.c_str()); {
} offset = slen;
} }
offset += len;
}
else
{
offset = slen;
}
}
x = mVec.size();
if (x > 0)
{
res = 0;
off = mVec[0].offset;
len = mVec[0].length;
s = oper.substr(off, len);
sym = findVariable(s);
if (sym != NULL)
{
//printf("match |%s|\n",sym->var_text.c_str());
if (sym->var_text != "")
{
oper = oper.replace(off, len, sym->var_text);
ct++;
if (pass > 0)
{
//printf("%d |%s|\n", ct, s.c_str());
}
goto restart;
}
}
else
{
done=true;
}
offset += len;
}
else
{
offset = slen;
done=true;
}
}
}
else
{
done=true;
}
}
//printf("inoper=|%s| outoper=|%s|\n",operin.c_str(),oper.c_str());
if (ct>0)
{
outop=oper;
res=ct;
} }
return (res); return (res);
} }
@ -1911,7 +1969,7 @@ void CLASS::process(void)
sprintf(buff, "$%X", PC.currentpc); sprintf(buff, "$%X", PC.currentpc);
ls = buff; ls = buff;
sym = addVariable(line.lable, ls, true); sym = addVariable(line.lable, ls, true);
if (sym == NULL) { dupsym = true; } //if (sym == NULL) { dupsym = true; }
break; break;
case ':': case ':':
@ -1937,7 +1995,16 @@ void CLASS::process(void)
line.setError(errDupSymbol); line.setError(errDupSymbol);
} }
} }
x = substituteVariables(line); std::string outop;
if (pass==0)
{
line.printoperand=line.operand;
}
x = substituteVariables(line,outop);
if (x>0)
{
line.operand=outop;
}
x = parseOperand(line); x = parseOperand(line);
if (x >= 0) if (x >= 0)
{ {

13
asm.h
View File

@ -18,6 +18,7 @@
#define OPTION_FORCE_REPSEP 0x0800 #define OPTION_FORCE_REPSEP 0x0800
#define OPTION_NO_REPSEP 0x1000 #define OPTION_NO_REPSEP 0x1000
#define OPTION_CFG_REPSEP 0x2000 #define OPTION_CFG_REPSEP 0x2000
#define OPTION_M32_VARS 0x4000
#define FLAG_FORCELONG 0x01 #define FLAG_FORCELONG 0x01
@ -189,6 +190,7 @@ public:
uint32_t syntax; uint32_t syntax;
std::string lable; std::string lable;
std::string printlable; std::string printlable;
std::string printoperand;
std::string opcode; std::string opcode;
std::string opcodelower; std::string opcodelower;
std::string operand; std::string operand;
@ -231,6 +233,8 @@ public:
class TFileProcessor class TFileProcessor
{ {
protected: protected:
int win_columns;
int win_rows;
std::string initialdir; std::string initialdir;
std::vector<std::string> filenames; std::vector<std::string> filenames;
uint32_t syntax; uint32_t syntax;
@ -310,7 +314,8 @@ class TSymbol
public: public:
std::string namelc; std::string namelc;
std::string name; std::string name;
std::string text; //std::string text;
std::string var_text;
uint32_t value; uint32_t value;
uint16_t stype; uint16_t stype;
uint8_t opcode; uint8_t opcode;
@ -326,7 +331,8 @@ public:
{ {
value = 0; value = 0;
used = false; used = false;
text = ""; //text = "";
var_text="";
name = ""; name = "";
namelc = ""; namelc = "";
stype = 0; stype = 0;
@ -406,7 +412,8 @@ public:
void showVariables(void); void showVariables(void);
int evaluate(MerlinLine &line, std::string expr, int64_t &value); int evaluate(MerlinLine &line, std::string expr, int64_t &value);
int substituteVariables(MerlinLine & line); int substituteVariables(MerlinLine & line, std::string &outop);
bool codeSkipped(void); bool codeSkipped(void);
int parseOperand(MerlinLine &line); int parseOperand(MerlinLine &line);

View File

@ -423,7 +423,7 @@ lup_start:
--^ --^
lst off ;lst off
//]XCODEEND ; Keep this at the end and put your code above this //]XCODEEND ; Keep this at the end and put your code above this
;lst off ;lst off

View File

@ -155,5 +155,5 @@ LOCAL1 lda #$2c ;EDIT: format as ASCII
beq LOCAL1 beq LOCAL1
LOCAL2 lda $2c ;EDIT: format as ASCII LOCAL2 lda $2c ;EDIT: format as ASCII
ldx $5678 ;put empty variable table here ldx $5678 ;put empty variable table here
;beq LOCAL2 beq LOCAL2
rts rts

View File

@ -1,13 +1,12 @@
(0) 2019-11-17 - BRK does not detect a lable that can't be evaluated (0) 2019-11-17 - BRK does not detect a lable that can't be evaluated
(0) 2019-11-17 - ASCII parsing in both eval and for ASC type commands (0) 2019-11-17 - ASCII parsing in both eval and for ASC type commands
(0) 2019-11-17 - IF processing for character compare mode (0) 2019-11-17 - IF processing for character compare mode
(0) 2019-11-17 - Note (syntax) Merlin doesn't allow 'A' implied addressing
(0) 2019-11-17 - Note (syntax): Merlin doesn't allow local labels without a previous global (0) 2019-11-17 - Note (syntax): Merlin doesn't allow local labels without a previous global
(0) 2019-11-17 - Note (syntax): Merlin doesn't allow local colons after label which is ignored (0) 2019-11-17 - Note (syntax): Merlin doesn't allow local colons after label which is ignored
(0) 2019-11-17 - Note (syntax): Merlin doesn't allow for 'rep/sep/xce' tracking (0) 2019-11-17 - Note (syntax): Merlin doesn't allow for 'rep/sep/xce' tracking
(0) 2019-11-17 - Bug (evaluation routine puts ascii bytes in reverse order (#"AB") (0) 2019-11-17 - Bug (evaluation routine puts ascii bytes in reverse order (#"AB")
(0) 2019-11-17 - (0) 2019-11-17 - want to wrap comments based on current terminal width, and don't if printing to non-terminal
(0) 2019-11-17 - (0) 2019-11-17 - syntax options - check OPTION bits, not syntax type (OPTION_ALLOW_LOCAL)
(0) 2019-11-17 - (0) 2019-11-17 -
(0) 2019-11-17 - (0) 2019-11-17 -
(0) 2019-11-17 - (0) 2019-11-17 -