1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-07-27 11:29:01 +00:00

Fancy comments, part 1

Added a "fancy" flag to MultiLineComment.  If set, we will use
formatting commands embedded in the text itself.  The max width pop-up
and "boxed" flag will be ignored in favor of width and boxing
directives.  (See issue #111.)

The current "fancy" formatter is just a placeholder that folds lines
every 10 characters.

Removed FormattedMlcCache (added two changes back).  Caching the
rendered string list in the MLC itself is simpler and more efficient
than having a separate cache, and it works for Notes as well.

Added anchors for more comments in the 20090 test.
This commit is contained in:
Andy McFadden 2024-07-04 16:04:33 -07:00
parent 14cacb4274
commit 83da0d952c
18 changed files with 432 additions and 179 deletions

View File

@ -24,7 +24,10 @@ namespace CommonWPF {
/// Miscellaneous helper functions.
/// </summary>
public static class Helper {
public static Color ZeroColor = Color.FromArgb(0, 0, 0, 0);
/// <summary>
/// Transparent black.
/// </summary>
public static readonly Color ZeroColor = Color.FromArgb(0, 0, 0, 0);
/// <summary>
/// Measures the size of a string when rendered with the specified parameters. Uses

View File

@ -20,7 +20,7 @@ namespace CommonWPF {
/// <summary>
/// A value inverter for negating a boolean value (value --> !value).
///
/// See https://stackoverflow.com/questions/1039636/how-to-bind-inverse-boolean-properties-in-wpf
/// From <see href="https://stackoverflow.com/a/1039681/294248"/>.
/// </summary>
[ValueConversion(typeof(bool), typeof(bool))]
public class InverseBooleanConverter : IValueConverter {

View File

@ -17,9 +17,12 @@ limitations under the License.
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SourceGen"
xmlns:common="clr-namespace:CommonWPF;assembly=CommonWPF"
StartupUri="WpfGui/MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<common:InverseBooleanConverter x:Key="InvertBool"/>
<FontFamily x:Key="GeneralMonoFont">Consolas</FontFamily>
<!-- gradient background for bitmap images -->

View File

@ -1,117 +0,0 @@
/*
* Copyright 2024 faddenSoft
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Asm65;
namespace SourceGen {
/// <summary>
/// Holds a cache of formatted multi-line comments.
/// </summary>
/// <remarks>
/// <para>We need to discard the entry if the MLC changes or the formatting parameters
/// change. MLCs are immutable and Formatters can't be reconfigured, so we can just do
/// a quick reference equality check.</para>
/// </remarks>
public class FormattedMlcCache {
/// <summary>
/// One entry in the cache.
/// </summary>
private class FormattedStringEntry {
public List<string> Lines { get; private set; }
private MultiLineComment mMlc;
private Formatter mFormatter;
public FormattedStringEntry(List<string> lines, MultiLineComment mlc,
Formatter formatter) {
// Can't be sure the list won't change, so duplicate it.
Lines = new List<string>(lines.Count);
foreach (string str in lines) {
Lines.Add(str);
}
mMlc = mlc;
mFormatter = formatter;
}
/// <summary>
/// Checks the entry's dependencies.
/// </summary>
/// <returns>True if the dependencies match.</returns>
public bool CheckDeps(MultiLineComment mlc, Formatter formatter) {
bool ok = (ReferenceEquals(mMlc, mlc) && ReferenceEquals(mFormatter, formatter));
return ok;
}
}
/// <summary>
/// Cached entries, keyed by file offset.
/// </summary>
private Dictionary<int, FormattedStringEntry> mStringEntries =
new Dictionary<int, FormattedStringEntry>();
/// <summary>
/// Retrieves the formatted string data for the specified offset.
/// </summary>
/// <param name="offset">File offset.</param>
/// <param name="formatter">Formatter dependency.</param>
/// <returns>A reference to the string list, or null if the entry is absent or invalid.
/// The caller must not modify the list.</returns>
public List<string> GetStringEntry(int offset, MultiLineComment mlc, Formatter formatter) {
if (!mStringEntries.TryGetValue(offset, out FormattedStringEntry entry)) {
DebugNotFoundCount++;
return null;
}
if (!entry.CheckDeps(mlc, formatter)) {
//Debug.WriteLine(" stale entry at +" + offset.ToString("x6"));
DebugFoundStaleCount++;
return null;
}
DebugFoundValidCount++;
return entry.Lines;
}
/// <summary>
/// Sets the string data entry for the specified offset.
/// </summary>
/// <param name="offset">File offset.</param>
/// <param name="lines">String data.</param>
/// <param name="mlc">Multi-line comment to be formatted.</param>
/// <param name="formatter">Formatter dependency.</param>
public void SetStringEntry(int offset, List<string> lines, MultiLineComment mlc,
Formatter formatter) {
Debug.Assert(lines != null);
FormattedStringEntry fse = new FormattedStringEntry(lines, mlc, formatter);
mStringEntries[offset] = fse;
}
// Some counters for evaluating efficacy.
public int DebugFoundValidCount { get; private set; }
public int DebugFoundStaleCount { get; private set; }
public int DebugNotFoundCount { get; private set; }
public void DebugResetCounters() {
DebugFoundValidCount = DebugFoundStaleCount = DebugNotFoundCount = 0;
}
public void DebugLogCounters() {
Debug.WriteLine("MLC cache: valid=" + DebugFoundValidCount + ", stale=" +
DebugFoundStaleCount + ", missing=" + DebugNotFoundCount);
}
}
}

View File

@ -76,11 +76,6 @@ namespace SourceGen {
/// </summary>
private FormattedOperandCache mFormattedLineCache = new FormattedOperandCache();
/// <summary>
/// Cache of previous-formatted multi-line comment strings.
/// </summary>
private FormattedMlcCache mFormattedMlcCache = new FormattedMlcCache();
/// <summary>
/// Local variable table data extractor.
/// </summary>
@ -1057,14 +1052,7 @@ namespace SourceGen {
spaceAdded = true;
}
if (mProject.LongComments.TryGetValue(offset, out MultiLineComment longComment)) {
List<string> formatted = mFormattedMlcCache.GetStringEntry(offset, longComment,
mFormatter);
if (formatted == null) {
Debug.WriteLine("Render " + longComment);
formatted = longComment.FormatText(mFormatter, string.Empty);
mFormattedMlcCache.SetStringEntry(offset, formatted, longComment,
mFormatter);
}
List<string> formatted = longComment.FormatText(mFormatter, string.Empty);
StringListToLines(formatted, offset, Line.Type.LongComment,
longComment.BackgroundColor, NoteColorMultiplier, lines);
spaceAdded = true;
@ -1768,11 +1756,9 @@ namespace SourceGen {
public void DebugResetCacheCounters() {
mFormattedLineCache.DebugResetCounters();
mFormattedMlcCache.DebugResetCounters();
}
public void DebugLogCacheCounters() {
mFormattedLineCache.DebugLogCounters();
mFormattedMlcCache.DebugLogCounters();
}
}
}

View File

@ -21,10 +21,13 @@ using System.Text;
namespace SourceGen {
/// <summary>
/// Representation of a multi-line comment, which is a string plus some format directives.
/// Used for long comments and notes.
/// <para>Representation of a multi-line comment, which is a string plus some format options.
/// Used for long comments and notes.</para>
///
/// Instances are immutable.
/// <para>Instances are effectively immutable, as the text and options can't be modified
/// after the object is created. The object does cache the result of the last FormatText()
/// call, which is determined in part by the Formatter argument, which can change between
/// calls.</para>
/// </summary>
public class MultiLineComment {
/// <summary>
@ -37,6 +40,12 @@ namespace SourceGen {
/// </summary>
public string Text { get; private set; }
/// <summary>
/// True if this uses "fancy" formatting. If set, the BoxMode and MaxWidth properties
/// are ignored.
/// </summary>
public bool IsFancy { get; private set; }
/// <summary>
/// Set to true to render text surrounded by a box of ASCII characters.
/// </summary>
@ -57,27 +66,50 @@ namespace SourceGen {
/// </summary>
private const char BASIC_BOX_CHAR = '*';
private const int DEFAULT_WIDTH = 80;
private const int MIN_WIDTH = 8;
/// <summary>
/// Constructor. Object will have a max width of 80 and not be boxed.
/// Constructor. By default, comments use basic formatting, have a basic-mode max
/// width of 80, and aren't boxed.
/// </summary>
/// <remarks>
/// We'd actually prefer to have fancy formatting be the default, but that does the
/// wrong thing when deserializing older projects.
/// </remarks>
/// <param name="text">Unformatted comment text.</param>
public MultiLineComment(string text) {
Debug.Assert(text != null); // empty string is okay
Text = text;
IsFancy = false;
BoxMode = false;
MaxWidth = 80;
MaxWidth = DEFAULT_WIDTH;
BackgroundColor = CommonWPF.Helper.ZeroColor;
}
/// <summary>
/// Constructor. Used when creating an empty MLC for editing.
/// </summary>
/// <param name="isFancy">True if we want to be in "fancy" mode initially.</param>
public MultiLineComment(bool isFancy) : this(string.Empty) {
IsFancy = isFancy;
}
/// <summary>
/// Constructor. Used for long comments.
/// </summary>
/// <param name="text">Unformatted text.</param>
/// <param name="boxMode">Set to true to enable box mode.</param>
/// <param name="maxWidth">Maximum line width.</param>
public MultiLineComment(string text, bool boxMode, int maxWidth) : this(text) {
Debug.Assert((!boxMode && maxWidth > 1) || (boxMode && maxWidth > 5));
/// <param name="isFancy">True if we're using fancy format mode.</param>
/// <param name="boxMode">For basic mode, set to true to enable box mode.</param>
/// <param name="maxWidth">For basic mode, maximum line width.</param>
public MultiLineComment(string text, bool isFancy, bool boxMode, int maxWidth)
: this(text) {
if (maxWidth < MIN_WIDTH) {
Debug.Assert(false, "unexpectedly small max width");
maxWidth = MIN_WIDTH;
}
IsFancy = isFancy;
BoxMode = boxMode;
MaxWidth = maxWidth;
}
@ -91,14 +123,46 @@ namespace SourceGen {
BackgroundColor = bkgndColor;
}
private List<string> mPreviousRender = null;
private Asm65.Formatter mPreviousFormatter = null;
private string mPreviousPrefix = null;
/// <summary>
/// Generates one or more lines of formatted text.
/// </summary>
/// <param name="formatter">Formatter, with comment delimiters.</param>
/// <param name="textPrefix">String to prepend to text before formatting. If this
/// is non-empty, comment delimiters aren't emitted. (Used for notes.)</param>
/// <returns>Array of formatted strings.</returns>
/// <returns>List of formatted strings. Do not modify the list.</returns>
public List<string> FormatText(Asm65.Formatter formatter, string textPrefix) {
if (mPreviousRender != null && formatter == mPreviousFormatter &&
textPrefix == mPreviousPrefix) {
// We rendered this with the same formatter before. Return the list. It would
// be safer to clone the list, but I'm not expecting the caller to edit it.
return mPreviousRender;
}
List<string> lines;
if (IsFancy) {
Debug.Assert(string.IsNullOrEmpty(textPrefix));
lines = FormatFancyText(formatter);
} else {
lines = FormatSimpleText(formatter, textPrefix);
}
// Cache result.
mPreviousRender = lines;
mPreviousFormatter = formatter;
mPreviousPrefix = textPrefix;
return lines;
}
/// <summary>
/// Generates one or more lines of formatted text, using the basic formatter.
/// </summary>
/// <param name="formatter">Formatter, with comment delimiters.</param>
/// <param name="textPrefix">String to prepend to text before formatting. If this
/// is non-empty, comment delimiters aren't emitted. (Used for notes.)</param>
/// <returns>List of formatted strings.</returns>
private List<string> FormatSimpleText(Asm65.Formatter formatter, string textPrefix) {
const char spcRep = '\u2219'; // BULLET OPERATOR
string workString = string.IsNullOrEmpty(textPrefix) ? Text : textPrefix + Text;
List<string> lines = new List<string>();
@ -263,6 +327,20 @@ namespace SourceGen {
return lines;
}
/// <summary>
/// Generates one or more lines of formatted text, using the fancy formatter.
/// </summary>
/// <param name="formatter">Formatter, with comment delimiters.</param>
/// <returns>List of formatted strings.</returns>
private List<string> FormatFancyText(Asm65.Formatter formatter) {
List<string> lines = new List<string>();
string mod = Text.Replace("\r\n", "CRLF");
for (int i = 0; i < mod.Length; i += 10) {
lines.Add(formatter.FullLineCommentDelimiterPlus +
mod.Substring(i, Math.Min(10, mod.Length - i)));
}
return lines;
}
public override string ToString() {
return "MLC box=" + BoxMode + " width=" + MaxWidth + " text='" + Text + "'";

View File

@ -283,6 +283,7 @@ namespace SourceGen {
public class SerMultiLineComment {
// NOTE: Text must be CRLF at line breaks.
public string Text { get; set; }
public bool IsFancy { get; set; }
public bool BoxMode { get; set; }
public int MaxWidth { get; set; }
public int BackgroundColor { get; set; }
@ -290,6 +291,7 @@ namespace SourceGen {
public SerMultiLineComment() { }
public SerMultiLineComment(MultiLineComment mlc) {
Text = mlc.Text;
IsFancy = mlc.IsFancy;
BoxMode = mlc.BoxMode;
MaxWidth = mlc.MaxWidth;
BackgroundColor = CommonWPF.Helper.ColorToInt(mlc.BackgroundColor);
@ -762,7 +764,7 @@ namespace SourceGen {
continue;
}
proj.LongComments[intKey] = new MultiLineComment(kvp.Value.Text,
kvp.Value.BoxMode, kvp.Value.MaxWidth);
kvp.Value.IsFancy, kvp.Value.BoxMode, kvp.Value.MaxWidth);
}
// Deserialize notes.

View File

@ -1,8 +1,8 @@
### 6502bench SourceGen dis65 v1.0 ###
{
"_ContentVersion":5,
"FileDataLength":98,
"FileDataCrc32":-80207687,
"_ContentVersion":6,
"FileDataLength":169,
"FileDataCrc32":-1449180249,
"ProjectProps":{
"CpuName":"6502",
"IncludeUndocumentedInstr":false,
@ -28,6 +28,8 @@
"Addr":4096,
"Length":-1024,
"PreLabel":"",
"DisallowInward":false,
"DisallowOutward":false,
"IsRelative":false}],
"TypeHints":[{
"Low":0,
@ -41,97 +43,119 @@
"2":"\u0026another comment with \u0026\u0026s!",
"8":"comment ending in backslash\\",
"10":"comment, with, commas \\\\ \\\" \\/ \\\\\\",
"30":"Pull in plataddr to see the comment on the platform file entry.",
"34":"Comment at the end of a lengthy bulk hex item might overflow various things, but could be wrapped."},
"34":"Comment at the end of a lengthy bulk hex item might overflow various things, but could be wrapped.",
"98":"Pull in plataddr to see the comment on the platform file entry."},
"LongComments":{
"-2147483647":{
"Text":"Old school boxed output header. Brk\r\nmultiple lines yay. How about a hy-phenated word?\r\nLooonglonglonglonglonglonglonglonglonglonglongword.\r\n*\r\nThrow in a line divider. These aren\u0027t:\r\n*!\r\n *\r\n\u0026XYZ\r\n\r\n",
"IsFancy":false,
"BoxMode":true,
"MaxWidth":40,
"BackgroundColor":0},
"0":{
"Text":"Short, unboxed comment here!! Two spaces after. More hyp-hens?\r\n",
"IsFancy":false,
"BoxMode":false,
"MaxWidth":30,
"BackgroundColor":0},
"2":{
"Text":"Comment rulers can be helpful in findin the edges of notes. Comments are hyph-enatingly fun. Like the note, this goes out to 80 columns.",
"IsFancy":false,
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":0},
"4":{
"Text":"Down to 64 columns this time. Why 64? Why not 64. A rose, by any other name, would break the line at the same place. Or hy-phen split.\r\n",
"IsFancy":false,
"BoxMode":false,
"MaxWidth":64,
"BackgroundColor":0},
"6":{
"Text":"Ah, the classic 40-column limitation... brings back memories. Of, you know, h-yphenated things.",
"IsFancy":false,
"BoxMode":false,
"MaxWidth":40,
"BackgroundColor":0},
"8":{
"Text":"Thirty columns. \u0027cause forty felt like too many. Oh, hyp-henation!",
"IsFancy":false,
"BoxMode":false,
"MaxWidth":30,
"BackgroundColor":0},
"10":{
"Text":"Short box comment, 80 cols.",
"IsFancy":false,
"BoxMode":true,
"MaxWidth":80,
"BackgroundColor":0},
"12":{
"Text":"\r\nChoppy\r\n\r\nbox\r\n\r\ncomment\r\n\r\n64 cols\r\n\r\n",
"IsFancy":false,
"BoxMode":true,
"MaxWidth":64,
"BackgroundColor":0},
"14":{
"Text":"Some non-ASCII stuff:\r\n†•<E280A0>␇\r\n(right side of box looks pushed over on-screen because font isn\u0027t fully mono)",
"IsFancy":false,
"BoxMode":true,
"MaxWidth":64,
"BackgroundColor":0},
"16":{
"Text":"Specific line break case at end of. Sentence.\r\nAlternate version for semicolon zz. Output.\r\n\r\nSame thing but with three spaces zz. Three!\r\nAgain with the three spces between. Things.\r\n\r\nTry to make it the very last thing.. ",
"IsFancy":false,
"BoxMode":true,
"MaxWidth":40,
"BackgroundColor":0},
"101":{
"Text":"\r\nA trivial fancy comment. Nothing special about it at all. Go on about your business.\r\n\r\n",
"IsFancy":true,
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":0}},
"Notes":{
"0":{
"Text":"And now, a note.",
"IsFancy":false,
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":-7278960},
"2":{
"Text":"Another note, this one longer. We don\u0027t get to see where the lines break, which makes it harder to hit the edges.",
"IsFancy":false,
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":-5383962},
"4":{
"Text":"Another day, another note.",
"IsFancy":false,
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":-256},
"6":{
"Text":"Take note!",
"IsFancy":false,
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":-18751},
"8":{
"Text":"Duly noted.",
"IsFancy":false,
"BoxMode":false,
"MaxWidth":80,
"BackgroundColor":-23296}},
@ -149,7 +173,8 @@
"Length":64,
"Format":"Dense",
"SubFormat":"None",
"SymbolRef":null}},
"SymbolRef":null,
"Extra":null}},
"LvTables":{
},

View File

@ -80,10 +80,58 @@ plataddr = $3000 ;address only in platform file
lda #$0d
lda #$0e
lda #$0f
bit plataddr ;Pull in plataddr to see the comment on the platform file entry.
rts
jmp L1062
.byte $ea
bytes .byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f ;Comment at the end of a lengthy bulk hex item might overflow various things, but could be wrapped.
.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.
;CRLFA triv
;ial fancy
;comment.
;Nothing sp
;ecial abou
;t it at al
;l. Go on
;about your
; business.
;CRLFCRLF
lda #$10
lda #$11
lda #$12
lda #$13
lda #$14
lda #$15
lda #$16
lda #$17
lda #$18
lda #$19
lda #$1a
lda #$1b
lda #$1c
lda #$1d
lda #$1e
lda #$1f
lda #$20
lda #$21
lda #$22
lda #$23
lda #$24
lda #$25
lda #$26
lda #$27
lda #$28
lda #$29
lda #$2a
lda #$2b
lda #$2c
lda #$2d
lda #$2e
lda #$2f
jmp _L10A8
_L10A8 rts

View File

@ -80,8 +80,56 @@ plataddr = $3000 ;address only in platform file
lda #$0d
lda #$0e
lda #$0f
bit plataddr ;Pull in plataddr to see the comment on the platform file entry.
rts
jmp L1062
!byte $ea
bytes !hex 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f ;Comment at the end of a lengthy bulk hex item might overflow various things, but could be wrapped.
!hex 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f
L1062 bit plataddr ;Pull in plataddr to see the comment on the platform file entry.
;CRLFA triv
;ial fancy
;comment.
;Nothing sp
;ecial abou
;t it at al
;l. Go on
;about your
; business.
;CRLFCRLF
lda #$10
lda #$11
lda #$12
lda #$13
lda #$14
lda #$15
lda #$16
lda #$17
lda #$18
lda #$19
lda #$1a
lda #$1b
lda #$1c
lda #$1d
lda #$1e
lda #$1f
lda #$20
lda #$21
lda #$22
lda #$23
lda #$24
lda #$25
lda #$26
lda #$27
lda #$28
lda #$29
lda #$2a
lda #$2b
lda #$2c
lda #$2d
lda #$2e
lda #$2f
jmp @L10A8
@L10A8 rts

View File

@ -80,10 +80,58 @@ plataddr = $3000 ;address only in platform file
lda #$0d
lda #$0e
lda #$0f
bit plataddr ;Pull in plataddr to see the comment on the platform file entry.
rts
jmp L1062
.byte $ea
bytes: .byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f ;Comment at the end of a lengthy bulk hex item might overflow various things, but could be wrapped.
.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.
;CRLFA triv
;ial fancy
;comment.
;Nothing sp
;ecial abou
;t it at al
;l. Go on
;about your
; business.
;CRLFCRLF
lda #$10
lda #$11
lda #$12
lda #$13
lda #$14
lda #$15
lda #$16
lda #$17
lda #$18
lda #$19
lda #$1a
lda #$1b
lda #$1c
lda #$1d
lda #$1e
lda #$1f
lda #$20
lda #$21
lda #$22
lda #$23
lda #$24
lda #$25
lda #$26
lda #$27
lda #$28
lda #$29
lda #$2a
lda #$2b
lda #$2c
lda #$2d
lda #$2e
lda #$2f
jmp @L10A8
@L10A8: rts

View File

@ -77,8 +77,56 @@ plataddr equ $3000 ;address only in platform file
lda #$0d
lda #$0e
lda #$0f
bit plataddr ;Pull in plataddr to see the comment on the platform file entry.
rts
jmp L1062
dfb $ea
bytes hex 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f ;Comment at the end of a lengthy bulk hex item might overflow various things, but could be wrapped.
hex 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f
L1062 bit plataddr ;Pull in plataddr to see the comment on the platform file entry.
*CRLFA triv
*ial fancy
*comment.
*Nothing sp
*ecial abou
*t it at al
*l. Go on
*about your
* business.
*CRLFCRLF
lda #$10
lda #$11
lda #$12
lda #$13
lda #$14
lda #$15
lda #$16
lda #$17
lda #$18
lda #$19
lda #$1a
lda #$1b
lda #$1c
lda #$1d
lda #$1e
lda #$1f
lda #$20
lda #$21
lda #$22
lda #$23
lda #$24
lda #$25
lda #$26
lda #$27
lda #$28
lda #$29
lda #$2a
lda #$2b
lda #$2c
lda #$2d
lda #$2e
lda #$2f
jmp :L10A8
:L10A8 rts

View File

@ -10,6 +10,7 @@ plataddr equ $3000 ;defined in TestSyms
org $1000
; places to put "basic" comments
lda #$01
lda #$02
lda #$03
@ -26,10 +27,53 @@ plataddr equ $3000 ;defined in TestSyms
lda #$0e
lda #$0f
bit plataddr
rts
jmp next
nop
; multi-line operand
hex 000102030405060708090a0b0c0d0e0f
hex 000102030405060708090a0b0c0d0e0f
hex 000102030405060708090a0b0c0d0e0f
hex 000102030405060708090a0b0c0d0e0f
next
bit plataddr ;pull in platform symbol, with comment
lda #$10
lda #$11
lda #$12
lda #$13
lda #$14
lda #$15
lda #$16
lda #$17
lda #$18
lda #$19
lda #$1a
lda #$1b
lda #$1c
lda #$1d
lda #$1e
lda #$1f
lda #$20
lda #$21
lda #$22
lda #$23
lda #$24
lda #$25
lda #$26
lda #$27
lda #$28
lda #$29
lda #$2a
lda #$2b
lda #$2c
lda #$2d
lda #$2e
lda #$2f
jmp done
done rts

View File

@ -52,6 +52,7 @@ namespace SourceGen {
public class SerMultiLineComment {
// NOTE: Text must be CRLF at line breaks.
public string Text { get; set; }
public bool IsFancy { get; set; }
public bool BoxMode { get; set; }
public int MaxWidth { get; set; }
public int BackgroundColor { get; set; }
@ -59,6 +60,7 @@ namespace SourceGen {
public SerMultiLineComment() { }
public SerMultiLineComment(MultiLineComment mlc) {
Text = mlc.Text;
IsFancy = mlc.IsFancy;
BoxMode = mlc.BoxMode;
MaxWidth = mlc.MaxWidth;
BackgroundColor = CommonWPF.Helper.ColorToInt(mlc.BackgroundColor);
@ -288,7 +290,7 @@ namespace SourceGen {
mlc = new MultiLineComment(smlc.Text,
CommonWPF.Helper.ColorFromInt(smlc.BackgroundColor));
} else {
mlc = new MultiLineComment(smlc.Text, smlc.BoxMode, smlc.MaxWidth);
mlc = new MultiLineComment(smlc.Text, smlc.IsFancy, smlc.BoxMode, smlc.MaxWidth);
}
return true;
}

View File

@ -81,7 +81,6 @@
<Compile Include="AsmGen\LabelLocalizer.cs" />
<Compile Include="DailyTips.cs" />
<Compile Include="Exporter.cs" />
<Compile Include="FormattedMlcCache.cs" />
<Compile Include="FormattedOperandCache.cs" />
<Compile Include="LabelFileGenerator.cs" />
<Compile Include="LocalVariableLookup.cs" />

View File

@ -56,12 +56,24 @@ limitations under the License.
FontFamily="{StaticResource GeneralMonoFont}" VerticalScrollBarVisibility="Visible"
AcceptsReturn="True" TextWrapping="Wrap"/>
<StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,20,0,0">
<TextBlock Text="Maximum line width:" Margin="0,3,0,0"/>
<ComboBox Name="maxWidthComboBox" Width="75" Margin="8,0,0,0"
ItemsSource="{Binding LineWidthItems}" SelectionChanged="MaxWidthComboBox_SelectionChanged"/>
<CheckBox Content="Render in _box" Margin="40,4,0,0" IsChecked="{Binding RenderInBox}"/>
</StackPanel>
<Grid Grid.Row="2" Margin="0,20,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<CheckBox Grid.Column="0" Content="Enable fancy formatting" Margin="0,4,0,0"
IsChecked="{Binding IsFancyEnabled}"/>
<StackPanel Grid.Column="1" Orientation="Horizontal"
IsEnabled="{Binding Path=IsFancyEnabled, Converter={StaticResource InvertBool}}">
<TextBlock Text="Line width:" Margin="0,3,0,0"/>
<ComboBox Name="maxWidthComboBox" Width="75" Margin="8,0,0,0"
ItemsSource="{Binding LineWidthItems}" SelectionChanged="MaxWidthComboBox_SelectionChanged"/>
</StackPanel>
<CheckBox Grid.Column="2" Content="Render in _box" Margin="0,4,0,0"
IsEnabled="{Binding Path=IsFancyEnabled, Converter={StaticResource InvertBool}}"
IsChecked="{Binding RenderInBox}"/>
</Grid>
<TextBlock Grid.Row="3" Text="Expected output:" Margin="0,20,0,0"/>
<TextBox Name="displayTextBox" Grid.Row="4"

View File

@ -28,6 +28,12 @@ namespace SourceGen.WpfGui {
/// Long comment editor.
/// </summary>
public partial class EditLongComment : Window, INotifyPropertyChanged {
// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
/// <summary>
/// Get or set the multi-line comment object. On exit, will be set to null if
/// the user wants to delete the comment.
@ -36,6 +42,22 @@ namespace SourceGen.WpfGui {
private Asm65.Formatter mFormatter;
/// <summary>
/// Checkbox state for fancy-mode toggle.
/// </summary>
public bool IsFancyEnabled {
get { return mIsFancyEnabled; }
set {
mIsFancyEnabled = value;
OnPropertyChanged();
FormatInput();
}
}
private bool mIsFancyEnabled;
/// <summary>
/// Checkbox state for basic-mode boxing.
/// </summary>
public bool RenderInBox {
get { return mRenderInBox; }
set {
@ -60,7 +82,7 @@ namespace SourceGen.WpfGui {
private string mUserInput;
/// <summary>
/// Generated text output. This is bound to the output TextBox.
/// Generated text output. This is bound to the output TextBox, for display.
/// </summary>
public string TextOutput {
get { return mTextOutput; }
@ -71,30 +93,31 @@ namespace SourceGen.WpfGui {
}
private string mTextOutput;
// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
/// <summary>
/// ItemsSource for line width combo box.
/// </summary>
public int[] LineWidthItems { get; } = new int[] { 30, 40, 64, 80 };
/// <summary>
/// Dialog constructor. Pass in the current formatter object.
/// </summary>
public EditLongComment(Window owner, Asm65.Formatter formatter) {
InitializeComponent();
Owner = owner;
DataContext = this;
mFormatter = formatter;
LongComment = new MultiLineComment(string.Empty);
LongComment = new MultiLineComment(true);
}
/// <summary>
/// Configures dialog controls after the window finishes loading.
/// </summary>
private void Window_Loaded(object sender, RoutedEventArgs e) {
Debug.Assert(LongComment != null);
UserInput = LongComment.Text;
IsFancyEnabled = LongComment.IsFancy;
RenderInBox = LongComment.BoxMode;
// Try to find a match for the max width specified in the MLC.
@ -133,7 +156,8 @@ namespace SourceGen.WpfGui {
}
/// <summary>
/// Formats entryTextBox.Text into displayTextBox.Text.
/// Formats entryTextBox.Text into displayTextBox.Text. This is done every time the
/// user makes a change to the text entry box.
/// </summary>
private void FormatInput() {
if (!IsLoaded) {
@ -170,7 +194,7 @@ namespace SourceGen.WpfGui {
if (maxWidthComboBox.SelectedItem == null) {
return null; // still initializing
}
return new MultiLineComment(UserInput, RenderInBox,
return new MultiLineComment(UserInput, IsFancyEnabled, RenderInBox,
(int)maxWidthComboBox.SelectedItem);
}
}