mirror of
https://github.com/MoleskiCoder/EightBitNet.git
synced 2026-01-22 16:16:17 +00:00
More symbols improvements
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user