Class: CSVPlusPlus::Language::Compiler
- Inherits:
-
Object
- Object
- CSVPlusPlus::Language::Compiler
- Defined in:
- lib/csv_plus_plus/language/compiler.rb
Overview
Encapsulates the parsing and building of objects (Template -> Row -> Cell). Variable resolution is delegated to the Scope rubocop:disable Metrics/ClassLength
Instance Attribute Summary collapse
-
#benchmark ⇒ Object
readonly
Returns the value of attribute benchmark.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#runtime ⇒ Object
readonly
Returns the value of attribute runtime.
-
#scope ⇒ Object
readonly
Returns the value of attribute scope.
-
#timings ⇒ Object
readonly
Returns the value of attribute timings.
Class Method Summary collapse
-
.compiler_with_timings(options:, runtime:, &block) ⇒ Object
Create a compiler that can time each of it’s stages.
-
.with_compiler(input:, filename:, options:, &block) ⇒ Object
Create a compiler and make sure it gets cleaned up.
Instance Method Summary collapse
-
#initialize(runtime:, options:, scope: nil, benchmark: nil) ⇒ Compiler
constructor
initialize.
-
#outputting!(&block) ⇒ Object
workflow when writing results.
-
#parse_code_section! ⇒ Object
parses the input file and returns a
CodeSection. -
#parse_csv_section! ⇒ Object
workflow when parsing csv.
-
#parse_row(csv_row) ⇒ Object
Using the current @runtime and the given
csv_rowparse it into aRowof Cellscsv_rowshould have already been run through a CSV parser and is an array of strings. -
#parse_template ⇒ Object
Parse an entire template and return a
::CSVPlusPlus::Templateinstance. -
#resolve_all_cells!(template) ⇒ Object
workflow when resolving the values of all cells.
-
#to_s ⇒ Object
to_s.
Constructor Details
#initialize(runtime:, options:, scope: nil, benchmark: nil) ⇒ Compiler
initialize
49 50 51 52 53 54 55 |
# File 'lib/csv_plus_plus/language/compiler.rb', line 49 def initialize(runtime:, options:, scope: nil, benchmark: nil) @options = @runtime = runtime @scope = scope || ::CSVPlusPlus::Language::Scope.new(runtime:) @benchmark = benchmark @timings = [] if benchmark end |
Instance Attribute Details
#benchmark ⇒ Object (readonly)
Returns the value of attribute benchmark.
22 23 24 |
# File 'lib/csv_plus_plus/language/compiler.rb', line 22 def benchmark @benchmark end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
22 23 24 |
# File 'lib/csv_plus_plus/language/compiler.rb', line 22 def @options end |
#runtime ⇒ Object (readonly)
Returns the value of attribute runtime.
22 23 24 |
# File 'lib/csv_plus_plus/language/compiler.rb', line 22 def runtime @runtime end |
#scope ⇒ Object (readonly)
Returns the value of attribute scope.
22 23 24 |
# File 'lib/csv_plus_plus/language/compiler.rb', line 22 def scope @scope end |
#timings ⇒ Object (readonly)
Returns the value of attribute timings.
22 23 24 |
# File 'lib/csv_plus_plus/language/compiler.rb', line 22 def timings @timings end |
Class Method Details
.compiler_with_timings(options:, runtime:, &block) ⇒ Object
Create a compiler that can time each of it’s stages
40 41 42 43 44 45 46 |
# File 'lib/csv_plus_plus/language/compiler.rb', line 40 def self.compiler_with_timings(options:, runtime:, &block) ::Benchmark.benchmark(::Benchmark::CAPTION, 25, ::Benchmark::FORMAT, '> Total') do |x| compiler = new(options:, runtime:, benchmark: x) block.call(compiler) [compiler.timings.reduce(:+)] end end |
.with_compiler(input:, filename:, options:, &block) ⇒ Object
Create a compiler and make sure it gets cleaned up
25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/csv_plus_plus/language/compiler.rb', line 25 def self.with_compiler(input:, filename:, options:, &block) runtime = ::CSVPlusPlus::Language::Runtime.new(filename:, input:) if .verbose compiler_with_timings(runtime:, options:) do |c| block.call(c) end else yield(new(runtime:, options:)) end ensure runtime.cleanup! end |
Instance Method Details
#outputting!(&block) ⇒ Object
workflow when writing results
124 125 126 127 128 |
# File 'lib/csv_plus_plus/language/compiler.rb', line 124 def outputting!(&block) workflow(stage: 'Writing the spreadsheet') do block.call end end |
#parse_code_section! ⇒ Object
parses the input file and returns a CodeSection
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/csv_plus_plus/language/compiler.rb', line 70 def parse_code_section! parsing_code_section do |input| code_section, csv_section = ::CSVPlusPlus::Language::CodeSectionParser.new.parse(input, self) # TODO: infer a type # allow user-supplied key/values to override anything global or from the code section code_section.def_variables( .key_values.transform_values { |v| ::CSVPlusPlus::Language::Entities::String.new(v.to_s) } ) @scope.code_section = code_section # return the csv_section to the caller because they're gonna re-write input with it next csv_section end @scope.code_section end |
#parse_csv_section! ⇒ Object
workflow when parsing csv
87 88 89 90 91 92 93 94 95 96 |
# File 'lib/csv_plus_plus/language/compiler.rb', line 87 def parse_csv_section! workflow(stage: 'Parsing CSV section') do @runtime.map_rows(::CSV.new(runtime.input)) do |csv_row| parse_row(csv_row) end end ensure # we're done with the file and everything is in memory @runtime.cleanup! end |
#parse_row(csv_row) ⇒ Object
Using the current @runtime and the given csv_row parse it into a Row of Cells csv_row should have already been run through a CSV parser and is an array of strings
100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/csv_plus_plus/language/compiler.rb', line 100 def parse_row(csv_row) row_modifier = ::CSVPlusPlus::Modifier.new(row_level: true) cells = @runtime.map_row(csv_row) do |value, _cell_index| cell_modifier = ::CSVPlusPlus::Modifier.new parsed_value = ::CSVPlusPlus::ModifierParser.new(row_modifier:, cell_modifier:).parse(value, @runtime) ::CSVPlusPlus::Cell.parse(parsed_value, runtime:, modifier: cell_modifier) end ::CSVPlusPlus::Row.new(@runtime.row_index, cells, row_modifier) end |
#parse_template ⇒ Object
Parse an entire template and return a ::CSVPlusPlus::Template instance
58 59 60 61 62 63 64 65 66 67 |
# File 'lib/csv_plus_plus/language/compiler.rb', line 58 def parse_template parse_code_section! rows = parse_csv_section! ::CSVPlusPlus::Template.new(rows:, scope: @scope).tap do |t| t.(@runtime) { t. } resolve_all_cells!(t) end end |
#resolve_all_cells!(template) ⇒ Object
workflow when resolving the values of all cells
115 116 117 118 119 120 121 |
# File 'lib/csv_plus_plus/language/compiler.rb', line 115 def resolve_all_cells!(template) workflow(stage: 'Resolving each cell') do @runtime.map_rows(template.rows, cells_too: true) do |cell| cell.ast = @scope.resolve_cell_value if cell.ast end end end |
#to_s ⇒ Object
to_s
131 132 133 |
# File 'lib/csv_plus_plus/language/compiler.rb', line 131 def to_s "Compiler(options: #{@options}, runtime: #{@runtime}, scope: #{@scope})" end |