Class: Parslet::Source::LineCache
- Inherits:
-
Object
- Object
- Parslet::Source::LineCache
- Defined in:
- lib/parslet/source/line_cache.rb
Overview
A cache for line start positions.
Instance Method Summary collapse
-
#initialize ⇒ LineCache
constructor
A new instance of LineCache.
-
#line_and_column(pos) ⇒ Object
Returns a <line, column> tuple for the given input position.
- #scan_for_line_endings(start_pos, buf) ⇒ Object
Constructor Details
#initialize ⇒ LineCache
Returns a new instance of LineCache.
7 8 9 10 11 12 13 |
# File 'lib/parslet/source/line_cache.rb', line 7 def initialize # Stores line endings as a simple position number. The first line always # starts at 0; numbers beyond the biggest entry are on any line > size, # but probably make a scan to that position neccessary. @line_ends = [] @line_ends.extend RangeSearch end |
Instance Method Details
#line_and_column(pos) ⇒ Object
Returns a <line, column> tuple for the given input position.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/parslet/source/line_cache.rb', line 17 def line_and_column(pos) eol_idx = @line_ends.lbound(pos) if eol_idx # eol_idx points to the offset that ends the current line. # Let's try to find the offset that starts it: offset = eol_idx>0 && @line_ends[eol_idx-1] || 0 return [eol_idx+1, pos-offset+1] else # eol_idx is nil, that means that we're beyond the last line end that # we know about. Pretend for now that we're just on the last line. offset = @line_ends.last || 0 return [@line_ends.size+1, pos-offset+1] end end |
#scan_for_line_endings(start_pos, buf) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/parslet/source/line_cache.rb', line 33 def scan_for_line_endings(start_pos, buf) return unless buf return unless buf.index("\n") cur = -1 # If we have already read part or all of buf, we already know about # line ends in that portion. remove it and correct cur (search index) if @last_line_end && start_pos < @last_line_end # Let's not search the range from start_pos to last_line_end again. cur = @last_line_end - start_pos -1 end # Scan the string for line endings; store the positions of all endings # in @line_ends. while buf && cur = buf.index("\n", cur+1) @last_line_end = (start_pos + cur+1) @line_ends << @last_line_end end end |