Class: Parsby::PosRange

Inherits:
Object
  • Object
show all
Defined in:
lib/parsby.rb

Direct Known Subclasses

ParsedRange

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pos_start, pos_end) ⇒ PosRange

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.



18
19
20
21
# File 'lib/parsby.rb', line 18

def initialize(pos_start, pos_end)
  @start = pos_start
  @end = pos_end
end

Instance Attribute Details

#endObject

Returns the value of attribute end.



11
12
13
# File 'lib/parsby.rb', line 11

def end
  @end
end

#startObject

Returns the value of attribute start.



11
12
13
# File 'lib/parsby.rb', line 11

def start
  @start
end

Instance Method Details

#&(range) ⇒ Object

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



35
36
37
38
# File 'lib/parsby.rb', line 35

def &(range)
  return nil unless overlaps?(range) || touching?(range)
  PosRange.new [@start, range.start].max, [@end, range.end].min
end

#completely_inside_of?(range) ⇒ Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/parsby.rb', line 72

def completely_inside_of?(range)
  starts_inside_of?(range) && ends_inside_of?(range)
end

#completely_left_of?(range) ⇒ Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/parsby.rb', line 52

def completely_left_of?(range)
  @end <= range.start
end

#completely_right_of?(range) ⇒ Boolean

Returns:

  • (Boolean)


56
57
58
# File 'lib/parsby.rb', line 56

def completely_right_of?(range)
  range.end <= @start
end

#contains?(pos) ⇒ Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/parsby.rb', line 60

def contains?(pos)
  @start <= pos && pos < @end
end

#ends_inside_of?(range) ⇒ Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/parsby.rb', line 68

def ends_inside_of?(range)
  range.contains?(@end) || range.end == @end
end

#lengthObject

Length of range.



24
25
26
# File 'lib/parsby.rb', line 24

def length
  @end - @start
end

#length_in(range) ⇒ Object

Length of overlap. 0 for non-overlapping ranges.



29
30
31
# File 'lib/parsby.rb', line 29

def length_in(range)
  (self & range)&.length || 0
end

#overlaps?(range) ⇒ Boolean

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.

Returns:

  • (Boolean)


48
49
50
# File 'lib/parsby.rb', line 48

def overlaps?(range)
  !(completely_left_of?(range) || completely_right_of?(range))
end

#render_in(line_range) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
# File 'lib/parsby.rb', line 76

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) ⇒ Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/parsby.rb', line 64

def starts_inside_of?(range)
  range.contains? @start
end

#touching?(range) ⇒ Boolean

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

Returns:

  • (Boolean)


41
42
43
# File 'lib/parsby.rb', line 41

def touching?(range)
  range.end == self.start || self.end == range.start
end