This repository has been archived on 2025-10-23. You can view files and clone it, but cannot push or open issues or pull requests.
Files
nub-lang-archive/compiler/NubLang/Code/SourceSpan.cs
2025-09-11 23:03:44 +02:00

68 lines
2.2 KiB
C#

namespace NubLang.Code;
public readonly struct SourceSpan : IEquatable<SourceSpan>, IComparable<SourceSpan>
{
public static SourceSpan Zero => new(SourceLocation.Zero, SourceLocation.Zero);
public static SourceSpan Merge(params IEnumerable<SourceSpan> spans)
{
var spanArray = spans as SourceSpan[] ?? spans.ToArray();
if (spanArray.Length == 0)
{
return Zero;
}
var minStart = spanArray.Min(s => s.Start);
var maxEnd = spanArray.Max(s => s.End);
return new SourceSpan(minStart, maxEnd);
}
public SourceSpan(SourceLocation start, SourceLocation end)
{
if (start > end)
{
throw new ArgumentException("Start location cannot be after end location");
}
Start = start;
End = end;
}
public SourceLocation Start { get; }
public SourceLocation End { get; }
public override string ToString()
{
if (Start == End)
{
return $"{Start}";
}
if (Start.Line == End.Line)
{
return Start.Column == End.Column ? $"{Start}" : $"{Start.Line}:{Start.Column}-{End.Column}";
}
return $"{Start}-{End}";
}
public bool Equals(SourceSpan other) => Start == other.Start && End == other.End;
public override bool Equals(object? obj) => obj is SourceSpan other && Equals(other);
public override int GetHashCode() => HashCode.Combine(typeof(SourceSpan), Start, End);
public static bool operator ==(SourceSpan left, SourceSpan right) => Equals(left, right);
public static bool operator !=(SourceSpan left, SourceSpan right) => !Equals(left, right);
public static bool operator <(SourceSpan left, SourceSpan right) => left.CompareTo(right) < 0;
public static bool operator <=(SourceSpan left, SourceSpan right) => left.CompareTo(right) <= 0;
public static bool operator >(SourceSpan left, SourceSpan right) => left.CompareTo(right) > 0;
public static bool operator >=(SourceSpan left, SourceSpan right) => left.CompareTo(right) >= 0;
public int CompareTo(SourceSpan other)
{
var startComparison = Start.CompareTo(other.Start);
return startComparison != 0 ? startComparison : End.CompareTo(other.End);
}
}