Class: Ibex::Frontend::SourceCursor

Inherits:
Object
  • Object
show all
Defined in:
lib/ibex/frontend/source_cursor.rb

Overview

Advances through source text while maintaining one-based coordinates.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, file) ⇒ SourceCursor

Returns a new instance of SourceCursor.



51
52
53
54
55
56
57
58
59
60
# File 'lib/ibex/frontend/source_cursor.rb', line 51

def initialize(source, file)
  @source = SourceEncoding.validated_utf8(source, file)
  @file = file.dup.freeze
  @ascii_only = @source.ascii_only?
  @character_length = @ascii_only ? @source.bytesize : @source.length
  @index = 0
  @byte_offset = 0
  @line = 1
  @column = 1
end

Instance Attribute Details

#byte_offsetObject (readonly)

: Integer



46
47
48
# File 'lib/ibex/frontend/source_cursor.rb', line 46

def byte_offset
  @byte_offset
end

#columnObject (readonly)

: Integer



48
49
50
# File 'lib/ibex/frontend/source_cursor.rb', line 48

def column
  @column
end

#fileObject (readonly)

: String



44
45
46
# File 'lib/ibex/frontend/source_cursor.rb', line 44

def file
  @file
end

#indexObject (readonly)

: Integer



45
46
47
# File 'lib/ibex/frontend/source_cursor.rb', line 45

def index
  @index
end

#lineObject (readonly)

: Integer



47
48
49
# File 'lib/ibex/frontend/source_cursor.rb', line 47

def line
  @line
end

#sourceObject (readonly)

: String



43
44
45
# File 'lib/ibex/frontend/source_cursor.rb', line 43

def source
  @source
end

Instance Method Details

#advance(count = 1) ⇒ Object



111
112
113
114
115
# File 'lib/ibex/frontend/source_cursor.rb', line 111

def advance(count = 1)
  return advance_utf8(count) unless @ascii_only

  advance_ascii(count)
end

#eof?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/ibex/frontend/source_cursor.rb', line 63

def eof?
  @index >= @character_length
end

#locationObject



96
97
98
# File 'lib/ibex/frontend/source_cursor.rb', line 96

def location
  Location.new(file: @file, line: @line, column: @column)
end

#peek(offset = 0) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/ibex/frontend/source_cursor.rb', line 68

def peek(offset = 0)
  character_index = @index + offset
  if @ascii_only
    return if character_index >= @character_length

    return @source.byteslice(character_index, 1)
  end

  character_index += @character_length if character_index.negative?
  return if character_index.negative? || character_index >= @character_length

  start_byte = if character_index == @index
                 @byte_offset
               elsif character_index == @index + 1
                 @byte_offset + utf8_character_width(@byte_offset)
               else
                 byte_offset_for_character(character_index)
               end
  @source.byteslice(start_byte, utf8_character_width(start_byte))
end

#positionObject



101
102
103
# File 'lib/ibex/frontend/source_cursor.rb', line 101

def position
  SourcePosition.new(byte_offset: @byte_offset, line: @line, column: @column)
end

#restObject



90
91
92
93
# File 'lib/ibex/frontend/source_cursor.rb', line 90

def rest
  @source.byteslice(@byte_offset, @source.bytesize - @byte_offset) ||
    String.new(encoding: Encoding::UTF_8)
end

#span_from(start) ⇒ Object



106
107
108
# File 'lib/ibex/frontend/source_cursor.rb', line 106

def span_from(start)
  SourceSpan.new(file: @file, start: start, finish: position)
end