csv_plus_plus 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -1
  3. data/README.md +18 -62
  4. data/lib/csv_plus_plus/benchmarked_compiler.rb +62 -0
  5. data/lib/csv_plus_plus/can_define_references.rb +88 -0
  6. data/lib/csv_plus_plus/can_resolve_references.rb +8 -0
  7. data/lib/csv_plus_plus/cell.rb +3 -3
  8. data/lib/csv_plus_plus/cli.rb +24 -7
  9. data/lib/csv_plus_plus/color.rb +12 -6
  10. data/lib/csv_plus_plus/compiler.rb +156 -0
  11. data/lib/csv_plus_plus/data_validation.rb +138 -0
  12. data/lib/csv_plus_plus/{language → entities}/ast_builder.rb +5 -7
  13. data/lib/csv_plus_plus/entities/boolean.rb +31 -0
  14. data/lib/csv_plus_plus/{language → entities}/builtins.rb +2 -4
  15. data/lib/csv_plus_plus/entities/cell_reference.rb +60 -0
  16. data/lib/csv_plus_plus/entities/date.rb +30 -0
  17. data/lib/csv_plus_plus/entities/entity.rb +84 -0
  18. data/lib/csv_plus_plus/entities/function.rb +33 -0
  19. data/lib/csv_plus_plus/entities/function_call.rb +35 -0
  20. data/lib/csv_plus_plus/entities/number.rb +34 -0
  21. data/lib/csv_plus_plus/entities/runtime_value.rb +26 -0
  22. data/lib/csv_plus_plus/entities/string.rb +29 -0
  23. data/lib/csv_plus_plus/entities/variable.rb +25 -0
  24. data/lib/csv_plus_plus/entities.rb +33 -0
  25. data/lib/csv_plus_plus/error/error.rb +10 -0
  26. data/lib/csv_plus_plus/error/formula_syntax_error.rb +36 -0
  27. data/lib/csv_plus_plus/error/modifier_syntax_error.rb +27 -0
  28. data/lib/csv_plus_plus/error/modifier_validation_error.rb +49 -0
  29. data/lib/csv_plus_plus/{language → error}/syntax_error.rb +6 -14
  30. data/lib/csv_plus_plus/error/writer_error.rb +9 -0
  31. data/lib/csv_plus_plus/error.rb +9 -2
  32. data/lib/csv_plus_plus/expand.rb +3 -1
  33. data/lib/csv_plus_plus/google_api_client.rb +4 -0
  34. data/lib/csv_plus_plus/lexer/lexer.rb +19 -11
  35. data/lib/csv_plus_plus/modifier/conditional_formatting.rb +17 -0
  36. data/lib/csv_plus_plus/modifier.rb +73 -70
  37. data/lib/csv_plus_plus/options.rb +3 -0
  38. data/lib/csv_plus_plus/parser/cell_value.tab.rb +305 -0
  39. data/lib/csv_plus_plus/parser/code_section.tab.rb +410 -0
  40. data/lib/csv_plus_plus/parser/modifier.tab.rb +484 -0
  41. data/lib/csv_plus_plus/references.rb +68 -0
  42. data/lib/csv_plus_plus/row.rb +0 -3
  43. data/lib/csv_plus_plus/runtime.rb +199 -0
  44. data/lib/csv_plus_plus/scope.rb +196 -0
  45. data/lib/csv_plus_plus/template.rb +21 -5
  46. data/lib/csv_plus_plus/validated_modifier.rb +164 -0
  47. data/lib/csv_plus_plus/version.rb +1 -1
  48. data/lib/csv_plus_plus/writer/file_backer_upper.rb +6 -4
  49. data/lib/csv_plus_plus/writer/google_sheet_builder.rb +24 -29
  50. data/lib/csv_plus_plus/writer/google_sheet_modifier.rb +33 -12
  51. data/lib/csv_plus_plus/writer/rubyxl_builder.rb +3 -6
  52. data/lib/csv_plus_plus.rb +41 -16
  53. metadata +34 -24
  54. data/lib/csv_plus_plus/code_section.rb +0 -68
  55. data/lib/csv_plus_plus/language/benchmarked_compiler.rb +0 -65
  56. data/lib/csv_plus_plus/language/cell_value.tab.rb +0 -332
  57. data/lib/csv_plus_plus/language/code_section.tab.rb +0 -442
  58. data/lib/csv_plus_plus/language/compiler.rb +0 -157
  59. data/lib/csv_plus_plus/language/entities/boolean.rb +0 -33
  60. data/lib/csv_plus_plus/language/entities/cell_reference.rb +0 -33
  61. data/lib/csv_plus_plus/language/entities/entity.rb +0 -86
  62. data/lib/csv_plus_plus/language/entities/function.rb +0 -35
  63. data/lib/csv_plus_plus/language/entities/function_call.rb +0 -26
  64. data/lib/csv_plus_plus/language/entities/number.rb +0 -36
  65. data/lib/csv_plus_plus/language/entities/runtime_value.rb +0 -28
  66. data/lib/csv_plus_plus/language/entities/string.rb +0 -31
  67. data/lib/csv_plus_plus/language/entities/variable.rb +0 -25
  68. data/lib/csv_plus_plus/language/entities.rb +0 -28
  69. data/lib/csv_plus_plus/language/references.rb +0 -70
  70. data/lib/csv_plus_plus/language/runtime.rb +0 -205
  71. data/lib/csv_plus_plus/language/scope.rb +0 -188
  72. data/lib/csv_plus_plus/modifier.tab.rb +0 -907
