diff --git a/src/Draco.Compiler/Internal/FlowAnalysis/Domain/IntegralDomain.cs b/src/Draco.Compiler/Internal/FlowAnalysis/Domain/IntegralDomain.cs index bf3725bc1..54fa6dbc9 100644 --- a/src/Draco.Compiler/Internal/FlowAnalysis/Domain/IntegralDomain.cs +++ b/src/Draco.Compiler/Internal/FlowAnalysis/Domain/IntegralDomain.cs @@ -24,6 +24,13 @@ internal sealed class IntegralDomain : ValueDomain IAdditiveIdentity, IMultiplicativeIdentity { + /// + /// A continuous interval of integral values. + /// + /// The lower bound (inclusive). + /// The upper bound (inclusive). + private readonly record struct Interval(TInteger From, TInteger To); + public override bool IsEmpty => this.subtracted.Count == 1 && this.subtracted[0].From == this.minValue @@ -32,14 +39,13 @@ internal sealed class IntegralDomain : ValueDomain private readonly TypeSymbol backingType; private readonly TInteger minValue; private readonly TInteger maxValue; - // inclusive - inclusive - private readonly List<(TInteger From, TInteger To)> subtracted; + private readonly List subtracted; private IntegralDomain( TypeSymbol backingType, TInteger minValue, TInteger maxValue, - List<(TInteger From, TInteger To)> subtracted) + List subtracted) { this.backingType = backingType; this.minValue = minValue; @@ -83,26 +89,13 @@ public override void SubtractPattern(BoundPattern pattern) // Special case: entire domain covered if (this.IsEmpty) return null; - // Search to the closest zero - var span = (ReadOnlySpan<(TInteger From, TInteger To)>)CollectionsMarshal.AsSpan(this.subtracted); - var (index, found) = BinarySearch.Search(span, TInteger.AdditiveIdentity, i => i.From); - - // TODO: Not correct - // If not found, we can just return the identity - if (!found) return TInteger.AdditiveIdentity; - - // Otherwise, we need to return one of the endpoints - if (span[index].To == this.maxValue) - { - // Edge, return the one below - return span[index].From - TInteger.MultiplicativeIdentity; - } - return span[index].To + TInteger.MultiplicativeIdentity; + // TODO + throw new NotImplementedException(); } public override string ToString() { - if (this.IsEmpty) return "empty"; + if (this.IsEmpty) return $"[{this.minValue}; {this.maxValue}]"; var parts = new List(); if (this.subtracted[0].From != this.minValue) parts.Add($"[{this.minValue}; {this.subtracted[0].From})"); @@ -116,30 +109,15 @@ public override string ToString() private void SubtractRange(TInteger from, TInteger to) { - var span = (ReadOnlySpan<(TInteger From, TInteger To)>)CollectionsMarshal.AsSpan(this.subtracted); + if (from > to) throw new ArgumentOutOfRangeException(nameof(to), "from must be less than or equal to to"); - var (startIndex, startMatch) = BinarySearch.Search(span, from, i => i.To); - var (endIndex, endMatch) = BinarySearch.Search(span, to, i => i.From); - - // TODO: NOT CORRECT - // Merge sides - if (startIndex > 0 && span[startIndex - 1].To + TInteger.MultiplicativeIdentity == from) - { - --startIndex; - from = span[startIndex].From; - } - // TODO: NOT CORRECT - if (endIndex < span.Length - 1 && span[endIndex + 1].From == to + TInteger.MultiplicativeIdentity) - { - ++endIndex; - to = span[endIndex].To; - } + var span = (ReadOnlySpan)CollectionsMarshal.AsSpan(this.subtracted); - // Remove overlapping - this.subtracted.RemoveRange(startIndex, endIndex - startIndex); + var (startIndex, startMatch) = BinarySearch.Search(span, from, i => i.From); + var (endIndex, endMatch) = BinarySearch.Search(span, to, i => i.To); - // Insert new range - this.subtracted.Insert(startIndex, (from, to)); + // TODO + throw new NotImplementedException(); } private BoundPattern ToPattern(TInteger integer) =>