More MACRO-10 updates (eg, LOC pseudo-op, SIXBIT/ASCII expression support)
This commit is contained in:
parent
15417ca686
commit
0c9f752f86
24 changed files with 40332 additions and 87 deletions
|
|
@ -288,7 +288,10 @@ class Macro10 {
|
|||
/*
|
||||
* We know that local resources ending with ".MAC" are actually stored with a ".txt" extension.
|
||||
*/
|
||||
if (sURL.indexOf(':') < 0 && sURL.slice(-4).toUpperCase() == ".MAC") sURL += ".txt";
|
||||
if (sURL.indexOf(':') < 0) {
|
||||
var sExt = sURL.slice(-4).toUpperCase();
|
||||
if (".MAC.KLM".indexOf(sExt) >= 0) sURL += ".txt";
|
||||
}
|
||||
|
||||
Web.getResource(sURL, null, true, function processMacro10(sFile, sResource, nErrorCode) {
|
||||
if (nErrorCode) {
|
||||
|
|
@ -521,7 +524,7 @@ class Macro10 {
|
|||
}
|
||||
|
||||
if (this.chASCII != null) {
|
||||
sLine = this.addASCII(sLine);
|
||||
sLine = this.defASCII(sLine);
|
||||
}
|
||||
|
||||
var fParse = true;
|
||||
|
|
@ -603,7 +606,7 @@ class Macro10 {
|
|||
*/
|
||||
var sLiteral = this.getLiteral(sOperands);
|
||||
if (sLiteral) {
|
||||
sOperands = sOperands.replace(sLiteral, this.addMacro(Macro10.PSEUDO_OP.LITERAL, this.getLiteral(sRemainder)));
|
||||
sOperands = sOperands.replace(sLiteral, this.defMacro(Macro10.PSEUDO_OP.LITERAL, this.getLiteral(sRemainder)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -620,39 +623,48 @@ class Macro10 {
|
|||
case Macro10.PSEUDO_OP.ASCII:
|
||||
case Macro10.PSEUDO_OP.ASCIZ:
|
||||
case Macro10.PSEUDO_OP.SIXBIT:
|
||||
this.addASCII(sRemainder);
|
||||
this.defASCII(sRemainder);
|
||||
break;
|
||||
|
||||
case Macro10.PSEUDO_OP.END:
|
||||
this.addEND(sOperands);
|
||||
this.defEND(sOperands);
|
||||
break;
|
||||
|
||||
case Macro10.PSEUDO_OP.EXP:
|
||||
this.addEXP(sOperands);
|
||||
this.defEXP(sOperands);
|
||||
break;
|
||||
|
||||
case Macro10.PSEUDO_OP.LOC:
|
||||
this.defLocation(sOperands);
|
||||
break;
|
||||
|
||||
case Macro10.PSEUDO_OP.XWD:
|
||||
this.addXWD(sOperands);
|
||||
this.defXWD(sOperands);
|
||||
break;
|
||||
|
||||
case Macro10.PSEUDO_OP.DEFINE:
|
||||
case Macro10.PSEUDO_OP.IFE:
|
||||
case Macro10.PSEUDO_OP.IFG:
|
||||
case Macro10.PSEUDO_OP.IFL:
|
||||
case Macro10.PSEUDO_OP.IFN:
|
||||
case Macro10.PSEUDO_OP.IRP:
|
||||
case Macro10.PSEUDO_OP.IRPC:
|
||||
case Macro10.PSEUDO_OP.OPDEF:
|
||||
case Macro10.PSEUDO_OP.REPEAT:
|
||||
this.addMacro(sOperator, sRemainder);
|
||||
this.defMacro(sOperator, sRemainder);
|
||||
break;
|
||||
|
||||
case Macro10.PSEUDO_OP.LALL: // TODO
|
||||
case Macro10.PSEUDO_OP.LIST: // TODO
|
||||
case Macro10.PSEUDO_OP.NOSYM: // TODO
|
||||
case Macro10.PSEUDO_OP.PAGE: // TODO
|
||||
case Macro10.PSEUDO_OP.SUBTTL: // TODO
|
||||
case Macro10.PSEUDO_OP.TITLE: // TODO
|
||||
case Macro10.PSEUDO_OP.XLIST: // TODO
|
||||
break;
|
||||
|
||||
default:
|
||||
this.addWord(sOperator, sSeparator, sOperands);
|
||||
this.defWord(sOperator, sSeparator, sOperands);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -762,6 +774,18 @@ class Macro10 {
|
|||
}
|
||||
break;
|
||||
|
||||
case Macro10.PSEUDO_OP.IFG:
|
||||
if (macro.nOperand > 0) {
|
||||
this.parseText(macro.sText);
|
||||
}
|
||||
break;
|
||||
|
||||
case Macro10.PSEUDO_OP.IFL:
|
||||
if (macro.nOperand < 0) {
|
||||
this.parseText(macro.sText);
|
||||
}
|
||||
break;
|
||||
|
||||
case Macro10.PSEUDO_OP.IFN:
|
||||
if (macro.nOperand) {
|
||||
this.parseText(macro.sText);
|
||||
|
|
@ -915,7 +939,7 @@ class Macro10 {
|
|||
continue;
|
||||
}
|
||||
if (fQuotes) continue;
|
||||
if (sDelim.indexOf(ch) >= 0) {
|
||||
if (!cNesting && sDelim.indexOf(ch) >= 0) {
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
|
|
@ -963,6 +987,12 @@ class Macro10 {
|
|||
if (nLocation === undefined) {
|
||||
nLocation = (this.nLocationScope >= 0? this.nLocationScope : this.nLocation);
|
||||
}
|
||||
/*
|
||||
* The SIXBIT (and presumably ASCII; not sure about ASCIZ) pseudo-ops can also be used in expressions
|
||||
* (or at least assignments), so we check for those in the given expression and convert them to quoted
|
||||
* sequences that the debugger's parseExpression() understands.
|
||||
*/
|
||||
sOperand = sOperand.replace(/SIXBIT\s*(\S)(.*?)\1/g, "'$2'").replace(/ASCII\s*(\S)(.*?)\1/g, '"$2"');
|
||||
/*
|
||||
* Check for the "period" syntax that MACRO-10 uses to represent the value of the current location.
|
||||
* The Debugger's parseInstruction() method understands that syntax, but its parseExpression() method
|
||||
|
|
@ -1068,21 +1098,23 @@ class Macro10 {
|
|||
sReserved = match[0];
|
||||
var sLabel = match[1];
|
||||
var name = '?' + sLabel;
|
||||
if (this.tblMacros[name] !== undefined) {
|
||||
this.error("reserved symbol redefined: " + sReserved);
|
||||
/*
|
||||
* We now allow reserved symbols to reused (which would make sense if they appeared in a macro).
|
||||
*/
|
||||
if (this.tblMacros[name] === undefined) {
|
||||
var aParms, aDefaults, aValues;
|
||||
aParms = aDefaults = aValues = [];
|
||||
this.tblMacros[name] = {
|
||||
name: name,
|
||||
nOperand: Macro10.MACRO_OP.RESERVED,
|
||||
aParms,
|
||||
aDefaults,
|
||||
aValues,
|
||||
sText: sLabel + ": 0",
|
||||
nLine: this.nLine
|
||||
};
|
||||
this.aVariables.push(name);
|
||||
}
|
||||
var aParms, aDefaults, aValues;
|
||||
aParms = aDefaults = aValues = [];
|
||||
this.tblMacros[name] = {
|
||||
name: name,
|
||||
nOperand: Macro10.MACRO_OP.RESERVED,
|
||||
aParms,
|
||||
aDefaults,
|
||||
aValues,
|
||||
sText: sLabel + ": 0",
|
||||
nLine: this.nLine
|
||||
};
|
||||
this.aVariables.push(name);
|
||||
}
|
||||
return sReserved;
|
||||
}
|
||||
|
|
@ -1125,13 +1157,13 @@ class Macro10 {
|
|||
}
|
||||
|
||||
/**
|
||||
* addASCII(sOperands)
|
||||
* defASCII(sOperands)
|
||||
*
|
||||
* @this {Macro10}
|
||||
* @param {string} sOperands
|
||||
* @return {string} (returns whatever portion of the string was not part of an ASCII pseudo-op)
|
||||
*/
|
||||
addASCII(sOperands)
|
||||
defASCII(sOperands)
|
||||
{
|
||||
var sRemain = sOperands;
|
||||
if (this.chASCII == null) {
|
||||
|
|
@ -1159,7 +1191,7 @@ class Macro10 {
|
|||
}
|
||||
|
||||
/**
|
||||
* addMacro(sOperator, sOperands)
|
||||
* defMacro(sOperator, sOperands)
|
||||
*
|
||||
* If sOperator is DEFINE (or OPDEF), then a macro definition is expected. If it's REPEAT, then we're
|
||||
* starting a REPEAT block instead.
|
||||
|
|
@ -1178,7 +1210,7 @@ class Macro10 {
|
|||
* @param {string} sOperands
|
||||
* @return {string}
|
||||
*/
|
||||
addMacro(sOperator, sOperands)
|
||||
defMacro(sOperator, sOperands)
|
||||
{
|
||||
var i, match, name, nOperand, aParms, aDefaults, aValues, iMatch;
|
||||
|
||||
|
|
@ -1192,7 +1224,7 @@ class Macro10 {
|
|||
* (parenthesized) parameters exist on the same line, but the (angle-bracketed)
|
||||
* definition can continue on for multiple lines.
|
||||
*/
|
||||
match = sOperands.match(/([A-Z$%.][0-9A-Z$%.]*)\s*(\([^)]*\)|)\s*(<|)([\s\S]*)/i);
|
||||
match = sOperands.match(/([A-Z$%.][0-9A-Z$%.]*)\s*(\([^)]*\)|)\s*,?\s*(<|)([\s\S]*)/i);
|
||||
if (!match) {
|
||||
this.error("unrecognized " + sOperator + ": " + sOperands);
|
||||
return sOperands;
|
||||
|
|
@ -1201,7 +1233,7 @@ class Macro10 {
|
|||
/*
|
||||
* If this macro has defined parameters, parse them (and any defaults) now.
|
||||
*/
|
||||
if (match[2]) {
|
||||
if (match[2] && match[2] != ',') {
|
||||
aParms = this.getValues(match[2], true);
|
||||
aDefaults = this.getDefaults(aParms);
|
||||
}
|
||||
|
|
@ -1343,44 +1375,6 @@ class Macro10 {
|
|||
return sRemain;
|
||||
}
|
||||
|
||||
/**
|
||||
* addEND()
|
||||
*
|
||||
* Processes the END pseudo-op.
|
||||
*
|
||||
* @this {Macro10}
|
||||
* @param {string} sOperands
|
||||
*/
|
||||
addEND(sOperands)
|
||||
{
|
||||
if (!sOperands) {
|
||||
this.nAddrStart = this.nAddr;
|
||||
} else {
|
||||
this.nAddrStart = this.parseExpression(sOperands, true);
|
||||
if (this.nAddrStart === undefined) {
|
||||
this.error("unrecognized expression: " + sOperands);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* addEXP()
|
||||
*
|
||||
* Processes the EXP pseudo-op.
|
||||
*
|
||||
* @this {Macro10}
|
||||
* @param {string} sOperands
|
||||
*/
|
||||
addEXP(sOperands)
|
||||
{
|
||||
var w = this.parseExpression(sOperands, true);
|
||||
if (w !== undefined) {
|
||||
this.genWord(w, this.dbg.sUndefined);
|
||||
} else {
|
||||
this.error("unrecognized expression: " + sOperands);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* addSymbol(name, value, nType)
|
||||
*
|
||||
|
|
@ -1416,14 +1410,81 @@ class Macro10 {
|
|||
}
|
||||
|
||||
/**
|
||||
* addWord(sOperator, sSeparator, sOperands)
|
||||
* defEND()
|
||||
*
|
||||
* Processes the END pseudo-op.
|
||||
*
|
||||
* @this {Macro10}
|
||||
* @param {string} sOperands
|
||||
*/
|
||||
defEND(sOperands)
|
||||
{
|
||||
if (!sOperands) {
|
||||
this.nAddrStart = this.nAddr;
|
||||
} else {
|
||||
this.nAddrStart = this.parseExpression(sOperands, true);
|
||||
if (this.nAddrStart === undefined) {
|
||||
this.error("unrecognized expression: " + sOperands);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* defEXP()
|
||||
*
|
||||
* Processes the EXP pseudo-op.
|
||||
*
|
||||
* @this {Macro10}
|
||||
* @param {string} sOperands
|
||||
*/
|
||||
defEXP(sOperands)
|
||||
{
|
||||
var w = this.parseExpression(sOperands, true);
|
||||
if (w !== undefined) {
|
||||
this.genWord(w, this.dbg.sUndefined);
|
||||
} else {
|
||||
this.error("unrecognized expression: " + sOperands);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* defLocation(sOperands)
|
||||
*
|
||||
* Processes the LOC pseudo-op.
|
||||
*
|
||||
* @this {Macro10}
|
||||
* @param {string} sOperands
|
||||
*/
|
||||
defLocation(sOperands)
|
||||
{
|
||||
this.nLocation = this.parseExpression(sOperands) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* defXWD()
|
||||
*
|
||||
* Processes the XWD pseudo-op.
|
||||
*
|
||||
* Since the XWD pseudo-op appears to be equivalent to two values separated by two commas, which defEXP() must also
|
||||
* support, we can piggy-back on defExp().
|
||||
*
|
||||
* @this {Macro10}
|
||||
* @param {string} sOperands
|
||||
*/
|
||||
defXWD(sOperands)
|
||||
{
|
||||
this.defEXP(sOperands.replace(",", ",,"));
|
||||
}
|
||||
|
||||
/**
|
||||
* defWord(sOperator, sSeparator, sOperands)
|
||||
*
|
||||
* @this {Macro10}
|
||||
* @param {string} sOperator
|
||||
* @param {string} sSeparator
|
||||
* @param {string} sOperands
|
||||
*/
|
||||
addWord(sOperator, sSeparator, sOperands)
|
||||
defWord(sOperator, sSeparator, sOperands)
|
||||
{
|
||||
var w = -1;
|
||||
|
||||
|
|
@ -1445,22 +1506,6 @@ class Macro10 {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* addXWD()
|
||||
*
|
||||
* Processes the XWD pseudo-op.
|
||||
*
|
||||
* Since the XWD pseudo-op appears to be equivalent to two values separated by two commas, which addEXP() must also
|
||||
* support, we can piggy-back on addExp().
|
||||
*
|
||||
* @this {Macro10}
|
||||
* @param {string} sOperands
|
||||
*/
|
||||
addXWD(sOperands)
|
||||
{
|
||||
this.addEXP(sOperands.replace(",", ",,"));
|
||||
}
|
||||
|
||||
/**
|
||||
* genASCII()
|
||||
*
|
||||
|
|
@ -1566,18 +1611,24 @@ Macro10.PSEUDO_OP = {
|
|||
END: "END",
|
||||
EXP: "EXP",
|
||||
IFE: "IFE",
|
||||
IFG: "IFG",
|
||||
IFL: "IFL",
|
||||
IFN: "IFN",
|
||||
IRP: "IRP",
|
||||
IRPC: "IRPC",
|
||||
LALL: "LALL",
|
||||
LITERAL: "LITERAL", // this is a pseudo-pseudo-op, used for internal purposes
|
||||
LIST: "LIST",
|
||||
LOC: "LOC",
|
||||
NOSYM: "NOSYM",
|
||||
OPDEF: "OPDEF",
|
||||
PAGE: "PAGE",
|
||||
REPEAT: "REPEAT",
|
||||
SIXBIT: "SIXBIT",
|
||||
SUBTTL: "SUBTTL",
|
||||
TITLE: "TITLE",
|
||||
XWD: "XWD"
|
||||
XWD: "XWD",
|
||||
XLIST: "XLIST"
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue