1
0
mirror of https://github.com/fadden/6502bench.git synced 2025-02-06 08:30:04 +00:00

Fancy comments, part 2

Started implementing the fancy formatter.  It currently doesn't do
anything fancy, just word-wrapping.

Moved the static DebugShowRuler field into Formatter, so that the
cached data is discarded when the setting changes.

Also, updated SourceNotes with instructions for publishing a release.
This commit is contained in:
Andy McFadden 2024-07-06 14:54:09 -07:00
parent 83da0d952c
commit 1c84357bbf
9 changed files with 371 additions and 92 deletions

View File

@ -72,6 +72,8 @@ namespace Asm65 {
/// <summary>Insert space after delimiter for long comments?</summary> /// <summary>Insert space after delimiter for long comments?</summary>
public bool AddSpaceLongComment { get; set; } = false; public bool AddSpaceLongComment { get; set; } = false;
/// <summary>Enable debug mode for long comments?</summary>
public bool DebugLongComments { get; set; } = false;
// //
// Functional changes to assembly output. // Functional changes to assembly output.
@ -163,6 +165,7 @@ namespace Asm65 {
UpperOperandXY = src.UpperOperandXY; UpperOperandXY = src.UpperOperandXY;
AddSpaceLongComment = src.AddSpaceLongComment; AddSpaceLongComment = src.AddSpaceLongComment;
DebugLongComments = src.DebugLongComments;
SuppressHexNotation = src.SuppressHexNotation; SuppressHexNotation = src.SuppressHexNotation;
SuppressImpliedAcc = src.SuppressImpliedAcc; SuppressImpliedAcc = src.SuppressImpliedAcc;
@ -539,6 +542,13 @@ namespace Asm65 {
get { return mFullLineCommentDelimiterPlus; } get { return mFullLineCommentDelimiterPlus; }
} }
/// <summary>
/// If true, enable debug mode when rendering long comments.
/// </summary>
public bool DebugLongComments {
get { return mFormatConfig.DebugLongComments; }
}
/// <summary> /// <summary>
/// Prefix for non-unique address labels. /// Prefix for non-unique address labels.
/// </summary> /// </summary>
@ -565,7 +575,7 @@ namespace Asm65 {
/// <summary> /// <summary>
/// Constructor. Initializes various fields based on the configuration. We want to /// Constructor. Initializes various fields based on the configuration. We want to
/// do as much work as possible here. /// pre-compute as many things as possible, to speed up formatting.
/// </summary> /// </summary>
public Formatter(FormatConfig config) { public Formatter(FormatConfig config) {
mFormatConfig = new FormatConfig(config); // make a copy mFormatConfig = new FormatConfig(config); // make a copy
@ -573,7 +583,9 @@ namespace Asm65 {
if (string.IsNullOrEmpty(mFormatConfig.NonUniqueLabelPrefix)) { if (string.IsNullOrEmpty(mFormatConfig.NonUniqueLabelPrefix)) {
mFormatConfig.NonUniqueLabelPrefix = "@"; mFormatConfig.NonUniqueLabelPrefix = "@";
} }
if (string.IsNullOrEmpty(mFormatConfig.FullLineCommentDelimiterBase)) {
mFormatConfig.FullLineCommentDelimiterBase = "!";
}
if (mFormatConfig.AddSpaceLongComment) { if (mFormatConfig.AddSpaceLongComment) {
mFullLineCommentDelimiterPlus = mFormatConfig.FullLineCommentDelimiterBase + " "; mFullLineCommentDelimiterPlus = mFormatConfig.FullLineCommentDelimiterBase + " ";
} else { } else {

View File

@ -500,6 +500,7 @@ namespace SourceGen {
settings.GetString(AppSettings.FMT_LOCAL_VARIABLE_PREFIX, string.Empty); settings.GetString(AppSettings.FMT_LOCAL_VARIABLE_PREFIX, string.Empty);
mFormatterConfig.CommaSeparatedDense = mFormatterConfig.CommaSeparatedDense =
settings.GetBool(AppSettings.FMT_COMMA_SEP_BULK_DATA, true); settings.GetBool(AppSettings.FMT_COMMA_SEP_BULK_DATA, true);
mFormatterConfig.DebugLongComments = DebugLongComments;
string chrDelCereal = settings.GetString(AppSettings.FMT_CHAR_DELIM, null); string chrDelCereal = settings.GetString(AppSettings.FMT_CHAR_DELIM, null);
if (chrDelCereal != null) { if (chrDelCereal != null) {
@ -4721,6 +4722,11 @@ namespace SourceGen {
#region Debug features #region Debug features
/// <summary>
/// If set, show rulers and visible spaces in long comments.
/// </summary>
internal bool DebugLongComments { get; private set; } = false;
public void Debug_ExtensionScriptInfo() { public void Debug_ExtensionScriptInfo() {
string info = mProject.DebugGetLoadedScriptInfo(); string info = mProject.DebugGetLoadedScriptInfo();
@ -4793,13 +4799,16 @@ namespace SourceGen {
} }
public void Debug_ToggleCommentRulers() { public void Debug_ToggleCommentRulers() {
MultiLineComment.DebugShowRuler = !MultiLineComment.DebugShowRuler; DebugLongComments = !DebugLongComments;
// Don't need to repeat the analysis, but we do want to save/restore the mFormatterConfig.DebugLongComments = DebugLongComments;
// selection and top position when the comment fields change size. mFormatterConfig.AddSpaceLongComment = !DebugLongComments;
mFormatterCpuDef = null; // force mFormatter refresh on next analysis
if (CodeLineList != null) {
UndoableChange uc = UndoableChange uc =
UndoableChange.CreateDummyChange(UndoableChange.ReanalysisScope.DataOnly); UndoableChange.CreateDummyChange(UndoableChange.ReanalysisScope.DisplayOnly);
ApplyChanges(new ChangeSet(uc), false); ApplyChanges(new ChangeSet(uc), false);
} }
}
public void Debug_ToggleKeepAliveHack() { public void Debug_ToggleKeepAliveHack() {
ScriptManager.UseKeepAliveHack = !ScriptManager.UseKeepAliveHack; ScriptManager.UseKeepAliveHack = !ScriptManager.UseKeepAliveHack;

View File

@ -19,6 +19,17 @@ using System.Diagnostics;
using System.Windows.Media; using System.Windows.Media;
using System.Text; using System.Text;
// Spaces and hyphens are different. For example, if width is 10,
// "long words<space>more words" becomes:
// 0123456789
// long words
// more words
// However, "long words-more words" becomes:
// long
// words-more
// words
// because the hyphen is retained but the space is discarded.
namespace SourceGen { namespace SourceGen {
/// <summary> /// <summary>
/// <para>Representation of a multi-line comment, which is a string plus some format options. /// <para>Representation of a multi-line comment, which is a string plus some format options.
@ -30,11 +41,6 @@ namespace SourceGen {
/// calls.</para> /// calls.</para>
/// </summary> /// </summary>
public class MultiLineComment { public class MultiLineComment {
/// <summary>
/// If set, sticks a MaxWidth "ruler" at the top, and makes spaces visible.
/// </summary>
public static bool DebugShowRuler { get; set; }
/// <summary> /// <summary>
/// Unformatted text. /// Unformatted text.
/// </summary> /// </summary>
@ -68,6 +74,10 @@ namespace SourceGen {
private const int DEFAULT_WIDTH = 80; private const int DEFAULT_WIDTH = 80;
private const int MIN_WIDTH = 8; private const int MIN_WIDTH = 8;
private const int MAX_WIDTH = 128;
private const string SPACES = // MAX_WIDTH spaces
" " +
" ";
/// <summary> /// <summary>
@ -166,44 +176,48 @@ namespace SourceGen {
const char spcRep = '\u2219'; // BULLET OPERATOR const char spcRep = '\u2219'; // BULLET OPERATOR
string workString = string.IsNullOrEmpty(textPrefix) ? Text : textPrefix + Text; string workString = string.IsNullOrEmpty(textPrefix) ? Text : textPrefix + Text;
List<string> lines = new List<string>(); List<string> lines = new List<string>();
bool debugMode = formatter.DebugLongComments;
if (MaxWidth > MAX_WIDTH) {
lines.Add("!Bad MaxWidth!");
return lines;
}
string linePrefix; string linePrefix;
if (!string.IsNullOrEmpty(textPrefix)) { if (!string.IsNullOrEmpty(textPrefix)) {
// This is a Note, no comment delimiter needed.
linePrefix = string.Empty; linePrefix = string.Empty;
} else if (BoxMode) { } else if (BoxMode) {
if (formatter.FullLineCommentDelimiterBase.Length == 1 && if (formatter.FullLineCommentDelimiterBase.Length == 1 &&
formatter.FullLineCommentDelimiterBase[0] == BASIC_BOX_CHAR) { formatter.FullLineCommentDelimiterBase[0] == BASIC_BOX_CHAR) {
// Box char is same as comment delimiter, don't double-up.
linePrefix = string.Empty; linePrefix = string.Empty;
} else { } else {
// Prefix with comment delimiter, but don't include optional space.
linePrefix = formatter.FullLineCommentDelimiterBase; linePrefix = formatter.FullLineCommentDelimiterBase;
} }
} else { } else {
// No box, prefix every line with comment delimiter and optional space.
linePrefix = formatter.FullLineCommentDelimiterPlus; linePrefix = formatter.FullLineCommentDelimiterPlus;
} }
StringBuilder sb = new StringBuilder(MaxWidth); StringBuilder sb = new StringBuilder(MaxWidth);
if (DebugShowRuler) { if (debugMode) {
for (int i = 0; i < MaxWidth; i++) { for (int i = 0; i < MaxWidth; i++) {
sb.Append((i % 10).ToString()); sb.Append((i % 10).ToString());
} }
lines.Add(sb.ToString()); lines.Add(sb.ToString());
sb.Clear(); sb.Clear();
} }
string boxLine, spaces; string boxLine;
if (BoxMode) { if (BoxMode) {
for (int i = 0; i < MaxWidth - linePrefix.Length; i++) { for (int i = 0; i < MaxWidth - linePrefix.Length; i++) {
sb.Append(BASIC_BOX_CHAR); sb.Append(BASIC_BOX_CHAR);
} }
boxLine = sb.ToString(); boxLine = sb.ToString();
sb.Clear(); sb.Clear();
for (int i = 0; i < MaxWidth; i++) {
sb.Append(' ');
}
spaces = sb.ToString();
sb.Clear();
} else { } else {
boxLine = spaces = null; boxLine = null;
} }
if (BoxMode && workString.Length > 0) { if (BoxMode && workString.Length > 0) {
@ -213,24 +227,14 @@ namespace SourceGen {
int lineWidth = BoxMode ? int lineWidth = BoxMode ?
MaxWidth - linePrefix.Length - 4 : MaxWidth - linePrefix.Length - 4 :
MaxWidth - linePrefix.Length; MaxWidth - linePrefix.Length;
Debug.Assert(lineWidth > 0);
int startIndex = 0; int startIndex = 0;
int breakIndex = -1; int breakIndex = -1;
for (int i = 0; i < workString.Length; i++) { for (int i = 0; i < workString.Length; i++) {
// Spaces and hyphens are different. For example, if width is 10,
// "long words<space>more words" becomes:
// 0123456789
// long words
// more words
// However, "long words-more words" becomes:
// long
// words-more
// words
// because the hyphen is retained but the space is discarded.
if (workString[i] == '\r' || workString[i] == '\n') { if (workString[i] == '\r' || workString[i] == '\n') {
// explicit line break, emit line // explicit line break, emit line
string str = workString.Substring(startIndex, i - startIndex); string str = workString.Substring(startIndex, i - startIndex);
if (DebugShowRuler) { str = str.Replace(' ', spcRep); } if (debugMode) { str = str.Replace(' ', spcRep); }
if (BoxMode) { if (BoxMode) {
if (str == "" + BASIC_BOX_CHAR) { if (str == "" + BASIC_BOX_CHAR) {
// asterisk on a line by itself means "output row of asterisks" // asterisk on a line by itself means "output row of asterisks"
@ -238,16 +242,15 @@ namespace SourceGen {
} else { } else {
int padLen = lineWidth - str.Length; int padLen = lineWidth - str.Length;
str = linePrefix + BASIC_BOX_CHAR + " " + str + str = linePrefix + BASIC_BOX_CHAR + " " + str +
spaces.Substring(0, padLen + 1) + BASIC_BOX_CHAR; SPACES.Substring(0, padLen + 1) + BASIC_BOX_CHAR;
} }
} else { } else {
str = linePrefix + str; str = linePrefix + str;
} }
lines.Add(str); lines.Add(str);
// Eat the LF in CRLF. We don't actually work right with just LF, // Eat the LF in CRLF.
// because this will consume LFLF, but it's okay to insist that the if (workString[i] == '\r' && i < workString.Length - 1 &&
// string use CRLF for line breaks. workString[i + 1] == '\n') {
if (i < workString.Length - 1 && workString[i + 1] == '\n') {
i++; i++;
} }
startIndex = i + 1; startIndex = i + 1;
@ -258,11 +261,11 @@ namespace SourceGen {
} }
if (i - startIndex >= lineWidth) { if (i - startIndex >= lineWidth) {
// this character was one too many, break line one back // this character was one too many, break line at last break point
if (breakIndex <= 0) { if (breakIndex <= 0) {
// no break found, just chop it // no break found, just chop it
string str = workString.Substring(startIndex, i - startIndex); string str = workString.Substring(startIndex, i - startIndex);
if (DebugShowRuler) { str = str.Replace(' ', spcRep); } if (debugMode) { str = str.Replace(' ', spcRep); }
if (BoxMode) { if (BoxMode) {
str = linePrefix + BASIC_BOX_CHAR + " " + str + " " + BASIC_BOX_CHAR; str = linePrefix + BASIC_BOX_CHAR + " " + str + " " + BASIC_BOX_CHAR;
} else { } else {
@ -279,11 +282,11 @@ namespace SourceGen {
} }
string str = workString.Substring(startIndex, string str = workString.Substring(startIndex,
breakIndex + adj - startIndex); breakIndex + adj - startIndex);
if (DebugShowRuler) { str = str.Replace(' ', spcRep); } if (debugMode) { str = str.Replace(' ', spcRep); }
if (BoxMode) { if (BoxMode) {
int padLen = lineWidth - str.Length; int padLen = lineWidth - str.Length;
str = linePrefix + BASIC_BOX_CHAR + " " + str + str = linePrefix + BASIC_BOX_CHAR + " " + str +
spaces.Substring(0, padLen + 1) + BASIC_BOX_CHAR; SPACES.Substring(0, padLen + 1) + BASIC_BOX_CHAR;
} else { } else {
str = linePrefix + str; str = linePrefix + str;
} }
@ -309,11 +312,11 @@ namespace SourceGen {
if (startIndex < workString.Length) { if (startIndex < workString.Length) {
// Output remainder. // Output remainder.
string str = workString.Substring(startIndex, workString.Length - startIndex); string str = workString.Substring(startIndex, workString.Length - startIndex);
if (DebugShowRuler) { str = str.Replace(' ', spcRep); } if (debugMode) { str = str.Replace(' ', spcRep); }
if (BoxMode) { if (BoxMode) {
int padLen = lineWidth - str.Length; int padLen = lineWidth - str.Length;
str = linePrefix + BASIC_BOX_CHAR + " " + str + str = linePrefix + BASIC_BOX_CHAR + " " + str +
spaces.Substring(0, padLen + 1) + BASIC_BOX_CHAR; SPACES.Substring(0, padLen + 1) + BASIC_BOX_CHAR;
} else { } else {
str = linePrefix + str; str = linePrefix + str;
} }
@ -327,25 +330,283 @@ namespace SourceGen {
return lines; return lines;
} }
#region Fancy
private enum Tag {
Unknown = 0, Width, HorizRule, Break,
BoxStart, BoxEnd, UrlStart, UrlEnd, SymStart, SymEnd
}
private class DataSource {
private string mString;
private int mPosn;
public bool mInBox, mInUrl, mInSym;
public char this[int i] {
get { return mString[i]; }
}
public int Posn { get { return mPosn; } set { mPosn = value; } }
public int Length => mString.Length;
public char CurChar => mString[mPosn]; // mostly for debugger
public DataSource(string str, int posn, DataSource outer) {
mString = str;
mPosn = posn;
if (outer != null) {
// Inherit the values from the "outer" source.
mInBox = outer.mInBox;
mInUrl = outer.mInUrl;
mInSym = outer.mInSym;
}
}
}
private Stack<DataSource> mSourceStack = new Stack<DataSource>();
private StringBuilder mLineBuilder = new StringBuilder(MAX_WIDTH);
private const char DEFAULT_CHAR = '\0';
private int mLineWidth;
private char mBoxCharOrDef, mHorizRuleCharOrDef;
private char mBoxCharActual;
private bool mEscapeNext, mEatNextIfNewline;
private string mLinePrefix, mBoxPrefix;
private bool mDebugMode;
/// <summary>
/// Calculates the width of the usable text area, given the current attributes.
/// </summary>
private int CalcTextWidth(DataSource source) {
if (source.mInBox) {
if (mBoxCharOrDef == DEFAULT_CHAR) {
// Leave space for left/right box edges.
return mLineWidth - mBoxPrefix.Length - 4;
} else {
// Also leave space for a leading comment delimiter, even if the chosen
// box char happens to match the current delimiter. It might not match when
// it's rendered for asm gen, and we don't want the output to change.
return mLineWidth - mBoxPrefix.Length - 5;
}
} else {
return mLineWidth - mLinePrefix.Length;
}
}
/// <summary> /// <summary>
/// Generates one or more lines of formatted text, using the fancy formatter. /// Generates one or more lines of formatted text, using the fancy formatter.
/// </summary> /// </summary>
/// <param name="formatter">Formatter, with comment delimiters.</param> /// <param name="formatter">Formatter, with comment delimiters.</param>
/// <returns>List of formatted strings.</returns> /// <returns>List of formatted strings.</returns>
private List<string> FormatFancyText(Asm65.Formatter formatter) { private List<string> FormatFancyText(Asm65.Formatter formatter) {
Debug.Assert(SPACES.Length == MAX_WIDTH);
mLineWidth = DEFAULT_WIDTH;
mBoxCharOrDef = mHorizRuleCharOrDef = DEFAULT_CHAR;
mEscapeNext = mEatNextIfNewline = false;
mDebugMode = formatter.DebugLongComments;
mSourceStack.Clear();
mLinePrefix = formatter.FullLineCommentDelimiterPlus; // does not change
mBoxPrefix = formatter.FullLineCommentDelimiterBase; // changes if box char set
mBoxCharActual = mBoxPrefix[0];
DataSource source = new DataSource(Text, 0, null);
int textWidth = CalcTextWidth(source);
char[] outBuf = new char[MAX_WIDTH];
int outIndex = 0;
int outBreakIndex = -1;
List<string> lines = new List<string>(); List<string> lines = new List<string>();
string mod = Text.Replace("\r\n", "CRLF"); if (mDebugMode) {
for (int i = 0; i < mod.Length; i += 10) { for (int i = 0; i < mLineWidth; i++) {
lines.Add(formatter.FullLineCommentDelimiterPlus + outBuf[i] = (char)('0' + i % 10);
mod.Substring(i, Math.Min(10, mod.Length - i)));
} }
lines.Add(new string(outBuf, 0, mLineWidth));
}
// Walk through the input source.
while (true) {
if (source.Posn == source.Length) {
if (mSourceStack.Count != 0) {
source = mSourceStack.Pop();
textWidth = CalcTextWidth(source);
continue; // resume earlier string
}
break; // all done
}
if (source.CurChar == '\r' || source.CurChar == '\n') {
// Explicit line break. If it's a CRLF, eat both.
if (source.CurChar == '\r' && source.Posn + 1 < source.Length &&
source[source.Posn + 1] == '\n') {
source.Posn++;
}
mEscapeNext = false; // can't escape newlines
if (mEatNextIfNewline) {
mEatNextIfNewline = false;
} else {
// Output what we have.
OutputLine(outBuf, outIndex, source.mInBox, lines);
outIndex = 0;
outBreakIndex = -1;
}
source.Posn++;
continue;
}
mEatNextIfNewline = false;
char thisCh = source.CurChar;
if (thisCh == '\\') {
if (!mEscapeNext) {
mEscapeNext = true;
source.Posn++; // eat the backslash
continue; // restart loop; backslash might have been last char
}
} else if (thisCh == '[' && !mEscapeNext) {
// Start of format tag?
if (TryParseTag(source, out int skipLen, out DataSource subSource)) {
source.Posn += skipLen;
if (subSource != null) {
mSourceStack.Push(source);
source = subSource;
textWidth = CalcTextWidth(source);
}
continue;
}
} else if (thisCh == ' ') {
// Remember position of space for line break. If there are multiple
// consecutive spaces, remember the position of the first one.
if (outBreakIndex < 0 || outBuf[outBreakIndex] != ' ' ||
(outIndex > 0 && outBuf[outIndex - 1] != ' ')) {
outBreakIndex = outIndex;
}
}
// We need to add a character to the buffer. Will this put us over the limit?
if (outIndex == textWidth) {
int outputCount;
if (outBreakIndex <= 0) {
// No break found, or break char was at start of line. Just chop what
// we have.
outputCount = outIndex;
} else {
// Break was a hyphen or space.
outputCount = outBreakIndex;
}
int adj = 0;
if (outBuf[outputCount] == '-') {
// Break was a hyphen, include it.
adj = 1;
}
// Output everything up to the break point, but not the break char itself
// unless it's a hyphen.
OutputLine(outBuf, outputCount + adj, source.mInBox, lines);
// Consume any trailing spaces (which are about to become leading spaces).
while (outputCount < outIndex && outBuf[outputCount] == ' ') {
outputCount++;
}
// Copy any remaining chars to start of buffer.
outputCount += adj;
if (outputCount < outIndex) {
for (int i = 0; i < outIndex - outputCount; i++) {
outBuf[i] = outBuf[outputCount + i];
}
}
outIndex -= outputCount;
outBreakIndex = -1;
// If we're at the start of a line, eat all leading spaces. (This is what
// the WPF TextEdit dialog does when word-wrapping.)
if (outIndex == 0) {
while (source.Posn < source.Length && source.CurChar == ' ') {
source.Posn++;
}
if (source.Posn == source.Length) {
// Whoops, ran out of input.
continue;
}
}
}
if (source.CurChar == '-') {
// Can break on hyphen if it fits in line.
outBreakIndex = outIndex;
}
outBuf[outIndex++] = source[source.Posn++];
}
// If we didn't end with a CRLF, output the last bits.
if (outIndex > 0) {
OutputLine(outBuf, outIndex, source.mInBox, lines);
}
return lines; return lines;
} }
public override string ToString() { /// <summary>
return "MLC box=" + BoxMode + " width=" + MaxWidth + " text='" + Text + "'"; /// Attempts to parse a tag at the current source position.
/// </summary>
/// <remarks>
/// <para>This attempts to parse the full tag, including the closing tag if such is
/// appropriate.</para>
/// </remarks>
/// <param name="source">Input data source.</param>
/// <param name="skipLen">Number of characters to advance in data source.</param>
/// <param name="subSource">Result: data source with tag contents. May be null.</param>
/// <returns>True if the tag was successfully parsed.</returns>
private bool TryParseTag(DataSource source, out int skipLen, out DataSource subSource) {
skipLen = 0;
subSource = null;
// TODO
return false;
} }
/// <summary>
/// Adds the contents of the output buffer to the line list, prefixing it with comment
/// delimiters and/or wrapping it in a box.
/// </summary>
/// <param name="outBuf">Output buffer.</param>
/// <param name="length">Length of data in output buffer.</param>
/// <param name="inBox">True if we're inside a box.</param>
/// <param name="lines">Line list to add the line to.</param>
private void OutputLine(char[] outBuf, int length, bool inBox, List<string> lines) {
Debug.Assert(length >= 0);
mLineBuilder.Clear();
if (inBox) {
mLineBuilder.Append(mBoxPrefix);
mLineBuilder.Append(outBuf, 0, length);
int trailingCount = mLineWidth - mBoxPrefix.Length - length - 1;
if (trailingCount > 0) {
mLineBuilder.Append(SPACES, 0, trailingCount);
}
mLineBuilder.Append(mBoxCharActual);
} else {
mLineBuilder.Append(mLinePrefix);
mLineBuilder.Append(outBuf, 0, length);
}
string str = mLineBuilder.ToString();
if (mDebugMode) {
str = str.Replace(' ', '\u2219'); // replace spaces with BULLET OPERATOR
}
lines.Add(str);
}
#endregion Fancy
public override string ToString() {
if (IsFancy) {
return "MLC fancy text='" + Text + "'";
} else {
return "MLC box=" + BoxMode + " width=" + MaxWidth + " text='" + Text + "'";
}
}
public static bool operator ==(MultiLineComment a, MultiLineComment b) { public static bool operator ==(MultiLineComment a, MultiLineComment b) {
if (ReferenceEquals(a, b)) { if (ReferenceEquals(a, b)) {

View File

@ -89,16 +89,10 @@ bytes .byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f
.byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f .byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f
L1062 bit plataddr ;Pull in plataddr to see the comment on the platform file entry. L1062 bit plataddr ;Pull in plataddr to see the comment on the platform file entry.
;CRLFA triv ;
;ial fancy ;A trivial fancy comment. Nothing special about it at all. Go on about your
;comment.
;Nothing sp
;ecial abou
;t it at al
;l. Go on
;about your
;business. ;business.
;CRLFCRLF ;
lda #$10 lda #$10
lda #$11 lda #$11
lda #$12 lda #$12

View File

@ -87,16 +87,10 @@ bytes !hex 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f
!hex 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f !hex 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f
L1062 bit plataddr ;Pull in plataddr to see the comment on the platform file entry. L1062 bit plataddr ;Pull in plataddr to see the comment on the platform file entry.
;CRLFA triv ;
;ial fancy ;A trivial fancy comment. Nothing special about it at all. Go on about your
;comment.
;Nothing sp
;ecial abou
;t it at al
;l. Go on
;about your
;business. ;business.
;CRLFCRLF ;
lda #$10 lda #$10
lda #$11 lda #$11
lda #$12 lda #$12

View File

@ -89,16 +89,10 @@ bytes: .byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f
.byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f .byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f
L1062: bit plataddr ;Pull in plataddr to see the comment on the platform file entry. L1062: bit plataddr ;Pull in plataddr to see the comment on the platform file entry.
;CRLFA triv ;
;ial fancy ;A trivial fancy comment. Nothing special about it at all. Go on about your
;comment.
;Nothing sp
;ecial abou
;t it at al
;l. Go on
;about your
;business. ;business.
;CRLFCRLF ;
lda #$10 lda #$10
lda #$11 lda #$11
lda #$12 lda #$12

View File

@ -84,16 +84,10 @@ bytes hex 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f
hex 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f hex 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f
L1062 bit plataddr ;Pull in plataddr to see the comment on the platform file entry. L1062 bit plataddr ;Pull in plataddr to see the comment on the platform file entry.
*CRLFA triv *
*ial fancy *A trivial fancy comment. Nothing special about it at all. Go on about your
*comment.
*Nothing sp
*ecial abou
*t it at al
*l. Go on
*about your
*business. *business.
*CRLFCRLF *
lda #$10 lda #$10
lda #$11 lda #$11
lda #$12 lda #$12

View File

@ -1677,7 +1677,7 @@ namespace SourceGen.WpfGui {
toggleInstructionChartMenuItem.IsChecked = mMainCtrl.IsInstructionChartOpen; toggleInstructionChartMenuItem.IsChecked = mMainCtrl.IsInstructionChartOpen;
} }
private void DebugMenu_SubmenuOpened(object sender, RoutedEventArgs e) { private void DebugMenu_SubmenuOpened(object sender, RoutedEventArgs e) {
debugCommentRulersMenuItem.IsChecked = MultiLineComment.DebugShowRuler; debugCommentRulersMenuItem.IsChecked = mMainCtrl.DebugLongComments;
debugKeepAliveHackMenuItem.IsChecked = !Sandbox.ScriptManager.UseKeepAliveHack; debugKeepAliveHackMenuItem.IsChecked = !Sandbox.ScriptManager.UseKeepAliveHack;
debugSecuritySandboxMenuItem.IsChecked = mMainCtrl.UseMainAppDomainForPlugins; debugSecuritySandboxMenuItem.IsChecked = mMainCtrl.UseMainAppDomainForPlugins;
debugAnalysisTimersMenuItem.IsChecked = mMainCtrl.IsDebugAnalysisTimersOpen; debugAnalysisTimersMenuItem.IsChecked = mMainCtrl.IsDebugAnalysisTimersOpen;

View File

@ -38,3 +38,24 @@ SourceGen/RuntimeData directory has the system definitions used for the
"new project" list, along with subdirectories with symbol files and extension "new project" list, along with subdirectories with symbol files and extension
scripts. The [README file there](SourceGen/RuntimeData/README.md) scripts. The [README file there](SourceGen/RuntimeData/README.md)
explains a bit more. explains a bit more.
## Publishing a New Release ##
Steps:
1. Run Debug &gt; Source Generation Tests to verify that the code generation
tests pass. This requires that all cross-assemblers be installed and
configured.
2. Remove any existing `DIST_Release` directory from the top level.
3. In Visual Studio, change the build configuration to Release, and the startup project
to MakeDist.
4. Do a full clean build.
5. Hit F5 to start MakeDist. Click "Build" to generate a release build. The files will be
copied into `DIST_Release`.
6. Create an empty ZIP file (e.g. `6502bench123d1.zip`).
7. Copy all files from `DIST_Release` into it.
8. Submit all changes to git, push them to the server.
9. Create a new release on github. Drag the ZIP file into it.
10. Update/close any issues that have been addressed by the new release.
Version numbers should follow the semantic versioning scheme: v1.2.3, v1.2.3-dev1, etc.