csv_plus_plus 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +18 -63
  3. data/{CHANGELOG.md → docs/CHANGELOG.md} +17 -0
  4. data/lib/csv_plus_plus/benchmarked_compiler.rb +112 -0
  5. data/lib/csv_plus_plus/cell.rb +46 -24
  6. data/lib/csv_plus_plus/cli.rb +44 -17
  7. data/lib/csv_plus_plus/cli_flag.rb +1 -2
  8. data/lib/csv_plus_plus/color.rb +42 -11
  9. data/lib/csv_plus_plus/compiler.rb +178 -0
  10. data/lib/csv_plus_plus/entities/ast_builder.rb +50 -0
  11. data/lib/csv_plus_plus/entities/boolean.rb +40 -0
  12. data/lib/csv_plus_plus/entities/builtins.rb +58 -0
  13. data/lib/csv_plus_plus/entities/cell_reference.rb +231 -0
  14. data/lib/csv_plus_plus/entities/date.rb +63 -0
  15. data/lib/csv_plus_plus/entities/entity.rb +50 -0
  16. data/lib/csv_plus_plus/entities/entity_with_arguments.rb +57 -0
  17. data/lib/csv_plus_plus/entities/function.rb +45 -0
  18. data/lib/csv_plus_plus/entities/function_call.rb +50 -0
  19. data/lib/csv_plus_plus/entities/number.rb +48 -0
  20. data/lib/csv_plus_plus/entities/runtime_value.rb +43 -0
  21. data/lib/csv_plus_plus/entities/string.rb +42 -0
  22. data/lib/csv_plus_plus/entities/variable.rb +37 -0
  23. data/lib/csv_plus_plus/entities.rb +40 -0
  24. data/lib/csv_plus_plus/error/error.rb +20 -0
  25. data/lib/csv_plus_plus/error/formula_syntax_error.rb +37 -0
  26. data/lib/csv_plus_plus/error/modifier_syntax_error.rb +75 -0
  27. data/lib/csv_plus_plus/error/modifier_validation_error.rb +69 -0
  28. data/lib/csv_plus_plus/error/syntax_error.rb +71 -0
  29. data/lib/csv_plus_plus/error/writer_error.rb +17 -0
  30. data/lib/csv_plus_plus/error.rb +10 -2
  31. data/lib/csv_plus_plus/google_api_client.rb +11 -2
  32. data/lib/csv_plus_plus/google_options.rb +23 -18
  33. data/lib/csv_plus_plus/lexer/lexer.rb +17 -6
  34. data/lib/csv_plus_plus/lexer/tokenizer.rb +6 -1
  35. data/lib/csv_plus_plus/lexer.rb +24 -0
  36. data/lib/csv_plus_plus/modifier/conditional_formatting.rb +18 -0
  37. data/lib/csv_plus_plus/modifier/data_validation.rb +138 -0
  38. data/lib/csv_plus_plus/modifier/expand.rb +61 -0
  39. data/lib/csv_plus_plus/modifier/google_sheet_modifier.rb +133 -0
  40. data/lib/csv_plus_plus/modifier/modifier.rb +222 -0
  41. data/lib/csv_plus_plus/modifier/modifier_validator.rb +243 -0
  42. data/lib/csv_plus_plus/modifier/rubyxl_modifier.rb +84 -0
  43. data/lib/csv_plus_plus/modifier.rb +82 -150
  44. data/lib/csv_plus_plus/options.rb +64 -19
  45. data/lib/csv_plus_plus/{language → parser}/cell_value.tab.rb +25 -25
  46. data/lib/csv_plus_plus/{language → parser}/code_section.tab.rb +86 -95
  47. data/lib/csv_plus_plus/parser/modifier.tab.rb +478 -0
  48. data/lib/csv_plus_plus/row.rb +53 -15
  49. data/lib/csv_plus_plus/runtime/can_define_references.rb +87 -0
  50. data/lib/csv_plus_plus/runtime/can_resolve_references.rb +209 -0
  51. data/lib/csv_plus_plus/runtime/graph.rb +68 -0
  52. data/lib/csv_plus_plus/runtime/position_tracker.rb +231 -0
  53. data/lib/csv_plus_plus/runtime/references.rb +110 -0
  54. data/lib/csv_plus_plus/runtime/runtime.rb +126 -0
  55. data/lib/csv_plus_plus/runtime.rb +42 -0
  56. data/lib/csv_plus_plus/source_code.rb +66 -0
  57. data/lib/csv_plus_plus/template.rb +63 -36
  58. data/lib/csv_plus_plus/version.rb +2 -1
  59. data/lib/csv_plus_plus/writer/base_writer.rb +30 -5
  60. data/lib/csv_plus_plus/writer/csv.rb +11 -9
  61. data/lib/csv_plus_plus/writer/excel.rb +9 -2
  62. data/lib/csv_plus_plus/writer/file_backer_upper.rb +7 -4
  63. data/lib/csv_plus_plus/writer/google_sheet_builder.rb +88 -45
  64. data/lib/csv_plus_plus/writer/google_sheets.rb +79 -29
  65. data/lib/csv_plus_plus/writer/open_document.rb +6 -1
  66. data/lib/csv_plus_plus/writer/rubyxl_builder.rb +103 -33
  67. data/lib/csv_plus_plus/writer.rb +39 -9
  68. data/lib/csv_plus_plus.rb +41 -15
  69. metadata +44 -30
  70. data/lib/csv_plus_plus/code_section.rb +0 -101
  71. data/lib/csv_plus_plus/expand.rb +0 -18
  72. data/lib/csv_plus_plus/graph.rb +0 -62
  73. data/lib/csv_plus_plus/language/ast_builder.rb +0 -68
  74. data/lib/csv_plus_plus/language/benchmarked_compiler.rb +0 -65
  75. data/lib/csv_plus_plus/language/builtins.rb +0 -46
  76. data/lib/csv_plus_plus/language/compiler.rb +0 -152
  77. data/lib/csv_plus_plus/language/entities/boolean.rb +0 -33
  78. data/lib/csv_plus_plus/language/entities/cell_reference.rb +0 -33
  79. data/lib/csv_plus_plus/language/entities/entity.rb +0 -86
  80. data/lib/csv_plus_plus/language/entities/function.rb +0 -35
  81. data/lib/csv_plus_plus/language/entities/function_call.rb +0 -37
  82. data/lib/csv_plus_plus/language/entities/number.rb +0 -36
  83. data/lib/csv_plus_plus/language/entities/runtime_value.rb +0 -28
  84. data/lib/csv_plus_plus/language/entities/string.rb +0 -31
  85. data/lib/csv_plus_plus/language/entities/variable.rb +0 -25
  86. data/lib/csv_plus_plus/language/entities.rb +0 -28
  87. data/lib/csv_plus_plus/language/references.rb +0 -70
  88. data/lib/csv_plus_plus/language/runtime.rb +0 -205
  89. data/lib/csv_plus_plus/language/scope.rb +0 -192
  90. data/lib/csv_plus_plus/language/syntax_error.rb +0 -66
  91. data/lib/csv_plus_plus/modifier.tab.rb +0 -907
  92. data/lib/csv_plus_plus/writer/google_sheet_modifier.rb +0 -56
  93. data/lib/csv_plus_plus/writer/rubyxl_modifier.rb +0 -59
