Class: Ibex::Runtime::LexerInput
- Inherits:
-
Object
- Object
- Ibex::Runtime::LexerInput
- Defined in:
- lib/ibex/runtime/lexer_input.rb,
sig/ibex/runtime/lexer_input.rbs
Overview
Incremental String, IO, or Fiber input used by generated lexers.
Constant Summary collapse
- DEFAULT_CHUNK_SIZE =
16 * 1024
Instance Attribute Summary collapse
- #buffer ⇒ String readonly
Instance Method Summary collapse
- #append(chunk) ⇒ void
- #consume(prefix) ⇒ void
- #eof? ⇒ Boolean
-
#initialize(source, chunk_size: DEFAULT_CHUNK_SIZE) ⇒ LexerInput
constructor
A new instance of LexerInput.
- #read_chunk ⇒ void
-
#read_more? ⇒ Boolean
Read until at least one byte is added or EOF is observed.
- #resume_fiber(source) ⇒ Object
-
#source_bytes ⇒ String
Return every source byte read so far, including the unconsumed buffer.
-
#source_line(line) ⇒ String
Return one source line, reading ahead only to its line boundary.
Constructor Details
#initialize(source, chunk_size: DEFAULT_CHUNK_SIZE) ⇒ LexerInput
Returns a new instance of LexerInput.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/ibex/runtime/lexer_input.rb', line 13 def initialize(source, chunk_size: DEFAULT_CHUNK_SIZE) raise ArgumentError, "lexer chunk_size must be positive" unless chunk_size.positive? unless source.is_a?(String) || source.respond_to?(:read) || source.is_a?(Fiber) raise ArgumentError, "lexer input must be a String, IO, or Fiber" end @source = source @chunk_size = chunk_size @buffer = +"" @archive = +"" @eof = false return unless source.is_a?(String) append(source) @eof = true end |
Instance Attribute Details
#buffer ⇒ String (readonly)
10 11 12 |
# File 'lib/ibex/runtime/lexer_input.rb', line 10 def buffer @buffer end |
Instance Method Details
#append(chunk) ⇒ void
This method returns an undefined value.
101 102 103 104 |
# File 'lib/ibex/runtime/lexer_input.rb', line 101 def append(chunk) @buffer << chunk @archive << chunk end |
#consume(prefix) ⇒ void
This method returns an undefined value.
46 47 48 49 50 |
# File 'lib/ibex/runtime/lexer_input.rb', line 46 def consume(prefix) raise ArgumentError, "lexer input prefix does not match the buffer" unless @buffer.start_with?(prefix) @buffer.slice!(0, prefix.length) end |
#eof? ⇒ Boolean
31 |
# File 'lib/ibex/runtime/lexer_input.rb', line 31 def eof? = @eof |
#read_chunk ⇒ void
This method returns an undefined value.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/ibex/runtime/lexer_input.rb', line 64 def read_chunk source = @source chunk = if source.is_a?(Fiber) resume_fiber(source) elsif source.respond_to?(:read) source.read(@chunk_size) end if chunk.nil? || chunk == "" @eof = true return end raise TypeError, "lexer input chunks must be Strings" unless chunk.is_a?(String) text = chunk #: String append(text) end |
#read_more? ⇒ Boolean
Read until at least one byte is added or EOF is observed.
39 40 41 42 43 |
# File 'lib/ibex/runtime/lexer_input.rb', line 39 def read_more? before = @buffer.bytesize read_chunk until @eof || @buffer.bytesize > before @buffer.bytesize > before end |
#resume_fiber(source) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/ibex/runtime/lexer_input.rb', line 82 def resume_fiber(source) supports_alive = source.respond_to?(:alive?) if supports_alive && !source.alive? @eof = true return end value = source.resume @eof = true if supports_alive && !source.alive? value rescue FiberError => e terminated = /\A(?:dead fiber called|attempt to resume a terminated fiber)\z/.match?(e.) raise unless !supports_alive && terminated @eof = true nil end |
#source_bytes ⇒ String
Return every source byte read so far, including the unconsumed buffer.
35 |
# File 'lib/ibex/runtime/lexer_input.rb', line 35 def source_bytes = @archive.dup |
#source_line(line) ⇒ String
Return one source line, reading ahead only to its line boundary.
54 55 56 57 58 59 |
# File 'lib/ibex/runtime/lexer_input.rb', line 54 def source_line(line) raise ArgumentError, "source line must be positive" unless line.positive? read_more? while !@eof && @archive.count("\n") < line (@archive.lines[line - 1] || "").delete_suffix("\n").delete_suffix("\r") end |