Class: CSVPlusPlus::Runtime
- Inherits:
-
Object
- Object
- CSVPlusPlus::Runtime
- Defined in:
- lib/csv_plus_plus/runtime.rb
Overview
The runtime state of the compiler (the current line_number/row_index, cell being processed, etc) for parsing a given file. We take multiple runs through the input file for parsing so it’s really convenient to have a central place for these things to be managed.
Instance Attribute Summary collapse
-
#cell ⇒ Cell
The current cell being processed.
-
#cell_index ⇒ Integer
The index of the current cell being processed (starts at 0).
-
#filename ⇒ String?
readonly
The filename that the input came from (mostly used for debugging since
filenamecan benilif it’s read from stdin.. -
#length_of_code_section ⇒ Integer
readonly
The length (count of lines) of the code section part of the original input.
-
#length_of_csv_section ⇒ Integer
readonly
The length (count of lines) of the CSV part of the original csvpp input.
-
#length_of_original_file ⇒ Integer
readonly
The length (count of lines) of the original csvpp input.
-
#line_number ⇒ Integer
The line number of the original csvpp template (starts at 1).
-
#row_index ⇒ Integer
The index of the current row being processed (starts at 0).
Instance Method Summary collapse
-
#cleanup! ⇒ Object
Clean up the Tempfile we’re using for parsing.
-
#initialize(input:, filename:) ⇒ Runtime
constructor
A new instance of Runtime.
-
#input ⇒ String
The currently available input for parsing.
-
#map_lines(lines, &block) ⇒ Array
Map over an a csvpp file and keep track of line_number and row_index.
-
#map_row(row, &block) ⇒ Array
Map over a single row and keep track of the cell and it’s index.
-
#map_rows(rows, cells_too: false, &block) ⇒ Array
Map over all rows and keep track of row and line numbers.
-
#next_line! ⇒ Integer
Increment state to the next line.
-
#raise_formula_syntax_error(message, bad_input, wrapped_error: nil) ⇒ Object
Called when an error is encoutered during parsing.
-
#rewrite_input!(data) ⇒ Object
We mutate the input over and over.
-
#rownum ⇒ Integer?
Return the current spreadsheet row number.
-
#runtime_value(var_id) ⇒ Entity
Get the current (entity) value of a runtime value.
-
#runtime_variable?(var_id) ⇒ boolean
Is
var_ida runtime variable? (it’s a static variable otherwise). -
#set_cell!(cell, cell_index) ⇒ Object
Set the current cell and index.
-
#start! ⇒ Object
Each time we run a parse on the input, reset the runtime state starting at the beginning of the file.
-
#start_at_csv! ⇒ Object
Reset the runtime state starting at the CSV section.
- #to_s ⇒ String
Constructor Details
#initialize(input:, filename:) ⇒ Runtime
Returns a new instance of Runtime.
28 29 30 31 32 33 |
# File 'lib/csv_plus_plus/runtime.rb', line 28 def initialize(input:, filename:) @filename = filename || 'stdin' init_input!(input) start! end |
Instance Attribute Details
#cell ⇒ Cell
The current cell being processed
20 21 22 |
# File 'lib/csv_plus_plus/runtime.rb', line 20 def cell @cell end |
#cell_index ⇒ Integer
The index of the current cell being processed (starts at 0)
20 21 22 |
# File 'lib/csv_plus_plus/runtime.rb', line 20 def cell_index @cell_index end |
#filename ⇒ String? (readonly)
The filename that the input came from (mostly used for debugging since filename can be nil if it’s read from stdin.
20 21 22 |
# File 'lib/csv_plus_plus/runtime.rb', line 20 def filename @filename end |
#length_of_code_section ⇒ Integer (readonly)
The length (count of lines) of the code section part of the original input.
20 21 22 |
# File 'lib/csv_plus_plus/runtime.rb', line 20 def length_of_code_section @length_of_code_section end |
#length_of_csv_section ⇒ Integer (readonly)
The length (count of lines) of the CSV part of the original csvpp input.
20 21 22 |
# File 'lib/csv_plus_plus/runtime.rb', line 20 def length_of_csv_section @length_of_csv_section end |
#length_of_original_file ⇒ Integer (readonly)
The length (count of lines) of the original csvpp input.
20 21 22 |
# File 'lib/csv_plus_plus/runtime.rb', line 20 def length_of_original_file @length_of_original_file end |
#line_number ⇒ Integer
The line number of the original csvpp template (starts at 1)
20 21 22 |
# File 'lib/csv_plus_plus/runtime.rb', line 20 def line_number @line_number end |
#row_index ⇒ Integer
The index of the current row being processed (starts at 0)
20 21 22 |
# File 'lib/csv_plus_plus/runtime.rb', line 20 def row_index @row_index end |
Instance Method Details
#cleanup! ⇒ Object
Clean up the Tempfile we’re using for parsing
172 173 174 175 176 177 178 |
# File 'lib/csv_plus_plus/runtime.rb', line 172 def cleanup! return unless @tmp @tmp.close @tmp.unlink @tmp = nil end |
#input ⇒ String
The currently available input for parsing. The tmp state will be re-written between parsing the code section and the CSV section
158 159 160 |
# File 'lib/csv_plus_plus/runtime.rb', line 158 def input @tmp end |
#map_lines(lines, &block) ⇒ Array
Map over an a csvpp file and keep track of line_number and row_index
40 41 42 43 44 45 |
# File 'lib/csv_plus_plus/runtime.rb', line 40 def map_lines(lines, &block) @line_number = 1 lines.map do |line| block.call(line).tap { next_line! } end end |
#map_row(row, &block) ⇒ Array
Map over a single row and keep track of the cell and it’s index
52 53 54 55 56 57 58 |
# File 'lib/csv_plus_plus/runtime.rb', line 52 def map_row(row, &block) @cell_index = 0 row.map.with_index do |cell, index| set_cell!(cell, index) block.call(cell, index) end end |
#map_rows(rows, cells_too: false, &block) ⇒ Array
Map over all rows and keep track of row and line numbers
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/csv_plus_plus/runtime.rb', line 66 def map_rows(rows, cells_too: false, &block) @row_index = 0 map_lines(rows) do |row| if cells_too # it's either CSV or a Row object map_row((row.is_a?(::CSVPlusPlus::Row) ? row.cells : row), &block) else block.call(row) end end end |
#next_line! ⇒ Integer
Increment state to the next line
81 82 83 84 |
# File 'lib/csv_plus_plus/runtime.rb', line 81 def next_line! @row_index += 1 unless @row_index.nil? @line_number += 1 end |
#raise_formula_syntax_error(message, bad_input, wrapped_error: nil) ⇒ Object
Called when an error is encoutered during parsing. It will construct a useful error with the current @row/@cell_index, @line_number and @filename
150 151 152 |
# File 'lib/csv_plus_plus/runtime.rb', line 150 def raise_formula_syntax_error(, bad_input, wrapped_error: nil) raise(::CSVPlusPlus::Error::FormulaSyntaxError.new(, bad_input, self, wrapped_error:)) end |
#rewrite_input!(data) ⇒ Object
We mutate the input over and over. It’s ok because it’s just a Tempfile
165 166 167 168 169 |
# File 'lib/csv_plus_plus/runtime.rb', line 165 def rewrite_input!(data) @tmp.truncate(0) @tmp.write(data) @tmp.rewind end |
#rownum ⇒ Integer?
Return the current spreadsheet row number. It parallels @row_index but starts at 1.
89 90 91 92 93 |
# File 'lib/csv_plus_plus/runtime.rb', line 89 def rownum return if @row_index.nil? @row_index + 1 end |
#runtime_value(var_id) ⇒ Entity
Get the current (entity) value of a runtime value
127 128 129 130 131 132 133 |
# File 'lib/csv_plus_plus/runtime.rb', line 127 def runtime_value(var_id) if runtime_variable?(var_id) ::CSVPlusPlus::Entities::Builtins::VARIABLES[var_id.to_sym].resolve_fn.call(self) else raise_formula_syntax_error('Undefined variable', var_id) end end |
#runtime_variable?(var_id) ⇒ boolean
Is var_id a runtime variable? (it’s a static variable otherwise)
140 141 142 |
# File 'lib/csv_plus_plus/runtime.rb', line 140 def runtime_variable?(var_id) ::CSVPlusPlus::Entities::Builtins::VARIABLES.key?(var_id.to_sym) end |
#set_cell!(cell, cell_index) ⇒ Object
Set the current cell and index
99 100 101 102 |
# File 'lib/csv_plus_plus/runtime.rb', line 99 def set_cell!(cell, cell_index) @cell = cell @cell_index = cell_index end |
#start! ⇒ Object
Each time we run a parse on the input, reset the runtime state starting at the beginning of the file
105 106 107 108 |
# File 'lib/csv_plus_plus/runtime.rb', line 105 def start! @row_index = @cell_index = nil @line_number = 1 end |
#start_at_csv! ⇒ Object
Reset the runtime state starting at the CSV section
111 112 113 114 115 |
# File 'lib/csv_plus_plus/runtime.rb', line 111 def start_at_csv! # TODO: isn't the input re-written anyway without the code section? why do we need this? start! @line_number = @length_of_code_section || 1 end |
#to_s ⇒ String
118 119 120 |
# File 'lib/csv_plus_plus/runtime.rb', line 118 def to_s "Runtime(cell: #{@cell}, row_index: #{@row_index}, cell_index: #{@cell_index})" end |