@@ -25,12 +25,6 @@ module CSVPlusPlus
25
25
 
26
26
  private
27
27
 
28
- def sheets_ns
29
- ::Google::Apis::SheetsV4
30
- end
31
-
32
- def sheets_color(color); end
33
-
34
28
  def set_extended_value_type!(extended_value, value)
35
29
  v = value || ''
36
30
  if v.start_with?('=')
@@ -45,7 +39,7 @@ module CSVPlusPlus
45
39
  end
46
40
 
47
41
  def build_cell_format(mod)
48
- sheets_ns::CellFormat.new.tap do |cf|
42
+ ::Google::Apis::SheetsV4::CellFormat.new.tap do |cf|
49
43
  cf.text_format = mod.text_format
50
44
 
51
45
  cf.horizontal_alignment = mod.halign
@@ -56,7 +50,7 @@ module CSVPlusPlus
56
50
  end
57
51
 
58
52
  def grid_range_for_cell(cell)
59
- sheets_ns::GridRange.new(
53
+ ::Google::Apis::SheetsV4::GridRange.new(
60
54
  sheet_id: @sheet_id,
61
55
  start_column_index: cell.index,
62
56
  end_column_index: cell.index + 1,
@@ -72,7 +66,7 @@ module CSVPlusPlus
72
66
  end
73
67
 
74
68
  def build_cell_value(cell)
75
- sheets_ns::ExtendedValue.new.tap do |xv|
69
+ ::Google::Apis::SheetsV4::ExtendedValue.new.tap do |xv|
76
70
  value =
77
71
  if cell.value.nil?
78
72
  current_value(cell.row_index, cell.index)
@@ -87,7 +81,7 @@ module CSVPlusPlus
87
81
  def build_cell_data(cell)
88
82
  mod = ::CSVPlusPlus::Writer::GoogleSheetModifier.new(cell.modifier)
89
83
 
90
- sheets_ns::CellData.new.tap do |cd|
84
+ ::Google::Apis::SheetsV4::CellData.new.tap do |cd|
91
85
  cd.user_entered_format = build_cell_format(mod)
92
86
  cd.note = mod.note if mod.note
93
87
 
@@ -97,13 +91,13 @@ module CSVPlusPlus
97
91
  end
98
92
 
99
93
  def build_row_data(row)
100
- sheets_ns::RowData.new(values: row.cells.map { |cell| build_cell_data(cell) })
94
+ ::Google::Apis::SheetsV4::RowData.new(values: row.cells.map { |cell| build_cell_data(cell) })
101
95
  end
102
96
 
103
97
  def build_update_cells_request(rows)
104
- sheets_ns::UpdateCellsRequest.new(
98
+ ::Google::Apis::SheetsV4::UpdateCellsRequest.new(
105
99
  fields: '*',
106
- start: sheets_ns::GridCoordinate.new(
100
+ start: ::Google::Apis::SheetsV4::GridCoordinate.new(
107
101
  sheet_id: @sheet_id,
108
102
  column_index: @column_index,
109
103
  row_index: @row_index
@@ -113,29 +107,31 @@ module CSVPlusPlus
113
107
  end
114
108
 
115
109
  def build_border(cell)
116
- mod = cell.modifier
117
- # TODO: allow different border styles per side
118
- border = sheets_ns::Border.new(color: mod.bordercolor || '#000000', style: mod.borderstyle || 'solid')
119
- sheets_ns::UpdateBordersRequest.new(
120
- top: mod.border_along?('top') ? border : nil,
121
- right: mod.border_along?('right') ? border : nil,
122
- left: mod.border_along?('left') ? border : nil,
123
- bottom: mod.border_along?('bottom') ? border : nil,
110
+ mod = ::CSVPlusPlus::Writer::GoogleSheetModifier.new(cell.modifier)
111
+ border = mod.border
112
+
113
+ ::Google::Apis::SheetsV4::UpdateBordersRequest.new(
114
+ top: mod.border_along?(:top) ? border : nil,
115
+ right: mod.border_along?(:right) ? border : nil,
116
+ left: mod.border_along?(:left) ? border : nil,
117
+ bottom: mod.border_along?(:bottom) ? border : nil,
124
118
  range: grid_range_for_cell(cell)
125
119
  )
126
120
  end
127
121
 
128
122
  def build_update_borders_request(cell)
129
- sheets_ns::Request.new(update_borders: build_border(cell))
123
+ ::Google::Apis::SheetsV4::Request.new(update_borders: build_border(cell))
124
+ end
125
+
126
+ def chunked_requests(rows)
127
+ rows.each_slice(1000).to_a.map do |chunked_rows|
128
+ ::Google::Apis::SheetsV4::Request.new(update_cells: build_update_cells_request(chunked_rows))
129
+ end
130
130
  end
131
131
 
132
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
133
132
  def build_batch_request(rows)
134
- sheets_ns::BatchUpdateSpreadsheetRequest.new.tap do |bu|
135
- bu.requests =
136
- rows.each_slice(1000).to_a.map do |chunked_rows|
137
- sheets_ns::Request.new(update_cells: build_update_cells_request(chunked_rows))
138
- end
133
+ ::Google::Apis::SheetsV4::BatchUpdateSpreadsheetRequest.new.tap do |bu|
134
+ bu.requests = chunked_requests(rows)
139
135
 
140
136
  rows.each do |row|
141
137
  row.cells.filter { |c| c.modifier.any_border? }
@@ -145,7 +141,6 @@ module CSVPlusPlus
145
141
  end
146
142
  end
147
143
  end
148
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
149
144
  end
150
145
  # rubocop:enable Metrics/ClassLength
151
146
  end
@@ -4,44 +4,65 @@ module CSVPlusPlus
4
4
  module Writer
5
5
  # Decorate a Modifier so it can be written to the Google Sheets API
6
6
  class GoogleSheetModifier < ::SimpleDelegator
7
- # Format the halign for Google Sheets
8
- def halign
9
- super&.upcase
10
- end
11
-
12
- # Format the valign for Google Sheets
13
- def valign
14
- super&.upcase
7
+ # Format the border for Google Sheets
8
+ #
9
+ # @return [Google::Apis::SheetsV4::Border]
10
+ def border
11
+ # TODO: allow different border styles per side
12
+ ::Google::Apis::SheetsV4::Border.new(
13
+ color: bordercolor&.to_s || '#000000',
14
+ style: borderstyle&.to_s || 'solid'
15
+ )
15
16
  end
16
17
 
17
18
  # Format the color for Google Sheets
19
+ #
20
+ # @return [Google::Apis::SheetsV4::Color]
18
21
  def color
19
22
  google_sheets_color(super) if super
20
23
  end
21
24
 
22
25
  # Format the fontcolor for Google Sheets
26
+ #
27
+ # @return [Google::Apis::SheetsV4::Color]
23
28
  def fontcolor
24
29
  google_sheets_color(super) if super
25
30
  end
26
31
 
32
+ # Format the halign for Google Sheets
33
+ #
34
+ # @return [String]
35
+ def halign
36
+ super&.to_s&.upcase
37
+ end
38
+
27
39
  # Format the numberformat for Google Sheets
40
+ #
41
+ # @return [::Google::Apis::SheetsV4::NumberFormat]
28
42
  def numberformat
29
43
  ::Google::Apis::SheetsV4::NumberFormat.new(type: super) if super
30
44
  end
31
45
 
32
46
  # Builds a SheetsV4::TextFormat with the underlying Modifier
47
+ #
48
+ # @return [::Google::Apis::SheetsV4::TextFormat]
33
49
  def text_format
34
50
  ::Google::Apis::SheetsV4::TextFormat.new(
35
- bold: formatted?('bold') || nil,
36
- italic: formatted?('italic') || nil,
37
- strikethrough: formatted?('strikethrough') || nil,
38
- underline: formatted?('underline') || nil,
51
+ bold: formatted?(:bold) || nil,
52
+ italic: formatted?(:italic) || nil,
53
+ strikethrough: formatted?(:strikethrough) || nil,
54
+ underline: formatted?(:underline) || nil,
39
55
  font_family: fontfamily,
40
56
  font_size: fontsize,
41
57
  foreground_color: fontcolor
42
58
  )
43
59
  end
44
60
 
61
+ # Format the valign for Google Sheets
62
+ def valign
63
+ super&.to_s&.upcase
64
+ end
65
+
45
66
  private
46
67
 
47
68
  def google_sheets_color(color)
@@ -24,10 +24,7 @@ module CSVPlusPlus
24
24
  #
25
25
  # @return [RubyXL::Workbook]
26
26
  def build_workbook
27
- open_workbook.tap do |workbook|
28
- @worksheet = workbook[@sheet_name]
29
- build_workbook!
30
- end
27
+ open_workbook.tap { build_workbook! }
31
28
  end
32
29
 
33
30
  private
@@ -107,11 +104,11 @@ module CSVPlusPlus
107
104
  def open_workbook
108
105
  if ::File.exist?(@input_filename)
109
106
  ::RubyXL::Parser.parse(@input_filename).tap do |workbook|
110
- workbook.add_worksheet(@sheet_name) unless workbook[@sheet_name]
107
+ @worksheet = workbook[@sheet_name] || workbook.add_worksheet(@sheet_name)
111
108
  end
112
109
  else
113
110
  ::RubyXL::Workbook.new.tap do |workbook|
114
- workbook.worksheets[0].sheet_name = @sheet_name
111
+ @worksheet = workbook.worksheets[0].tap { |w| w.sheet_name = @sheet_name }
115
112
  end
116
113
  end
117
114
  end
data/lib/csv_plus_plus.rb CHANGED
@@ -1,17 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'benchmark'
4
+ require 'csv'
5
+ require 'fileutils'
3
6
  require 'google/apis/drive_v3'
4
7
  require 'google/apis/sheets_v4'
5
8
  require 'googleauth'
9
+ require 'pathname'
6
10
  require 'rubyXL'
7
11
  require 'rubyXL/convenience_methods'
12
+ require 'set'
13
+ require 'tempfile'
8
14
 
9
- require_relative 'csv_plus_plus/cli'
15
+ require_relative 'csv_plus_plus/entities'
10
16
  require_relative 'csv_plus_plus/error'
11
- require_relative 'csv_plus_plus/language/builtins'
12
- require_relative 'csv_plus_plus/language/compiler'
13
- require_relative 'csv_plus_plus/language/runtime'
17
+
18
+ require_relative 'csv_plus_plus/cell'
19
+ require_relative 'csv_plus_plus/cli'
20
+ require_relative 'csv_plus_plus/color'
21
+
22
+ require_relative 'csv_plus_plus/compiler'
23
+ require_relative 'csv_plus_plus/runtime'
24
+
25
+ require_relative 'csv_plus_plus/lexer'
26
+ require_relative 'csv_plus_plus/lexer/tokenizer'
27
+ require_relative 'csv_plus_plus/modifier'
14
28
  require_relative 'csv_plus_plus/options'
29
+ require_relative 'csv_plus_plus/parser/modifier.tab'
30
+ require_relative 'csv_plus_plus/row'
31
+ require_relative 'csv_plus_plus/template'
32
+ require_relative 'csv_plus_plus/validated_modifier'
15
33
  require_relative 'csv_plus_plus/writer'
16
34
 
17
35
  # A programming language for writing rich CSV files
@@ -21,23 +39,30 @@ module CSVPlusPlus
21
39
  # @param input [String] The csvpp input to compile
22
40
  # @param filename [String, nil] The filename the input was read from. +nil+ if it is read from stdin.
23
41
  # @param options [Options] The various options to compile with
24
- #
25
- # rubocop:disable Metrics/MethodLength
26
42
  def self.apply_template_to_sheet!(input, filename, options)
27
43
  warn(options.verbose_summary) if options.verbose
28
44
 
29
- ::CSVPlusPlus::Language::Compiler.with_compiler(
30
- options:,
31
- runtime: ::CSVPlusPlus::Language::Runtime.new(input:, filename:)
32
- ) do |c|
33
- template = c.compile_template
45
+ runtime = ::CSVPlusPlus::Runtime.new(input:, filename:)
34
46
 
47
+ ::CSVPlusPlus::Compiler.with_compiler(options:, runtime:) do |compiler|
48
+ template = compiler.compile_template
49
+
50
+ warn(template.verbose_summary) if options.verbose
51
+
52
+ write_template(template, compiler, options)
53
+ end
54
+ end
55
+
56
+ # Write the results (and possibly make a backup) of a compiled +template+
57
+ #
58
+ # @param template [Template] The compiled template
59
+ # @param compiler [Compiler] The compiler currently in use
60
+ # @param options [Options] The options we're running with
61
+ def self.write_template(template, compiler, options)
62
+ compiler.outputting! do
35
63
  output = ::CSVPlusPlus::Writer.writer(options)
36
- c.outputting! do
37
- output.write_backup if options.backup
38
- output.write(template)
39
- end
64
+ output.write_backup if options.backup
65
+ output.write(template)
40
66
  end
41
67
  end
42
- # rubocop:enable Metrics/MethodLength
43
68
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csv_plus_plus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick Carroll
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-10 00:00:00.000000000 Z
11
+ date: 2023-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-apis-drive_v3
@@ -123,44 +123,54 @@ files:
123
123
  - bin/csv++
124
124
  - bin/csvpp
125
125
  - lib/csv_plus_plus.rb
126
+ - lib/csv_plus_plus/benchmarked_compiler.rb
127
+ - lib/csv_plus_plus/can_define_references.rb
128
+ - lib/csv_plus_plus/can_resolve_references.rb
126
129
  - lib/csv_plus_plus/cell.rb
127
130
  - lib/csv_plus_plus/cli.rb
128
131
  - lib/csv_plus_plus/cli_flag.rb
129
- - lib/csv_plus_plus/code_section.rb
130
132
  - lib/csv_plus_plus/color.rb
133
+ - lib/csv_plus_plus/compiler.rb
134
+ - lib/csv_plus_plus/data_validation.rb
135
+ - lib/csv_plus_plus/entities.rb
136
+ - lib/csv_plus_plus/entities/ast_builder.rb
137
+ - lib/csv_plus_plus/entities/boolean.rb
138
+ - lib/csv_plus_plus/entities/builtins.rb
139
+ - lib/csv_plus_plus/entities/cell_reference.rb
140
+ - lib/csv_plus_plus/entities/date.rb
141
+ - lib/csv_plus_plus/entities/entity.rb
142
+ - lib/csv_plus_plus/entities/function.rb
143
+ - lib/csv_plus_plus/entities/function_call.rb
144
+ - lib/csv_plus_plus/entities/number.rb
145
+ - lib/csv_plus_plus/entities/runtime_value.rb
146
+ - lib/csv_plus_plus/entities/string.rb
147
+ - lib/csv_plus_plus/entities/variable.rb
131
148
  - lib/csv_plus_plus/error.rb
149
+ - lib/csv_plus_plus/error/error.rb
150
+ - lib/csv_plus_plus/error/formula_syntax_error.rb
151
+ - lib/csv_plus_plus/error/modifier_syntax_error.rb
152
+ - lib/csv_plus_plus/error/modifier_validation_error.rb
153
+ - lib/csv_plus_plus/error/syntax_error.rb
154
+ - lib/csv_plus_plus/error/writer_error.rb
132
155
  - lib/csv_plus_plus/expand.rb
133
156
  - lib/csv_plus_plus/google_api_client.rb
134
157
  - lib/csv_plus_plus/google_options.rb
135
158
  - lib/csv_plus_plus/graph.rb
136
- - lib/csv_plus_plus/language/ast_builder.rb
137
- - lib/csv_plus_plus/language/benchmarked_compiler.rb
138
- - lib/csv_plus_plus/language/builtins.rb
139
- - lib/csv_plus_plus/language/cell_value.tab.rb
140
- - lib/csv_plus_plus/language/code_section.tab.rb
141
- - lib/csv_plus_plus/language/compiler.rb
142
- - lib/csv_plus_plus/language/entities.rb
143
- - lib/csv_plus_plus/language/entities/boolean.rb
144
- - lib/csv_plus_plus/language/entities/cell_reference.rb
145
- - lib/csv_plus_plus/language/entities/entity.rb
146
- - lib/csv_plus_plus/language/entities/function.rb
147
- - lib/csv_plus_plus/language/entities/function_call.rb
148
- - lib/csv_plus_plus/language/entities/number.rb
149
- - lib/csv_plus_plus/language/entities/runtime_value.rb
150
- - lib/csv_plus_plus/language/entities/string.rb
151
- - lib/csv_plus_plus/language/entities/variable.rb
152
- - lib/csv_plus_plus/language/references.rb
153
- - lib/csv_plus_plus/language/runtime.rb
154
- - lib/csv_plus_plus/language/scope.rb
155
- - lib/csv_plus_plus/language/syntax_error.rb
156
159
  - lib/csv_plus_plus/lexer.rb
157
160
  - lib/csv_plus_plus/lexer/lexer.rb
158
161
  - lib/csv_plus_plus/lexer/tokenizer.rb
159
162
  - lib/csv_plus_plus/modifier.rb
160
- - lib/csv_plus_plus/modifier.tab.rb
163
+ - lib/csv_plus_plus/modifier/conditional_formatting.rb
161
164
  - lib/csv_plus_plus/options.rb
165
+ - lib/csv_plus_plus/parser/cell_value.tab.rb
166
+ - lib/csv_plus_plus/parser/code_section.tab.rb
167
+ - lib/csv_plus_plus/parser/modifier.tab.rb
168
+ - lib/csv_plus_plus/references.rb
162
169
  - lib/csv_plus_plus/row.rb
170
+ - lib/csv_plus_plus/runtime.rb
171
+ - lib/csv_plus_plus/scope.rb
163
172
  - lib/csv_plus_plus/template.rb
173
+ - lib/csv_plus_plus/validated_modifier.rb
164
174
  - lib/csv_plus_plus/version.rb
165
175
  - lib/csv_plus_plus/writer.rb
166
176
  - lib/csv_plus_plus/writer/base_writer.rb
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative './language/code_section.tab'
4
- require_relative './language/entities'
5
-
6
- module CSVPlusPlus
7
- # A representation of the code section part of a template (the variable and function definitions)
8
- #
9
- # @attr variables [Hash<Symbol, Variable>] All defined variables
10
- # @attr_reader functions [Hash<Symbol, Function>] All defined functions
11
- class CodeSection
12
- attr_reader :functions
13
- attr_accessor :variables
14
-
15
- # @param variables [Hash<Symbol, Variable>] Initial variables
16
- # @param functions [Hash<Symbol, Variable>] Initial functions
17
- def initialize(variables: {}, functions: {})
18
- @variables = variables
19
- @functions = functions
20
- end
21
-
22
- # Define a (or re-define an existing) variable
23
- #
24
- # @param id [String, Symbol] The identifier for the variable
25
- # @param entity [Entity] The value (entity) the variable holds
26
- def def_variable(id, entity)
27
- @variables[id.to_sym] = entity
28
- end
29
-
30
- # Define (or re-define existing) variables
31
- #
32
- # @param variables [Hash<Symbol, Variable>] Variables to define
33
- def def_variables(variables)
34
- variables.each { |id, entity| def_variable(id, entity) }
35
- end
36
-
37
- # Define a (or re-define an existing) function
38
- #
39
- # @param id [String, Symbol] The identifier for the function
40
- # @param entity [Entities::Function] The defined function
41
- def def_function(id, entity)
42
- @functions[id.to_sym] = entity
43
- end
44
-
45
- # Is the variable defined?
46
- #
47
- # @param var_id [Symbol, String] The identifier of the variable
48
- #
49
- # @return [boolean]
50
- def defined_variable?(var_id)
51
- @variables.key?(var_id.to_sym)
52
- end
53
-
54
- # Is the function defined?
55
- #
56
- # @param fn_id [Symbol, String] The identifier of the function
57
- #
58
- # @return [boolean]
59
- def defined_function?(fn_id)
60
- @functions.key?(fn_id.to_sym)
61
- end
62
-
63
- # @return [String]
64
- def to_s
65
- "CodeSection(functions: #{@functions}, variables: #{@variables})"
66
- end
67
- end
68
- end
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'benchmark'
4
-
5
- module CSVPlusPlus
6
- module Language
7
- # Extend a +Compiler+ class and add benchmark timings
8
- # @attr_reader timings [Array<Benchmark::Tms>] +Benchmark+ timings that have been accumulated by each step of
9
- # compilation
10
- # @attr_reader benchmark [Benchmark] A +Benchmark+ instance
11
- module BenchmarkedCompiler
12
- attr_reader :benchmark, :timings
13
-
14
- # Wrap a +Compiler+ with our instance methods that add benchmarks
15
- def self.with_benchmarks(compiler, &block)
16
- ::Benchmark.benchmark(::Benchmark::CAPTION, 25, ::Benchmark::FORMAT, '> Total') do |x|
17
- # compiler = new(options:, runtime:, benchmark: x)
18
- compiler.extend(self)
19
- compiler.benchmark = x
20
-
21
- block.call(compiler)
22
-
23
- [compiler.timings.reduce(:+)]
24
- end
25
- end
26
-
27
- # @param benchmark [Benchmark] A +Benchmark+ instance
28
- def benchmark=(benchmark)
29
- @benchmark = benchmark
30
- @timings = []
31
- end
32
-
33
- # Time the Compiler#outputting! stage
34
- def outputting!
35
- time_stage('Writing the spreadsheet') { super }
36
- end
37
-
38
- protected
39
-
40
- def parse_code_section!
41
- time_stage('Parsing code section') { super }
42
- end
43
-
44
- def parse_csv_section!
45
- time_stage('Parsing CSV section') { super }
46
- end
47
-
48
- def expanding
49
- time_stage('Expanding rows') { super }
50
- end
51
-
52
- def resolve_all_cells!(template)
53
- time_stage('Resolving each cell') { super(template) }
54
- end
55
-
56
- private
57
-
58
- def time_stage(stage, &block)
59
- ret = nil
60
- @timings << @benchmark.report(stage) { ret = block.call }
61
- ret
62
- end
63
- end
64
- end
65
- end