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 "eval.h"
#include "psuedo.h"
#include <sys/ioctl.h>
#include <unistd.h>
#define CLASS MerlinLine
@ -99,7 +102,7 @@ void CLASS::print(uint32_t lineno)
}
}
bool empty = false;
if ((printlable == "") && (opcode == "") && (operand == ""))
if ((printlable == "") && (opcode == "") && (printoperand == ""))
{
empty = true;
}
@ -202,7 +205,7 @@ void CLASS::print(uint32_t lineno)
{
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());
}
if ((errorcode > 0) && (!merlinerrors))
@ -287,6 +290,7 @@ void CLASS::clear()
opcode = "";
opcodelower = "";
operand = "";
printoperand="";
comment = "";
operand_expr = "";
operand_expr2 = "";
@ -494,7 +498,7 @@ void CLASS::set(std::string line)
if (x > 1)
{
// 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] == ':'))
{
@ -513,7 +517,20 @@ void CLASS::set(std::string line)
CLASS::CLASS()
{
int x;
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()
@ -1158,7 +1175,7 @@ TSymbol * CLASS::addVariable(std::string symname, std::string val, bool replace)
if (fnd != NULL)
{
//printf("replacing symbol: %s %08X\n",sym.c_str(),val);
fnd->text = val;
fnd->var_text = val;
return (fnd);
}
@ -1168,7 +1185,7 @@ TSymbol * CLASS::addVariable(std::string symname, std::string val, bool replace)
s.namelc = Poco::toLower(sym);
s.stype = 0;
s.value = 0;
s.text = val;
s.var_text = val;
s.used = false;
s.cb = NULL;
@ -1185,7 +1202,7 @@ TSymbol * CLASS::findVariable(std::string symname)
TSymbol *res = NULL;
//printf("finding: %s\n",symname.c_str());
auto itr = variables.find(Poco::toUpper(symname));
auto itr = variables.find(symname);
if (itr != variables.end())
{
//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)
{
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");
}
@ -1310,12 +1327,23 @@ int CLASS::callOpCode(std::string op, MerlinLine &line)
case '>':
line.expr_value >>= 8;
line.expr_value &= 0xFFFF;
if ((line.syntax&SYNTAX_MERLIN32)==SYNTAX_MERLIN32)
{
line.flags |= FLAG_FORCEABS;
}
break;
case '^':
line.expr_value = (line.expr_value >> 16) & 0xFFFF;
if ((line.syntax&SYNTAX_MERLIN32)==SYNTAX_MERLIN32)
{
line.flags |= FLAG_FORCEABS;
}
break;
case '|':
line.flags |= FLAG_FORCELONG;
if ((line.syntax&SYNTAX_MERLIN32)!=SYNTAX_MERLIN32)
{
line.flags |= FLAG_FORCELONG;
}
break;
}
if (line.expr_value >= 0x100)
@ -1496,7 +1524,7 @@ void CLASS::initpass(void)
lastcarry = false;
relocatable = false;
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
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
// 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
{
@ -1780,63 +1808,93 @@ int CLASS::parseOperand(MerlinLine & line)
return (res);
}
int CLASS::substituteVariables(MerlinLine & line)
int CLASS::substituteVariables(MerlinLine & line, std::string &outop)
{
int res = -1;
int res = 0;
int x;
std::string::size_type offset, slen;
std::string oper = line.operand;
std::string s;
std::string operin;
TSymbol *sym;
uint32_t len, off, ct;
slen = oper.length();
if (slen > 0)
bool done = false;
operin=oper;
ct=0;
restart:
while (!done)
{
std::vector<std::string> groups;
offset = 0;
RegularExpression varEx(varExpression, Poco::RegularExpression::RE_EXTRA, true);
Poco::RegularExpression::MatchVec mVec;
//printf("|%s|%s|\n", varExpression.c_str(), oper.c_str());
groups.clear();
ct = 0;
while (offset < slen)
slen = oper.length();
if (slen > 0)
{
try
{
varEx.match(oper, offset, mVec, 0);
}
catch (...)
{
offset = slen;
}
std::vector<std::string> groups;
x = mVec.size();
if (x > 0)
offset = 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;
off = mVec[0].offset;
len = mVec[0].length;
s = oper.substr(off, len);
sym = findVariable(s);
if (sym != NULL)
try
{
ct++;
if (pass > 0)
{
//printf("%d |%s|\n", ct, s.c_str());
}
varEx.match(oper, offset, mVec, 0);
}
catch (...)
{
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);
}
@ -1911,7 +1969,7 @@ void CLASS::process(void)
sprintf(buff, "$%X", PC.currentpc);
ls = buff;
sym = addVariable(line.lable, ls, true);
if (sym == NULL) { dupsym = true; }
//if (sym == NULL) { dupsym = true; }
break;
case ':':
@ -1937,7 +1995,16 @@ void CLASS::process(void)
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);
if (x >= 0)
{

13
asm.h
View File

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

View File

@ -155,5 +155,5 @@ LOCAL1 lda #$2c ;EDIT: format as ASCII
beq LOCAL1
LOCAL2 lda $2c ;EDIT: format as ASCII
ldx $5678 ;put empty variable table here
;beq LOCAL2
beq LOCAL2
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 - ASCII parsing in both eval and for ASC type commands
(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 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 - Bug (evaluation routine puts ascii bytes in reverse order (#"AB")
(0) 2019-11-17 -
(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 - syntax options - check OPTION bits, not syntax type (OPTION_ALLOW_LOCAL)
(0) 2019-11-17 -
(0) 2019-11-17 -
(0) 2019-11-17 -