namespace EightBit { namespace Files { namespace Symbols { using System.Globalization; public class Section { protected Parser? _parent; protected readonly Dictionary _strings = []; protected readonly Dictionary _integers = []; protected readonly Dictionary _longs = []; protected readonly Dictionary> _multiples = []; protected readonly HashSet _string_keys = []; protected readonly HashSet _enumeration_keys = []; protected readonly HashSet _integer_keys = []; protected readonly HashSet _long_keys = []; protected readonly HashSet _hex_integer_keys = []; protected readonly HashSet _hex_long_keys = []; protected readonly HashSet _multiple_keys = []; public virtual void Parse(Parser parent, Dictionary entries) { this._parent = parent; foreach (var entry in entries) { this.Parse(entry); } } private void Parse(KeyValuePair entry) { var key = entry.Key; var value = entry.Value; if (_string_keys.Contains(key)) { this._strings[key] = ExtractString(value); } else if (_enumeration_keys.Contains(key)) { this._strings[key] = ExtractEnumeration(value); } else if (_integer_keys.Contains(key)) { this._integers[key] = ExtractInteger(value); } else if (_hex_integer_keys.Contains(key)) { this._integers[key] = ExtractHexInteger(value); } else if (_long_keys.Contains(key)) { this._longs[key] = ExtractLong(value); } else if (_hex_long_keys.Contains(key)) { this._longs[key] = ExtractHexLong(value); } else if (_multiple_keys.Contains(key)) { this._multiples[key] = ExtractCompoundInteger(value); } else { throw new InvalidOperationException($"Section: {key} has not been categorised"); } } 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 string? MaybeTakeString(string key) => this._strings.TryGetValue(key, out var value) ? value : null; protected List? MaybeTakeMultiple(string key) => this._multiples.TryGetValue(key, out var value) ? value : null; protected int TakeInteger(string key) => this.MaybeTakeInteger(key) ?? throw new InvalidOperationException($"Section is missing an integer entry named {key}"); protected long TakeLong(string key) => this.MaybeTakeLong(key) ?? throw new InvalidOperationException($"Section is missing an long integer entry named {key}"); protected string TakeString(string key) => this.MaybeTakeString(key) ?? throw new InvalidOperationException($"Section is missing a string entry named {key}"); protected List TakeMultiple(string key) => this.MaybeTakeMultiple(key) ?? throw new InvalidOperationException($"Section is missing a multiple entry named {key}"); protected static string ExtractString(string value) => value.Trim('"'); protected static string ExtractEnumeration(string value) => value; protected static int ExtractHexInteger(string value) => int.Parse(value.AsSpan(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture); protected static long ExtractHexLong(string value) => long.Parse(value.AsSpan(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture); protected static int ExtractInteger(string value) => int.Parse(value); protected static long ExtractLong(string value) => long.Parse(value); protected static List ExtractCompoundString(string value) => new(value.Split('+')); protected static List ExtractCompoundInteger(string value) { var returned = new List(); var elements = ExtractCompoundString(value); foreach (var element in elements) { returned.Add(ExtractInteger(element)); } return returned; } } } } }