1
0
mirror of https://github.com/fadden/6502bench.git synced 2026-04-22 01:16:42 +00:00

Add LocalVariableTable list to project

This involved adding a list to the DisasmProject, creating a new
UndoableChange type, and writing the project file serialization
code.  While doing the latter I realized that the new Width field
was redundant with the FormatDescriptor Length field, and removed it.

I added a placeholder line type, but we're not yet showing the
table in the display list.  (To edit the tables you just have to
know where they are.)
This commit is contained in:
Andy McFadden
2019-08-26 16:58:53 -07:00
parent 1cc9d2bd70
commit 0eeb36f59a
13 changed files with 362 additions and 114 deletions
+59 -26
View File
@@ -20,10 +20,15 @@ namespace SourceGen {
/// <summary>
/// Subclass of Symbol used for symbols defined in the platform or project.
///
/// Instances are immutable.
/// Instances are immutable, except for the Xrefs field.
/// </summary>
/// <remarks>
/// The Xrefs field isn't really part of the object. It's just convenient to reference
/// them from here.
/// </remarks>
public class DefSymbol : Symbol {
public const int NO_WIDTH = -1;
// width to use when width doesn't matter; use 1 to try to get a prefab object
public const int NO_WIDTH = 1;
public const int MIN_WIDTH = 1;
public const int MAX_WIDTH = 4;
@@ -41,33 +46,36 @@ namespace SourceGen {
/// Platform symbols only: tag used to organize symbols into groups. Used by
/// extension scripts.
/// </summary>
/// <remarks>
/// This is not included in DefSymbol serialization because symbols with tags are
/// not stored in the project file. It's only set when symbols are parsed out of
/// platform symbol files.
/// </remarks>
public string Tag { get; private set; }
/// <summary>
/// Number of bytes referenced by the symbol. Useful for identifying multi-byte items,
/// such as two-byte and three-byte pointers. Used for Variables. Value will be
/// NO_WIDTH if unset.
/// </summary>
public int Width { get; private set; }
/// <summary>
/// Cross-reference data, generated by the analyzer.
/// </summary>
/// <remarks>
/// This is just a convenient place to reference some data generated at run-time. It's
/// not serialized, and not included in the test for equality.
/// </remarks>
public XrefSet Xrefs { get; private set; }
// NOTE: might be nice to identify the symbol's origin, e.g. which platform
// symbol file it was defined in. This could then be stored in a
// DisplayList line, for benefit of the Info panel.
/// <summary>
/// Internal base-object constructor, called by other constructors.
/// </summary>
private DefSymbol(string label, int value, Source source, Type type)
: base(label, value, source, type) {
Debug.Assert(source == Source.Platform || source == Source.Project);
Debug.Assert(source == Source.Platform || source == Source.Project ||
source == Source.Variable);
Debug.Assert(type == Type.ExternalAddr || type == Type.Constant);
Xrefs = new XrefSet();
Width = NO_WIDTH;
}
/// <summary>
@@ -83,20 +91,10 @@ namespace SourceGen {
/// <param name="tag">Symbol tag, used for grouping platform symbols.</param>
public DefSymbol(string label, int value, Source source, Type type,
FormatDescriptor.SubType formatSubType, string comment, string tag)
: this(label, value, source, type) {
Debug.Assert(comment != null);
Debug.Assert(tag != null);
// Length doesn't matter; use 1 to get prefab object.
DataDescriptor = FormatDescriptor.Create(1,
FormatDescriptor.Type.NumericLE, formatSubType);
Comment = comment;
Tag = tag;
}
: this(label, value, source, type, formatSubType, comment, tag, NO_WIDTH) { }
/// <summary>
/// Constructor.
/// Constructor. Used for local variables, which have a meaningful width.
/// </summary>
/// <param name="label">Symbol's label.</param>
/// <param name="value">Symbol's value.</param>
@@ -109,9 +107,15 @@ namespace SourceGen {
/// <param name="width">Variable width.</param>
public DefSymbol(string label, int value, Source source, Type type,
FormatDescriptor.SubType formatSubType, string comment, string tag, int width)
: this(label, value, source, type, formatSubType, comment, tag) {
Debug.Assert(width == NO_WIDTH || (width >= MIN_WIDTH && width <= MAX_WIDTH));
Width = width;
: this(label, value, source, type) {
Debug.Assert(comment != null);
Debug.Assert(tag != null);
DataDescriptor = FormatDescriptor.Create(width,
FormatDescriptor.Type.NumericLE, formatSubType);
Comment = comment;
Tag = tag;
}
/// <summary>
@@ -130,6 +134,35 @@ namespace SourceGen {
Tag = string.Empty;
}
public static bool operator ==(DefSymbol a, DefSymbol b) {
if (ReferenceEquals(a, b)) {
return true; // same object, or both null
}
if (ReferenceEquals(a, null) || ReferenceEquals(b, null)) {
return false; // one is null
}
// All fields must be equal, except Xrefs.
if (a.DataDescriptor != b.DataDescriptor ||
a.Comment != b.Comment ||
a.Tag != b.Tag) {
return false;
}
return true;
}
public static bool operator !=(DefSymbol a, DefSymbol b) {
return !(a == b);
}
public override bool Equals(object obj) {
return obj is DefSymbol && this == (DefSymbol)obj;
}
public override int GetHashCode() {
return base.GetHashCode() ^
DataDescriptor.GetHashCode() ^
Comment.GetHashCode() ^
Tag.GetHashCode();
}
public override string ToString() {
return base.ToString() + ":" + DataDescriptor + ";" + Comment +
(string.IsNullOrEmpty(Tag) ? "" : " [" + Tag + "]");