Some more Debugger factoring

This commit is contained in:
Jeff Parsons 2016-09-14 21:11:57 -07:00
commit e5c5a8e6be
17 changed files with 1124 additions and 1539 deletions

View file

@ -66,6 +66,11 @@ function Debugger(parmsDbg)
this.nCycles = 0;
this.cOpcodes = this.cOpcodesStart = 0;
/*
* fAssemble is true when "assemble mode" is active, false when not.
*/
this.fAssemble = false;
/*
* This maintains command history. New commands are inserted at index 0 of the array.
* When Enter is pressed on an empty input buffer, we default to the command at aPrevCmds[0].
@ -215,6 +220,83 @@ if (DEBUGGER) {
return true;
};
/**
* parseCommand(sCmd, fSave, chSep)
*
* @this {Debugger}
* @param {string|undefined} sCmd
* @param {boolean} [fSave] is true to save the command, false if not
* @param {string} [chSep] is the command separator character (default is ';')
* @return {Array.<string>}
*/
Debugger.prototype.parseCommand = function(sCmd, fSave, chSep)
{
if (fSave) {
if (!sCmd) {
if (this.fAssemble) {
sCmd = "end";
} else {
sCmd = this.aPrevCmds[this.iPrevCmd+1];
}
} else {
if (this.iPrevCmd < 0 && this.aPrevCmds.length) {
this.iPrevCmd = 0;
}
if (this.iPrevCmd < 0 || sCmd != this.aPrevCmds[this.iPrevCmd]) {
this.aPrevCmds.splice(0, 0, sCmd);
this.iPrevCmd = 0;
}
this.iPrevCmd--;
}
}
var a = [];
if (sCmd) {
/*
* With the introduction of breakpoint commands (ie, quoted command sequences
* associated with a breakpoint), we can no longer perform simplistic splitting.
*
* a = sCmd.split(chSep || ';');
* for (var i = 0; i < a.length; i++) a[i] = str.trim(a[i]);
*
* We may now split on semi-colons ONLY if they are outside a quoted sequence.
*
* Also, to allow quoted strings *inside* breakpoint commands, we first replace all
* DOUBLE double-quotes with single quotes.
*/
sCmd = sCmd.toLowerCase().replace(/""/g, "'");
var iPrev = 0;
var chQuote = null;
chSep = chSep || ';';
/*
* NOTE: Processing charAt() up to and INCLUDING length is not a typo; we're taking
* advantage of the fact that charAt() with an invalid index returns an empty string,
* allowing us to use the same substring() call to capture the final portion of sCmd.
*
* In a sense, it allows us to pretend that the string ends with a zero terminator.
*/
for (var i = 0; i <= sCmd.length; i++) {
var ch = sCmd.charAt(i);
if (ch == '"' || ch == "'") {
if (!chQuote) {
chQuote = ch;
} else if (ch == chQuote) {
chQuote = null;
}
}
else if (ch == chSep && !chQuote || !ch) {
/*
* Recall that substring() accepts starting (inclusive) and ending (exclusive)
* indexes, whereas substr() accepts a starting index and a length. We need the former.
*/
a.push(str.trim(sCmd.substring(iPrev, i)));
iPrev = i + 1;
}
}
}
return a;
};
/**
* parseExpression(sExp, fPrint)
*
@ -383,7 +465,7 @@ if (DEBUGGER) {
value = this.getRegValue(iReg);
} else {
value = this.getVariable(sValue);
if (value === undefined) value = str.parseInt(sValue);
if (value === undefined) value = str.parseInt(sValue, 16);
}
if (value === undefined && !fQuiet) this.println("invalid " + (sName? sName : "value") + ": " + sValue);
} else {

View file

@ -41,7 +41,7 @@ var str = {};
* So use this function to validate the entire string.
*
* @param {string} s is the string representation of some number
* @param {number} [base] is the radix of the number represented above; 10 is the default (only 2, 8, 10 and 16 are supported)
* @param {number} [base] is the radix of the above number; 10 is the default (only 2, 8, 10 and 16 are supported)
* @return {boolean} true if valid, false if invalid (or the specified base isn't supported)
*/
str.isValidInt = function(s, base)
@ -63,14 +63,14 @@ str.isValidInt = function(s, base)
* for binary, because 1) it's not commonly used, and 2) it conflicts with valid hex sequences.
*
* @param {string} s is the string representation of some number
* @param {number} [base] is the default radix to use (default is 16); can be overridden by prefixes/suffixes
* @param {number} [base] is the default radix to use (default is 10); can be overridden by prefixes/suffixes
* @return {number|undefined} corresponding value, or undefined if invalid
*/
str.parseInt = function(s, base)
{
var value;
if (s) {
if (!base) base = 16;
if (!base) base = 10;
if (s.charAt(0) == '$') {
base = 16;
s = s.substr(1);