@@ -0,0 +1,478 @@
1
+ #
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by Racc 1.6.2
4
+ # from Racc grammar file "".
5
+ #
6
+
7
+ require 'racc/parser.rb'
8
+
9
+
10
+ require_relative '../lexer'
11
+
12
+ module CSVPlusPlus
13
+ module Parser
14
+ class Modifier < Racc::Parser
15
+
16
+ module_eval(<<'...end modifier.y/module_eval...', 'modifier.y', 60)
17
+ attr_reader :return_value
18
+
19
+ include ::CSVPlusPlus::Lexer
20
+
21
+ # @param cell_modifier [Modifier]
22
+ # @param row_modifier [Modifier]
23
+ def initialize(cell_modifier:, row_modifier:)
24
+ super()
25
+
26
+ @parsing_row = false
27
+ @cell_modifier = ::CSVPlusPlus::Modifier::ModifierValidator.new(cell_modifier)
28
+ @row_modifier = ::CSVPlusPlus::Modifier::ModifierValidator.new(row_modifier)
29
+ end
30
+
31
+ protected
32
+
33
+ def anything_to_parse?(input)
34
+ @modifiers_to_parse = input.scan(/!?\[\[/).count
35
+
36
+ if @modifiers_to_parse == 0
37
+ assign_defaults!
38
+ @return_value = input
39
+ end
40
+
41
+ @modifiers_to_parse > 0
42
+ end
43
+
44
+ def parse_subject
45
+ 'modifier'
46
+ end
47
+
48
+ def tokenizer
49
+ ::CSVPlusPlus::Lexer::Tokenizer.new(
50
+ ignore: /\s+/,
51
+ stop_fn: lambda do |scanner|
52
+ return false unless scanner.scan(/\]\]/)
53
+
54
+ @tokens << [:END_MODIFIERS, scanner.matched]
55
+ @return_value = scanner.rest
56
+
57
+ @modifiers_to_parse -= 1
58
+ @modifiers_to_parse == 0
59
+ end,
60
+ tokens: [
61
+ [/\bborder\b/, 'border'],
62
+ [/\bbordercolor\b/, 'bordercolor'],
63
+ [/\bborderstyle\b/, 'borderstyle'],
64
+ [/\bcolor\b/, 'color'],
65
+ [/\bexpand\b/, 'expand'],
66
+ [/\bfontcolor\b/, 'fontcolor'],
67
+ [/\bfontfamily\b/, 'fontfamily'],
68
+ [/\bfontsize\b/, 'fontsize'],
69
+ [/\bformat\b/, 'format'],
70
+ [/\bfreeze\b/, 'freeze'],
71
+ [/\bhalign\b/, 'halign'],
72
+ [/\bnote\b/, 'note'],
73
+ [/\bnumberformat\b/, 'numberformat'],
74
+ [/\bvalidate\b/, 'validate'],
75
+ [/\bvalign\b/, 'valign'],
76
+ [/\bvar\b/, 'var'],
77
+ [/-?[\d.]+/, :NUMBER],
78
+ TOKEN_LIBRARY[:HEX_COLOR],
79
+ [
80
+ /
81
+ (?:
82
+ \w+\s*:\s*'([^'\\]|\\.)*') # allow for a single-quoted string which can accept any input and also allow
83
+ # for escaping via backslash (i.e., 'ain\\'t won\\'t something' is valid)
84
+ | # - or -
85
+ (?:'([^'\\]|\\.)*') # allow for a single-quoted string which can accept any input and also allow
86
+ |
87
+ (?:
88
+ [\w,_:-] # something that accepts most basic input if it doesn't need to be quoted
89
+ [\w\s,_:-]+ # same thing but allow spaces in the middle
90
+ [\w,_:-] # no spaces at the end
91
+ )
92
+ /x,
93
+ :RIGHT_SIDE,
94
+ ],
95
+ [/\[\[/, :START_CELL_MODIFIERS],
96
+ [/!\[\[/, :START_ROW_MODIFIERS],
97
+ [/\//, :MODIFIER_SEPARATOR],
98
+ [/=/, :EQ],
99
+ ],
100
+ alter_matches: {
101
+ STRING: ->(s) { s.gsub(/^'|'$/, '') }
102
+ },
103
+ )
104
+ end
105
+
106
+ private
107
+
108
+ def assign_defaults!
109
+ @cell_modifier.modifier.take_defaults_from!(@row_modifier.modifier)
110
+ end
111
+
112
+ def parsing_row!
113
+ @parsing_row = true
114
+ end
115
+
116
+ def finished_row!
117
+ parsing_cell!
118
+ end
119
+
120
+ def parsing_cell!
121
+ @parsing_row = false
122
+ assign_defaults!
123
+ end
124
+
125
+ def modifier
126
+ @parsing_row ? @row_modifier : @cell_modifier
127
+ end
128
+ ...end modifier.y/module_eval...
129
+ ##### State transition tables begin ###
130
+
131
+ racc_action_table = [
132
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
133
+ 23, 24, 25, 26, 27, 28, 13, 14, 15, 16,
134
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
135
+ 27, 28, 13, 14, 15, 16, 17, 18, 19, 20,
136
+ 21, 22, 23, 24, 25, 26, 27, 28, 30, 47,
137
+ 5, 4, 6, 31, 31, 5, 10, 32, 33, 34,
138
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
139
+ 45, 46, 49, 50, 51, 52, 53, 54, 55, 56,
140
+ 57, 58, 59, 60, 61, 62, 63 ]
141
+
142
+ racc_action_check = [
143
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
144
+ 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,
145
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
146
+ 9, 9, 31, 31, 31, 31, 31, 31, 31, 31,
147
+ 31, 31, 31, 31, 31, 31, 31, 31, 11, 29,
148
+ 0, 0, 1, 11, 29, 2, 6, 13, 14, 15,
149
+ 16, 17, 18, 19, 20, 21, 23, 24, 25, 26,
150
+ 27, 28, 32, 33, 34, 35, 36, 37, 38, 39,
151
+ 40, 41, 42, 43, 44, 45, 46 ]
152
+
153
+ racc_action_pointer = [
154
+ 36, 52, 41, nil, nil, nil, 56, nil, -17, -1,
155
+ nil, 41, nil, 49, 50, 51, 52, 53, 54, 55,
156
+ 56, 57, nil, 58, 59, 60, 61, 62, 63, 42,
157
+ nil, 15, 59, 64, 61, 66, 66, 68, 65, 69,
158
+ 67, 68, 69, 70, 71, 72, 73, nil, nil, nil,
159
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
160
+ nil, nil, nil, nil ]
161
+
162
+ racc_action_default = [
163
+ -27, -27, -2, -3, -4, -6, -27, -1, -27, -27,
164
+ 64, -27, -9, -27, -27, -27, -27, -15, -27, -27,
165
+ -27, -27, -20, -27, -27, -27, -27, -27, -27, -27,
166
+ -5, -27, -27, -27, -27, -27, -27, -27, -27, -27,
167
+ -27, -27, -27, -27, -27, -27, -27, -7, -8, -10,
168
+ -11, -12, -13, -14, -16, -17, -18, -19, -21, -22,
169
+ -23, -24, -25, -26 ]
170
+
171
+ racc_goto_table = [
172
+ 3, 1, 7, 11, 29, 2, 8, 9, 48 ]
173
+
174
+ racc_goto_check = [
175
+ 3, 1, 3, 4, 4, 2, 5, 6, 7 ]
176
+
177
+ racc_goto_pointer = [
178
+ nil, 1, 5, 0, -5, 2, 2, -23 ]
179
+
180
+ racc_goto_default = [
181
+ nil, nil, nil, nil, nil, nil, nil, 12 ]
182
+
183
+ racc_reduce_table = [
184
+ 0, 0, :racc_error,
185
+ 2, 34, :_reduce_none,
186
+ 1, 34, :_reduce_none,
187
+ 1, 34, :_reduce_none,
188
+ 0, 38, :_reduce_4,
189
+ 4, 35, :_reduce_5,
190
+ 0, 39, :_reduce_6,
191
+ 4, 36, :_reduce_none,
192
+ 3, 37, :_reduce_none,
193
+ 1, 37, :_reduce_none,
194
+ 3, 40, :_reduce_10,
195
+ 3, 40, :_reduce_11,
196
+ 3, 40, :_reduce_12,
197
+ 3, 40, :_reduce_13,
198
+ 3, 40, :_reduce_14,
199
+ 1, 40, :_reduce_15,
200
+ 3, 40, :_reduce_16,
201
+ 3, 40, :_reduce_17,
202
+ 3, 40, :_reduce_18,
203
+ 3, 40, :_reduce_19,
204
+ 1, 40, :_reduce_20,
205
+ 3, 40, :_reduce_21,
206
+ 3, 40, :_reduce_22,
207
+ 3, 40, :_reduce_23,
208
+ 3, 40, :_reduce_24,
209
+ 3, 40, :_reduce_25,
210
+ 3, 40, :_reduce_26 ]
211
+
212
+ racc_reduce_n = 27
213
+
214
+ racc_shift_n = 64
215
+
216
+ racc_token_table = {
217
+ false => 0,
218
+ :error => 1,
219
+ "![[" => 2,
220
+ "[[" => 3,
221
+ "]]" => 4,
222
+ "=" => 5,
223
+ "/" => 6,
224
+ :END_MODIFIERS => 7,
225
+ :EQ => 8,
226
+ :HEX_COLOR => 9,
227
+ :NUMBER => 10,
228
+ :MODIFIER => 11,
229
+ :MODIFIER_SEPARATOR => 12,
230
+ :RIGHT_SIDE => 13,
231
+ :START_CELL_MODIFIERS => 14,
232
+ :START_ROW_MODIFIERS => 15,
233
+ :STRING => 16,
234
+ "border" => 17,
235
+ "bordercolor" => 18,
236
+ "borderstyle" => 19,
237
+ "color" => 20,
238
+ "expand" => 21,
239
+ "fontcolor" => 22,
240
+ "fontfamily" => 23,
241
+ "fontsize" => 24,
242
+ "format" => 25,
243
+ "freeze" => 26,
244
+ "halign" => 27,
245
+ "note" => 28,
246
+ "numberformat" => 29,
247
+ "validate" => 30,
248
+ "valign" => 31,
249
+ "var" => 32 }
250
+
251
+ racc_nt_base = 33
252
+
253
+ racc_use_result_var = true
254
+
255
+ Racc_arg = [
256
+ racc_action_table,
257
+ racc_action_check,
258
+ racc_action_default,
259
+ racc_action_pointer,
260
+ racc_goto_table,
261
+ racc_goto_check,
262
+ racc_goto_default,
263
+ racc_goto_pointer,
264
+ racc_nt_base,
265
+ racc_reduce_table,
266
+ racc_token_table,
267
+ racc_shift_n,
268
+ racc_reduce_n,
269
+ racc_use_result_var ]
270
+
271
+ Racc_token_to_s_table = [
272
+ "$end",
273
+ "error",
274
+ "\"![[\"",
275
+ "\"[[\"",
276
+ "\"]]\"",
277
+ "\"=\"",
278
+ "\"/\"",
279
+ "END_MODIFIERS",
280
+ "EQ",
281
+ "HEX_COLOR",
282
+ "NUMBER",
283
+ "MODIFIER",
284
+ "MODIFIER_SEPARATOR",
285
+ "RIGHT_SIDE",
286
+ "START_CELL_MODIFIERS",
287
+ "START_ROW_MODIFIERS",
288
+ "STRING",
289
+ "\"border\"",
290
+ "\"bordercolor\"",
291
+ "\"borderstyle\"",
292
+ "\"color\"",
293
+ "\"expand\"",
294
+ "\"fontcolor\"",
295
+ "\"fontfamily\"",
296
+ "\"fontsize\"",
297
+ "\"format\"",
298
+ "\"freeze\"",
299
+ "\"halign\"",
300
+ "\"note\"",
301
+ "\"numberformat\"",
302
+ "\"validate\"",
303
+ "\"valign\"",
304
+ "\"var\"",
305
+ "$start",
306
+ "modifiers_definition",
307
+ "row_modifiers",
308
+ "cell_modifiers",
309
+ "modifiers",
310
+ "@1",
311
+ "@2",
312
+ "modifier" ]
313
+
314
+ Racc_debug_parser = false
315
+
316
+ ##### State transition tables end #####
317
+
318
+ # reduce 0 omitted
319
+
320
+ # reduce 1 omitted
321
+
322
+ # reduce 2 omitted
323
+
324
+ # reduce 3 omitted
325
+
326
+ module_eval(<<'.,.,', 'modifier.y', 25)
327
+ def _reduce_4(val, _values, result)
328
+ parsing_row!
329
+ result
330
+ end
331
+ .,.,
332
+
333
+ module_eval(<<'.,.,', 'modifier.y', 27)
334
+ def _reduce_5(val, _values, result)
335
+ finished_row!
336
+ result
337
+ end
338
+ .,.,
339
+
340
+ module_eval(<<'.,.,', 'modifier.y', 29)
341
+ def _reduce_6(val, _values, result)
342
+ parsing_cell!
343
+ result
344
+ end
345
+ .,.,
346
+
347
+ # reduce 7 omitted
348
+
349
+ # reduce 8 omitted
350
+
351
+ # reduce 9 omitted
352
+
353
+ module_eval(<<'.,.,', 'modifier.y', 35)
354
+ def _reduce_10(val, _values, result)
355
+ modifier.border = val[2]
356
+ result
357
+ end
358
+ .,.,
359
+
360
+ module_eval(<<'.,.,', 'modifier.y', 36)
361
+ def _reduce_11(val, _values, result)
362
+ modifier.bordercolor = val[2]
363
+ result
364
+ end
365
+ .,.,
366
+
367
+ module_eval(<<'.,.,', 'modifier.y', 37)
368
+ def _reduce_12(val, _values, result)
369
+ modifier.borderstyle = val[2]
370
+ result
371
+ end
372
+ .,.,
373
+
374
+ module_eval(<<'.,.,', 'modifier.y', 38)
375
+ def _reduce_13(val, _values, result)
376
+ modifier.color = val[2]
377
+ result
378
+ end
379
+ .,.,
380
+
381
+ module_eval(<<'.,.,', 'modifier.y', 39)
382
+ def _reduce_14(val, _values, result)
383
+ modifier.expand = val[2]
384
+ result
385
+ end
386
+ .,.,
387
+
388
+ module_eval(<<'.,.,', 'modifier.y', 40)
389
+ def _reduce_15(val, _values, result)
390
+ modifier.infinite_expand!
391
+ result
392
+ end
393
+ .,.,
394
+
395
+ module_eval(<<'.,.,', 'modifier.y', 41)
396
+ def _reduce_16(val, _values, result)
397
+ modifier.fontcolor = val[2]
398
+ result
399
+ end
400
+ .,.,
401
+
402
+ module_eval(<<'.,.,', 'modifier.y', 42)
403
+ def _reduce_17(val, _values, result)
404
+ modifier.fontfamily = val[2]
405
+ result
406
+ end
407
+ .,.,
408
+
409
+ module_eval(<<'.,.,', 'modifier.y', 43)
410
+ def _reduce_18(val, _values, result)
411
+ modifier.fontsize = val[2]
412
+ result
413
+ end
414
+ .,.,
415
+
416
+ module_eval(<<'.,.,', 'modifier.y', 44)
417
+ def _reduce_19(val, _values, result)
418
+ modifier.format = val[2]
419
+ result
420
+ end
421
+ .,.,
422
+
423
+ module_eval(<<'.,.,', 'modifier.y', 45)
424
+ def _reduce_20(val, _values, result)
425
+ modifier.freeze!
426
+ result
427
+ end
428
+ .,.,
429
+
430
+ module_eval(<<'.,.,', 'modifier.y', 46)
431
+ def _reduce_21(val, _values, result)
432
+ modifier.halign = val[2]
433
+ result
434
+ end
435
+ .,.,
436
+
437
+ module_eval(<<'.,.,', 'modifier.y', 47)
438
+ def _reduce_22(val, _values, result)
439
+ modifier.note = val[2]
440
+ result
441
+ end
442
+ .,.,
443
+
444
+ module_eval(<<'.,.,', 'modifier.y', 48)
445
+ def _reduce_23(val, _values, result)
446
+ modifier.numberformat = val[2]
447
+ result
448
+ end
449
+ .,.,
450
+
451
+ module_eval(<<'.,.,', 'modifier.y', 49)
452
+ def _reduce_24(val, _values, result)
453
+ modifier.validate = val[2]
454
+ result
455
+ end
456
+ .,.,
457
+
458
+ module_eval(<<'.,.,', 'modifier.y', 50)
459
+ def _reduce_25(val, _values, result)
460
+ modifier.valign = val[2]
461
+ result
462
+ end
463
+ .,.,
464
+
465
+ module_eval(<<'.,.,', 'modifier.y', 51)
466
+ def _reduce_26(val, _values, result)
467
+ modifier.var = val[2]
468
+ result
469
+ end
470
+ .,.,
471
+
472
+ def _reduce_none(val, _values, result)
473
+ val[0]
474
+ end
475
+
476
+ end # class Modifier
477
+ end # module Parser
478
+ end # module CSVPlusPlus
@@ -1,26 +1,37 @@
1
+ # typed: strict
1
2
  # frozen_string_literal: true
2
3
 
3
- require_relative 'cell'
4
- require_relative 'modifier.tab'
5
-
6
4
  module CSVPlusPlus
7
- # A row of a template
5
+ # A row of a template. A row contains an +Array+ of +Cell+s and possibly a row-level +Modifier+.
8
6
  #
9
- # @attr_reader cells [Array<Cell>]
10
- # @attr_reader index [Integer] The index of this row
7
+ # @attr_reader cells [Array<Cell>] The cells contained by this row.
8
+ # @attr_reader index [Integer] The index of this row. Starts at 0.
11
9
  # @attr_reader modifier [Modifier] The modifier to apply to all cells in this row
12
10
  class Row
13
- attr_reader :cells, :index, :modifier
11
+ extend ::T::Sig
14
12
 
15
- # @param index [Integer] The index of this row (starts at 0)
13
+ sig { returns(::T::Array[::CSVPlusPlus::Cell]) }
14
+ attr_reader :cells
15
+
16
+ sig { returns(::Integer) }
17
+ attr_reader :index
18
+
19
+ sig { returns(::CSVPlusPlus::Modifier::Modifier) }
20
+ attr_reader :modifier
21
+
22
+ sig do
23
+ params(cells: ::T::Array[::CSVPlusPlus::Cell], index: ::Integer, modifier: ::CSVPlusPlus::Modifier::Modifier).void
24
+ end
16
25
  # @param cells [Array<Cell>] The cells belonging to this row
26
+ # @param index [Integer] The index of this row (starts at 0)
17
27
  # @param modifier [Modifier] The modifier to apply to all cells in this row
18
- def initialize(index, cells, modifier)
28
+ def initialize(cells:, index:, modifier:)
19
29
  @cells = cells
20
30
  @modifier = modifier
21
31
  @index = index
22
32
  end
23
33
 
34
+ sig { params(index: ::Integer).void }
24
35
  # Set the row's +index+ and update the +row_index+ of all affected cells
25
36
  #
26
37
  # @param index [Integer] The index of this row (starts at 0)
@@ -29,25 +40,52 @@ module CSVPlusPlus
29
40
  @cells.each { |cell| cell.row_index = index }
30
41
  end
31
42
 
43
+ sig { returns(::Integer) }
32
44
  # How much this row will expand itself, if at all (0)
33
45
  #
34
46
  # @return [Integer]
35
47
  def expand_amount
36
- return 0 unless @modifier.expand
48
+ return 0 if @modifier.expand.nil?
49
+
50
+ ::T.must(@modifier.expand).repetitions || (1000 - @index)
51
+ end
52
+
53
+ sig { params(starts_at: ::Integer, into: ::T::Array[::CSVPlusPlus::Row]).returns(::T::Array[::CSVPlusPlus::Row]) }
54
+ # Starting at +starts_at+, do a deep copy of this row into the +Array+ referenced by +into+.
55
+ #
56
+ # @param starts_at [Integer] The +row_index+ where this row was expanded.
57
+ # @param into [Array<Row>] An array where the expanded rows will be accumulated.
58
+ #
59
+ # @return [Array<Row>] The rows expanded
60
+ def expand_rows(starts_at:, into: [])
61
+ return into if @modifier.expand.nil?
37
62
 
38
- @modifier.expand.repetitions || (1000 - @index)
63
+ ::T.must(@modifier.expand).starts_at = starts_at
64
+
65
+ starts_at.upto(expand_amount + starts_at - 1) do |row_index|
66
+ into << deep_clone.tap { |c| c.index = row_index }
67
+ end
68
+ into
39
69
  end
40
70
 
41
- # @return [String]
42
- def to_s
43
- "Row(index: #{index}, modifier: #{modifier}, cells: #{cells})"
71
+ sig { returns(::T::Boolean) }
72
+ # Does the row have an ![[expand]] modifier but is yet to be expanded?
73
+ #
74
+ # @return [T::Boolean]
75
+ def unexpanded?
76
+ return false if @modifier.expand.nil?
77
+
78
+ !::T.must(@modifier.expand).expanded?
44
79
  end
45
80
 
81
+ private
82
+
83
+ sig { returns(::CSVPlusPlus::Row) }
46
84
  # Return a deep copy of this row
47
85
  #
48
86
  # @return [Row]
49
87
  def deep_clone
50
- ::Marshal.load(::Marshal.dump(self))
88
+ ::T.cast(::Marshal.load(::Marshal.dump(self)), ::CSVPlusPlus::Row)
51
89
  end
52
90
  end
53
91
  end
@@ -0,0 +1,87 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module CSVPlusPlus
5
+ module Runtime
6
+ # Methods for classes that need to manage +@variables+ and +@functions+
7
+ module CanDefineReferences
8
+ # Define a (or re-define an existing) variable
9
+ #
10
+ # @param id [String, Symbol] The identifier for the variable
11
+ # @param entity [Entity] The value (entity) the variable holds
12
+ #
13
+ # @return [Entity] The value of the variable (+entity+)
14
+ def def_variable(id, entity)
15
+ @variables[id.to_sym] = entity
16
+ end
17
+
18
+ # Define (or re-define existing) variables
19
+ #
20
+ # @param vars [Hash<Symbol, Variable>] Variables to define
21
+ def def_variables(vars)
22
+ vars.each { |id, entity| def_variable(id, entity) }
23
+ end
24
+
25
+ # Define a (or re-define an existing) function
26
+ #
27
+ # @param id [String, Symbol] The identifier for the function
28
+ # @param entity [Entities::Function] The defined function
29
+ #
30
+ # @return [Entities::Function] The defined function
31
+ def def_function(id, entity)
32
+ @functions[id.to_sym] = entity
33
+ end
34
+
35
+ # Is the variable defined?
36
+ #
37
+ # @param var_id [Symbol, String] The identifier of the variable
38
+ #
39
+ # @return [boolean]
40
+ def defined_variable?(var_id)
41
+ @variables.key?(var_id.to_sym)
42
+ end
43
+
44
+ # Is the function defined?
45
+ #
46
+ # @param fn_id [Symbol, String] The identifier of the function
47
+ #
48
+ # @return [boolean]
49
+ def defined_function?(fn_id)
50
+ @functions.key?(fn_id.to_sym)
51
+ end
52
+
53
+ # Provide a summary of the functions and variables compiled (to show in verbose mode)
54
+ #
55
+ # @return [String]
56
+ def verbose_summary
57
+ <<~SUMMARY
58
+ # Code Section Summary
59
+
60
+ ## Resolved Variables
61
+
62
+ #{variable_summary}
63
+
64
+ ## Functions
65
+
66
+ #{function_summary}
67
+ SUMMARY
68
+ end
69
+
70
+ private
71
+
72
+ def variable_summary
73
+ return '(no variables defined)' if @variables.empty?
74
+
75
+ @variables.map { |k, v| "#{k} := #{v}" }
76
+ .join("\n")
77
+ end
78
+
79
+ def function_summary
80
+ return '(no functions defined)' if @functions.empty?
81
+
82
+ @functions.map { |k, f| "#{k}: #{f}" }
83
+ .join("\n")
84
+ end
85
+ end
86
+ end
87
+ end