More symbols improvements

This commit is contained in:
Adrian Conlon
2024-09-18 11:19:41 +01:00
parent 93c753c596
commit 0621b9ed1d
16 changed files with 70 additions and 24 deletions

View File

@@ -5,13 +5,13 @@
namespace Symbols
{
// file id=0,name="sudoku.s",size=9141,mtime=0x6027C7F0,mod=0
public class File(Parser container) : NamedSection(container)
public sealed class File(Parser container) : NamedSection(container)
{
[SectionProperty("size")]
public int Size => this.TakeInteger("size");
[SectionProperty("mtime", hexadecimal: true)]
public long ModificationTime => this.TakeLong("mtime");
[SectionProperty("mtime")]
public DateTime ModificationTime => this.TakeDateTime("mtime");
[SectionReference("mod")]
public Symbols.Module Module => this.TakeModuleReference();

View File

@@ -5,7 +5,7 @@
namespace Symbols
{
//info csym = 0, file = 3, lib = 0, line = 380, mod = 1, scope = 12, seg = 8, span = 356, sym = 61, type = 3
public class Information : Section
public sealed class Information : Section
{
public Information(Parser container)
: base(container)

View File

@@ -5,7 +5,7 @@
namespace Symbols
{
// line id = 268, file = 1, line = 60, type = 2, count = 1, span = 286 + 195
public class Line(Parser container) : IdentifiableSection(container)
public sealed class Line(Parser container) : IdentifiableSection(container)
{
[SectionReference("file")]
public Symbols.File File => this.TakeFileReference();

View File

@@ -5,7 +5,7 @@
namespace Symbols
{
// mod id=0,name="sudoku.o",file=0
public class Module(Parser container) : NamedSection(container)
public sealed class Module(Parser container) : NamedSection(container)
{
[SectionReference("file")]
public Symbols.File File => this.TakeFileReference();

View File

@@ -31,7 +31,7 @@
{
get
{
if (_files == null)
if (this._files == null)
{
this.ExtractFiles();
}
@@ -44,7 +44,7 @@
{
get
{
if (_lines == null)
if (this._lines == null)
{
this.ExtractLines();
}
@@ -57,7 +57,7 @@
{
get
{
if (_modules == null)
if (this._modules == null)
{
this.ExtractModules();
}
@@ -70,7 +70,7 @@
{
get
{
if (_segments == null)
if (this._segments == null)
{
this.ExtractSegments();
}
@@ -83,7 +83,7 @@
{
get
{
if (_spans == null)
if (this._spans == null)
{
this.ExtractSpans();
}
@@ -96,7 +96,7 @@
{
get
{
if (_scopes == null)
if (this._scopes == null)
{
this.ExtractScopes();
}
@@ -109,7 +109,7 @@
{
get
{
if (_symbols == null)
if (this._symbols == null)
{
this.ExtractSymbols();
}
@@ -122,7 +122,7 @@
{
get
{
if (_types == null)
if (this._types == null)
{
this.ExtractTypes();
}
@@ -440,11 +440,20 @@
if (key is "version")
{
if (this._version != null)
{
throw new InvalidOperationException("Verson object has already been parsed");
}
this._version = new(this);
this._version.Parse(BuildDictionary(parts));
this.VerifyVersion();
}
else if (key is "info")
{
if (this._information != null)
{
throw new InvalidOperationException("Information object has already been parsed");
}
this._information = new(this);
this._information.Parse(BuildDictionary(parts));
}
@@ -502,7 +511,24 @@
return dictionary;
}
#endregion
private void VerifyVersion()
{
if (this._version == null)
{
throw new InvalidOperationException("Version has not yet been parsed");
}
var major = this._version?.Major;
var minor = this._version?.Minor;
var valid = major == 2 && minor == 0;
if (!valid)
{
throw new InvalidOperationException($"Unknown symbol file version: {major}.{minor}");
}
}
#endregion
}
}
}

View File

@@ -15,6 +15,7 @@
public HashSet<string> HexIntegerKeys { get; } = [];
public HashSet<string> LongKeys { get; } = [];
public HashSet<string> HexLongKeys { get; } = [];
public HashSet<string> DateTimeKeys { get; } = [];
public HashSet<string> MultipleKeys { get; } = [];
public ReflectedSectionProperties(System.Type type)
@@ -83,6 +84,12 @@
Debug.Assert(added, $"<{key}> already has an entry");
}
public void AddDateTimeKey(string key)
{
var added = this.DateTimeKeys.Add(key);
Debug.Assert(added, $"<{key}> already has an entry");
}
private void ProcessSectionPropertyAttribute(System.Type originalType, SectionPropertyAttribute attribute)
{
var key = attribute.Key;
@@ -135,6 +142,10 @@
this.AddLongKey(key);
}
}
else if (type == typeof(DateTime) || type == typeof(Nullable<DateTime>))
{
this.AddDateTimeKey(key);
}
else
{
throw new NotImplementedException($"Property type <{type}> has not been implemented");

View File

@@ -7,7 +7,7 @@
//scope id = 0, name = "", mod = 0, size = 1137, span = 355 + 354
//scope id = 1, name = "stack", mod = 0, type = scope, size = 7, parent = 0, span = 15
//scope id = 7, name = "print_box_break_vertical", mod = 0, type = scope, size = 6, parent = 0, sym = 33, span = 72
public class Scope(Parser container) : NamedSection(container)
public sealed class Scope(Parser container) : NamedSection(container)
{
[SectionReference("mod")]
public Symbols.Module Module => this.TakeModuleReference();

View File

@@ -12,12 +12,14 @@
public class Section
{
protected static readonly Dictionary<System.Type, ReflectedSectionProperties> _sectionPropertiesCache = [];
protected static readonly DateTime _unixEpoch = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
protected readonly Parser _container;
protected readonly Dictionary<string, string> _strings = [];
protected readonly Dictionary<string, int> _integers = [];
protected readonly Dictionary<string, long> _longs = [];
protected readonly Dictionary<string, DateTime> _dateTimes = [];
protected readonly Dictionary<string, List<int>> _multiples = [];
protected ReflectedSectionProperties SectionProperties
@@ -80,6 +82,10 @@
{
this._longs.Add(key, ExtractHexLong(value));
}
else if (this.SectionProperties.DateTimeKeys.Contains(key))
{
this._dateTimes.Add(key, ExtractDateTime(value));
}
else if (this.SectionProperties.MultipleKeys.Contains(key))
{
this._multiples.Add(key, ExtractCompoundInteger(value));
@@ -92,11 +98,13 @@
protected int? MaybeTakeInteger(string key) => this._integers.TryGetValue(key, out var value) ? value : null;
protected long? MaybeTakeLong(string key) => this._longs.TryGetValue(key, out var value) ? value : null;
protected DateTime? MaybeTakeDateTime(string key) => this._dateTimes.TryGetValue(key, out var value) ? value : null;
protected string? MaybeTakeString(string key) => this._strings.TryGetValue(key, out var value) ? value : null;
protected List<int>? MaybeTakeMultiple(string key) => this._multiples.TryGetValue(key, out var value) ? value : null;
protected int TakeInteger(string key) => this.MaybeTakeInteger(key) ?? throw new ArgumentOutOfRangeException(nameof(key), key, "Missing integer entry in section");
protected long TakeLong(string key) => this.MaybeTakeLong(key) ?? throw new ArgumentOutOfRangeException(nameof(key), key, "Missing long integer entry in section");
protected DateTime TakeDateTime(string key) => this.MaybeTakeDateTime(key) ?? throw new ArgumentOutOfRangeException(nameof(key), key, "Missing DateTime entry in section");
protected string TakeString(string key) => this.MaybeTakeString(key) ?? throw new ArgumentOutOfRangeException(nameof(key), key, "Missing string entry in section");
protected List<int> TakeMultiple(string key) => this.MaybeTakeMultiple(key) ?? throw new ArgumentOutOfRangeException(nameof(key), key, "Missing multiple entry in section");
@@ -110,6 +118,7 @@
protected static long ExtractHexLong(string value) => ExtractHexValue<long>(value);
protected static int ExtractInteger(string value) => ExtractNumericValue<int>(value);
protected static long ExtractLong(string value) => ExtractNumericValue<long>(value);
protected static DateTime ExtractDateTime(string value) => _unixEpoch.AddSeconds(ExtractHexLong(value));
protected static string[] ExtractCompoundString(string value) => value.Split('+');
protected static List<int> ExtractCompoundInteger(string value)

View File

@@ -5,7 +5,7 @@
namespace Symbols
{
[AttributeUsage(AttributeTargets.Property)]
internal class SectionEnumerationAttribute(string key) : SectionPropertyAttribute(key, enumeration: true)
internal sealed class SectionEnumerationAttribute(string key) : SectionPropertyAttribute(key, enumeration: true)
{
}
}

View File

@@ -5,7 +5,7 @@
namespace Symbols
{
[AttributeUsage(AttributeTargets.Property)]
internal class SectionReferenceAttribute(string key) : SectionPropertyAttribute(key, type: typeof(int))
internal sealed class SectionReferenceAttribute(string key) : SectionPropertyAttribute(key, type: typeof(int))
{
}
}

View File

@@ -5,7 +5,7 @@
namespace Symbols
{
[AttributeUsage(AttributeTargets.Property)]
internal class SectionReferencesAttribute(string key) : SectionPropertyAttribute(key, many: true)
internal sealed class SectionReferencesAttribute(string key) : SectionPropertyAttribute(key, many: true)
{
}
}

View File

@@ -5,7 +5,7 @@
namespace Symbols
{
// seg id=1,name="RODATA",start=0x00F471,size=0x0000,addrsize=absolute,type=ro,oname="sudoku.65b",ooffs=1137
public class Segment(Parser container) : NamedSection(container)
public sealed class Segment(Parser container) : NamedSection(container)
{
[SectionProperty("start", hexadecimal: true)]
public int Start => this.TakeInteger("start");

View File

@@ -5,7 +5,7 @@
namespace Symbols
{
//span id = 351, seg = 7, start = 0, size = 2, type = 2
public class Span(Parser container) : IdentifiableSection(container)
public sealed class Span(Parser container) : IdentifiableSection(container)
{
[SectionReference("seg")]
public Symbols.Segment Segment => this.TakeSegmentReference();

View File

@@ -7,7 +7,7 @@
using System.Collections.Generic;
// sym id = 16, name = "solve", addrsize = absolute, size = 274, scope = 0, def = 94,ref=144+17+351,val=0xF314,seg=6,type=lab
public class Symbol(Parser container) : NamedSection(container)
public sealed class Symbol(Parser container) : NamedSection(container)
{
[SectionEnumeration("addrsize")]
public string AddressSize => this.TakeString("addrsize");

View File

@@ -5,7 +5,7 @@
namespace Symbols
{
// type id = 0, val = "800920"
public class Type(Parser container) : IdentifiableSection(container)
public sealed class Type(Parser container) : IdentifiableSection(container)
{
[SectionProperty("val")]
public string Value => this.TakeString("val");

View File

@@ -5,7 +5,7 @@
namespace Symbols
{
//version major = 2, minor = 0
public class Version(Parser container) : Section(container)
public sealed class Version(Parser container) : Section(container)
{
[SectionProperty("major")]
public int Major => this.TakeInteger("major");