class Parsby::PosRange

Attributes

end[RW]
start[RW]

Public Class Methods

new(pos_start, pos_end) click to toggle source

PosRanges are constructed with a starting and ending position. We consider the starting position to be inside the range, and the ending position to be outside the range. So, if start is 1 and end is 2, then only position 1 is inside the range. If start is 1 and end is 1, then there is no position inside the range.

# File lib/parsby.rb, line 17
def initialize(pos_start, pos_end)
  @start = pos_start
  @end = pos_end
end

Public Instance Methods

&(range) click to toggle source

Intersection of two ranges. Touching ranges result in a range of length 0.

# File lib/parsby.rb, line 34
def &(range)
  return nil unless overlaps?(range) || touching?(range)
  PosRange.new [@start, range.start].max, [@end, range.end].min
end
completely_inside_of?(range) click to toggle source
# File lib/parsby.rb, line 71
def completely_inside_of?(range)
  starts_inside_of?(range) && ends_inside_of?(range)
end
completely_left_of?(range) click to toggle source
# File lib/parsby.rb, line 51
def completely_left_of?(range)
  @end <= range.start
end
completely_right_of?(range) click to toggle source
# File lib/parsby.rb, line 55
def completely_right_of?(range)
  range.end <= @start
end
contains?(pos) click to toggle source
# File lib/parsby.rb, line 59
def contains?(pos)
  @start <= pos && pos < @end
end
ends_inside_of?(range) click to toggle source
# File lib/parsby.rb, line 67
def ends_inside_of?(range)
  range.contains?(@end) || range.end == @end
end
length() click to toggle source

Length of range.

# File lib/parsby.rb, line 23
def length
  @end - @start
end
length_in(range) click to toggle source

Length of overlap. 0 for non-overlapping ranges.

# File lib/parsby.rb, line 28
def length_in(range)
  (self & range)&.length || 0
end
overlaps?(range) click to toggle source

True when one is not completely left of or right of the other. Touching ranges do not overlap, even though they have an intersection range of length 0.

# File lib/parsby.rb, line 47
def overlaps?(range)
  !(completely_left_of?(range) || completely_right_of?(range))
end
render_in(line_range) click to toggle source
# File lib/parsby.rb, line 75
def render_in(line_range)
  return "<-" if completely_left_of?(line_range) && !starts_inside_of?(line_range)
  return "->" if completely_right_of? line_range
  indentation = " " * [0, start - line_range.start].max
  r = "-" * length_in(line_range)
  r[0] = "\\" if starts_inside_of? line_range
  r[-1] = "/" if ends_inside_of? line_range
  r[0] = "|" if length_in(line_range) == 0
  r[0] = "V" if length_in(line_range) == 1 && completely_inside_of?(line_range)
  indentation + r
end
starts_inside_of?(range) click to toggle source
# File lib/parsby.rb, line 63
def starts_inside_of?(range)
  range.contains? @start
end
touching?(range) click to toggle source

True when the end of one is the beginning of the other.

# File lib/parsby.rb, line 40
def touching?(range)
  range.end == self.start || self.end == range.start
end