csv_plus_plus 0.1.0 → 0.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a93c3ee93f2320dc717ee330c55cd3f300cfa4d155a4502b9a433cdafdcc389
4
- data.tar.gz: aa95dca43a374d57f2217030e0aefef680341549613b0388cb5df1122cb5f815
3
+ metadata.gz: 6ef86258faa82b75114acc715e9cb68bb312dc55194d533270fce0a796e02362
4
+ data.tar.gz: 9316f43dd4169a779efc6d8f447002434c4fc5984064b1f22f1448baee0f4522
5
5
  SHA512:
6
- metadata.gz: 19a827c9a5fc8f0f9fe9d58c4e6b85de821c9e09627465673c2813c2690fadc886c7d8f24e3da5402783b27347a79f7832b13c82abe4e204026d12839d6f4691
7
- data.tar.gz: b157b531d9ae9e2fda9c93ed466976deacfe639b1fbc1527b60c706be9d97792946341a767f00c32b6d35cbc6e388711980767d9ef6b5c20b4a2f44ebe7fb121
6
+ metadata.gz: 8637e6c3dec41bf747e5fe1f6eb4d3227247e196ef530bbac96e964f6cdbe911d39bed9941ab7e116f00ea2547cf5050a609f078af8dab8f28a6e0f7746e776d
7
+ data.tar.gz: 57acb6edef384a31a41ea244841d2977d31817d87735944336688f5961d6eb22c97e5b88683d753c1163239f397936411a7836eafe1aef6e9ed6a612e846fd68
data/CHANGELOG.md CHANGED
@@ -1,8 +1,15 @@
1
+ ## v0.1.1
2
+
3
+ - Better support for the various infix operators (+,-,/,*,^,%,=,<,etc)
4
+ * Previously we were converting them to their prefix equivalent (multiply, minus, concat, etc) but excel doesn't support most of those. So we keep them infix
5
+ * Didn't support some infix operators (^, %, </>/<=/>=/<>)
6
+ * Proper support for operator precedence
7
+ - When in verbose mode, print a summary of compiled functions and variables
8
+ - docs & tests
1
9
 
2
10
  ## v0.1.0
3
11
 
4
12
  - revamp of builtin functions
5
-
6
13
  - docs & tests
7
14
 
8
15
  ## v0.0.5
@@ -64,5 +64,38 @@ module CSVPlusPlus
64
64
  def to_s
65
65
  "CodeSection(functions: #{@functions}, variables: #{@variables})"
66
66
  end
67
+
68
+ # Provide a summary of the functions and variables compiled (to show in verbose mode)
69
+ #
70
+ # @return [String]
71
+ def verbose_summary
72
+ <<~SUMMARY
73
+ # Code Section Summary
74
+
75
+ ## Resolved Variables
76
+
77
+ #{variable_summary}
78
+
79
+ ## Functions
80
+
81
+ #{function_summary}
82
+ SUMMARY
83
+ end
84
+
85
+ private
86
+
87
+ def variable_summary
88
+ return '(no variables defined)' if @variables.empty?
89
+
90
+ @variables.map { |k, v| "#{k} := #{v}" }
91
+ .join("\n")
92
+ end
93
+
94
+ def function_summary
95
+ return '(no functions defined)' if @functions.empty?
96
+
97
+ @functions.map { |k, f| "#{k}: #{f}" }
98
+ .join("\n")
99
+ end
67
100
  end
68
101
  end
@@ -13,11 +13,11 @@ module CSVPlusPlus
13
13
  # @param arguments [] The arguments to create the entity with
14
14
  #
15
15
  # @return [Entity, #super]
16
- def method_missing(method_name, *arguments)
16
+ def method_missing(method_name, *args, **kwargs, &)
17
17
  entity_class = ::CSVPlusPlus::Language::TYPES[method_name.to_sym]
18
18
  return super unless entity_class
19
19
 
20
- entity_class.new(*arguments)
20
+ entity_class.new(*args, **kwargs, &)
21
21
  end
22
22
 
23
23
  # Let the current class have functions which can build a given entity by calling it's type. For example
@@ -7,12 +7,14 @@
7
7
  require 'racc/parser.rb'
8
8
 
9
9
  require_relative '../lexer'
10
+ require_relative '../language/ast_builder'
10
11
 
11
12
  module CSVPlusPlus
12
13
  module Language
13
14
  class CellValueParser < Racc::Parser
14
15
 
15
16
  module_eval(<<'...end cell_value.y/module_eval...', 'cell_value.y', 48)
17
+ include ::CSVPlusPlus::Language::ASTBuilder
16
18
  include ::CSVPlusPlus::Lexer
17
19
 
18
20
  protected
@@ -31,15 +33,16 @@ module_eval(<<'...end cell_value.y/module_eval...', 'cell_value.y', 48)
31
33
 
32
34
  def tokenizer
33
35
  ::CSVPlusPlus::Lexer::Tokenizer.new(
34
- catchall: /[\(\)\/\*\+\-,=&]/,
36
+ catchall: /[\{\}\(\),=]/,
35
37
  ignore: /\s+/,
36
38
  tokens: [
37
- [/true/i, :TRUE],
38
- [/false/i, :FALSE],
39
- [/"(?:[^"\\]|\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4}))*"/, :STRING],
40
- [/-?[\d.]+/, :NUMBER],
41
- [/\$\$/, :VAR_REF],
42
- [/[\$\w_]+/, :ID]
39
+ TOKEN_LIBRARY[:TRUE],
40
+ TOKEN_LIBRARY[:FALSE],
41
+ TOKEN_LIBRARY[:NUMBER],
42
+ TOKEN_LIBRARY[:STRING],
43
+ TOKEN_LIBRARY[:INFIX_OP],
44
+ TOKEN_LIBRARY[:VAR_REF],
45
+ TOKEN_LIBRARY[:ID]
43
46
  ]
44
47
  )
45
48
  end
@@ -47,108 +50,99 @@ module_eval(<<'...end cell_value.y/module_eval...', 'cell_value.y', 48)
47
50
  ##### State transition tables begin ###
48
51
 
49
52
  racc_action_table = [
50
- 33, 16, 17, 20, 18, 19, 15, 7, 16, 17,
51
- 20, 18, 19, 7, 34, 12, 13, 10, 9, 11,
52
- 8, 12, 13, 10, 9, 11, 8, 7, 16, 17,
53
- 20, 18, 19, 7, 2, 12, 13, 10, 9, 11,
54
- 8, 12, 13, 10, 9, 11, 8, 7, 16, 17,
55
- 20, 3, 14, 7, 22, 12, 13, 10, 9, 11,
56
- 8, 12, 13, 10, 9, 11, 8, 7, 16, 17,
57
- 20, 23, 16, 7, 31, 12, 13, 10, 9, 11,
58
- 8, 12, 13, 10, 9, 11, 8, 7, 29, 16,
59
- 17, 20, 18, 19, 16, 12, 13, 10, 9, 11,
60
- 8 ]
53
+ 7, 21, 15, 25, 2, 16, 3, 7, 14, 18,
54
+ 19, 16, 16, 16, 7, 12, 13, 16, 10, 9,
55
+ 11, 8, 12, 13, 26, 10, 9, 11, 8, 12,
56
+ 13, nil, 10, 9, 11, 8, 7, 23, nil, nil,
57
+ nil, nil, nil, 7, nil, nil, nil, nil, nil, nil,
58
+ nil, 12, 13, nil, 10, 9, 11, 8, 12, 13,
59
+ nil, 10, 9, 11, 8 ]
61
60
 
62
61
  racc_action_check = [
63
- 30, 4, 4, 4, 4, 4, 4, 2, 32, 32,
64
- 32, 32, 32, 7, 30, 2, 2, 2, 2, 2,
65
- 2, 7, 7, 7, 7, 7, 7, 16, 35, 35,
66
- 35, 35, 35, 17, 0, 16, 16, 16, 16, 16,
67
- 16, 17, 17, 17, 17, 17, 17, 18, 26, 26,
68
- 26, 1, 3, 19, 8, 18, 18, 18, 18, 18,
69
- 18, 19, 19, 19, 19, 19, 19, 20, 27, 27,
70
- 27, 13, 25, 23, 23, 20, 20, 20, 20, 20,
71
- 20, 23, 23, 23, 23, 23, 23, 34, 21, 21,
72
- 21, 21, 21, 21, 28, 34, 34, 34, 34, 34,
73
- 34 ]
62
+ 2, 17, 4, 22, 0, 4, 1, 7, 3, 8,
63
+ 13, 20, 24, 27, 16, 2, 2, 17, 2, 2,
64
+ 2, 2, 7, 7, 22, 7, 7, 7, 7, 16,
65
+ 16, nil, 16, 16, 16, 16, 19, 19, nil, nil,
66
+ nil, nil, nil, 26, nil, nil, nil, nil, nil, nil,
67
+ nil, 19, 19, nil, 19, 19, 19, 19, 26, 26,
68
+ nil, 26, 26, 26, 26 ]
74
69
 
75
70
  racc_action_pointer = [
76
- 18, 51, 5, 52, -3, nil, nil, 11, 43, nil,
77
- nil, nil, nil, 69, nil, nil, 25, 31, 45, 51,
78
- 65, 85, nil, 71, nil, 68, 44, 64, 90, nil,
79
- -3, nil, 4, nil, 85, 24 ]
71
+ -6, 6, -2, 8, -14, nil, nil, 5, -9, nil,
72
+ nil, nil, nil, 8, nil, nil, 12, -2, nil, 34,
73
+ -8, nil, 0, nil, -7, nil, 41, -6 ]
80
74
 
81
75
  racc_action_default = [
82
- -20, -20, -20, -20, -20, -2, -3, -20, -20, -6,
83
- -7, -8, -9, -10, 36, -1, -20, -20, -20, -20,
84
- -20, -20, -5, -20, -15, -16, -17, -18, -19, -4,
85
- -20, -12, -14, -11, -20, -13 ]
76
+ -16, -16, -16, -16, -16, -2, -3, -16, -16, -6,
77
+ -7, -8, -9, -10, 28, -1, -16, -16, -5, -16,
78
+ -15, -4, -16, -12, -14, -11, -16, -13 ]
86
79
 
87
80
  racc_goto_table = [
88
- 4, 1, 30, nil, nil, 21, nil, nil, nil, nil,
89
- nil, nil, nil, nil, 24, 25, 26, 27, 28, nil,
90
- nil, 32, nil, nil, nil, nil, nil, nil, nil, nil,
91
- nil, nil, 35 ]
81
+ 4, 1, 22, nil, nil, 17, nil, nil, nil, nil,
82
+ nil, nil, nil, nil, 20, nil, nil, 24, nil, nil,
83
+ nil, nil, nil, nil, 27 ]
92
84
 
93
85
  racc_goto_check = [
94
86
  2, 1, 5, nil, nil, 2, nil, nil, nil, nil,
95
- nil, nil, nil, nil, 2, 2, 2, 2, 2, nil,
96
- nil, 2, nil, nil, nil, nil, nil, nil, nil, nil,
97
- nil, nil, 2 ]
87
+ nil, nil, nil, nil, 2, nil, nil, 2, nil, nil,
88
+ nil, nil, nil, nil, 2 ]
98
89
 
99
90
  racc_goto_pointer = [
100
- nil, 1, -2, nil, nil, -21 ]
91
+ nil, 1, -2, nil, nil, -17 ]
101
92
 
102
93
  racc_goto_default = [
103
94
  nil, nil, nil, 5, 6, nil ]
104
95
 
105
96
  racc_reduce_table = [
106
97
  0, 0, :racc_error,
107
- 3, 19, :_reduce_1,
108
- 1, 20, :_reduce_none,
109
- 1, 20, :_reduce_none,
110
- 3, 20, :_reduce_4,
111
- 2, 20, :_reduce_5,
112
- 1, 20, :_reduce_6,
113
- 1, 20, :_reduce_7,
114
- 1, 20, :_reduce_8,
115
- 1, 20, :_reduce_9,
116
- 1, 20, :_reduce_10,
117
- 4, 21, :_reduce_11,
118
- 3, 21, :_reduce_12,
119
- 3, 23, :_reduce_13,
120
- 1, 23, :_reduce_14,
121
- 3, 22, :_reduce_15,
122
- 3, 22, :_reduce_16,
123
- 3, 22, :_reduce_17,
124
- 3, 22, :_reduce_18,
125
- 3, 22, :_reduce_19 ]
126
-
127
- racc_reduce_n = 20
128
-
129
- racc_shift_n = 36
98
+ 3, 26, :_reduce_1,
99
+ 1, 27, :_reduce_none,
100
+ 1, 27, :_reduce_none,
101
+ 3, 27, :_reduce_4,
102
+ 2, 27, :_reduce_5,
103
+ 1, 27, :_reduce_6,
104
+ 1, 27, :_reduce_7,
105
+ 1, 27, :_reduce_8,
106
+ 1, 27, :_reduce_9,
107
+ 1, 27, :_reduce_10,
108
+ 4, 28, :_reduce_11,
109
+ 3, 28, :_reduce_12,
110
+ 3, 30, :_reduce_13,
111
+ 1, 30, :_reduce_14,
112
+ 3, 29, :_reduce_15 ]
113
+
114
+ racc_reduce_n = 16
115
+
116
+ racc_shift_n = 28
130
117
 
131
118
  racc_token_table = {
132
119
  false => 0,
133
120
  :error => 1,
134
121
  "(" => 2,
135
122
  ")" => 3,
136
- "&" => 4,
123
+ "^" => 4,
137
124
  "*" => 5,
138
125
  "/" => 6,
139
126
  "+" => 7,
140
127
  "-" => 8,
141
- :EOL => 9,
142
- :FALSE => 10,
143
- :ID => 11,
144
- :NUMBER => 12,
145
- :STRING => 13,
146
- :TRUE => 14,
147
- :VAR_REF => 15,
148
- "=" => 16,
149
- "," => 17 }
150
-
151
- racc_nt_base = 18
128
+ "&" => 9,
129
+ "=" => 10,
130
+ "<" => 11,
131
+ ">" => 12,
132
+ "<=" => 13,
133
+ ">=" => 14,
134
+ "<>" => 15,
135
+ :EOL => 16,
136
+ :FALSE => 17,
137
+ :ID => 18,
138
+ :INFIX_OP => 19,
139
+ :NUMBER => 20,
140
+ :STRING => 21,
141
+ :TRUE => 22,
142
+ :VAR_REF => 23,
143
+ "," => 24 }
144
+
145
+ racc_nt_base = 25
152
146
 
153
147
  racc_use_result_var = true
154
148
 
@@ -173,19 +167,26 @@ Racc_token_to_s_table = [
173
167
  "error",
174
168
  "\"(\"",
175
169
  "\")\"",
176
- "\"&\"",
170
+ "\"^\"",
177
171
  "\"*\"",
178
172
  "\"/\"",
179
173
  "\"+\"",
180
174
  "\"-\"",
175
+ "\"&\"",
176
+ "\"=\"",
177
+ "\"<\"",
178
+ "\">\"",
179
+ "\"<=\"",
180
+ "\">=\"",
181
+ "\"<>\"",
181
182
  "EOL",
182
183
  "FALSE",
183
184
  "ID",
185
+ "INFIX_OP",
184
186
  "NUMBER",
185
187
  "STRING",
186
188
  "TRUE",
187
189
  "VAR_REF",
188
- "\"=\"",
189
190
  "\",\"",
190
191
  "$start",
191
192
  "cell_value",
@@ -200,7 +201,7 @@ Racc_debug_parser = false
200
201
 
201
202
  # reduce 0 omitted
202
203
 
203
- module_eval(<<'.,.,', 'cell_value.y', 17)
204
+ module_eval(<<'.,.,', 'cell_value.y', 20)
204
205
  def _reduce_1(val, _values, result)
205
206
  @ast = val[1]
206
207
  result
@@ -211,114 +212,86 @@ module_eval(<<'.,.,', 'cell_value.y', 17)
211
212
 
212
213
  # reduce 3 omitted
213
214
 
214
- module_eval(<<'.,.,', 'cell_value.y', 21)
215
+ module_eval(<<'.,.,', 'cell_value.y', 24)
215
216
  def _reduce_4(val, _values, result)
216
217
  result = val[1]
217
218
  result
218
219
  end
219
220
  .,.,
220
221
 
221
- module_eval(<<'.,.,', 'cell_value.y', 22)
222
+ module_eval(<<'.,.,', 'cell_value.y', 25)
222
223
  def _reduce_5(val, _values, result)
223
- result = e(:variable, val[1])
224
+ result = variable(val[1])
224
225
  result
225
226
  end
226
227
  .,.,
227
228
 
228
- module_eval(<<'.,.,', 'cell_value.y', 23)
229
+ module_eval(<<'.,.,', 'cell_value.y', 26)
229
230
  def _reduce_6(val, _values, result)
230
- result = e(:string, val[0])
231
+ result = string(val[0])
231
232
  result
232
233
  end
233
234
  .,.,
234
235
 
235
- module_eval(<<'.,.,', 'cell_value.y', 24)
236
+ module_eval(<<'.,.,', 'cell_value.y', 27)
236
237
  def _reduce_7(val, _values, result)
237
- result = e(:number, val[0])
238
+ result = number(val[0])
238
239
  result
239
240
  end
240
241
  .,.,
241
242
 
242
- module_eval(<<'.,.,', 'cell_value.y', 25)
243
+ module_eval(<<'.,.,', 'cell_value.y', 28)
243
244
  def _reduce_8(val, _values, result)
244
- result = e(:boolean, true)
245
+ result = boolean(true)
245
246
  result
246
247
  end
247
248
  .,.,
248
249
 
249
- module_eval(<<'.,.,', 'cell_value.y', 26)
250
+ module_eval(<<'.,.,', 'cell_value.y', 29)
250
251
  def _reduce_9(val, _values, result)
251
- result = e(:boolean, false)
252
+ result = boolean(false)
252
253
  result
253
254
  end
254
255
  .,.,
255
256
 
256
- module_eval(<<'.,.,', 'cell_value.y', 27)
257
+ module_eval(<<'.,.,', 'cell_value.y', 30)
257
258
  def _reduce_10(val, _values, result)
258
- result = e(:cell_reference, val[0])
259
+ result = cell_reference(val[0])
259
260
  result
260
261
  end
261
262
  .,.,
262
263
 
263
- module_eval(<<'.,.,', 'cell_value.y', 29)
264
+ module_eval(<<'.,.,', 'cell_value.y', 32)
264
265
  def _reduce_11(val, _values, result)
265
- result = e(:function_call, val[0], val[2])
266
+ result = function_call(val[0], val[2])
266
267
  result
267
268
  end
268
269
  .,.,
269
270
 
270
- module_eval(<<'.,.,', 'cell_value.y', 30)
271
+ module_eval(<<'.,.,', 'cell_value.y', 33)
271
272
  def _reduce_12(val, _values, result)
272
- result = e(:function_call, val[0], [])
273
+ result = function_call(val[0], [])
273
274
  result
274
275
  end
275
276
  .,.,
276
277
 
277
- module_eval(<<'.,.,', 'cell_value.y', 32)
278
+ module_eval(<<'.,.,', 'cell_value.y', 35)
278
279
  def _reduce_13(val, _values, result)
279
280
  result = val[0] << val[2]
280
281
  result
281
282
  end
282
283
  .,.,
283
284
 
284
- module_eval(<<'.,.,', 'cell_value.y', 33)
285
+ module_eval(<<'.,.,', 'cell_value.y', 36)
285
286
  def _reduce_14(val, _values, result)
286
287
  result = [val[0]]
287
288
  result
288
289
  end
289
290
  .,.,
290
291
 
291
- module_eval(<<'.,.,', 'cell_value.y', 35)
292
- def _reduce_15(val, _values, result)
293
- result = e(:function_call, :concat, [val[0], val[2]])
294
- result
295
- end
296
- .,.,
297
-
298
- module_eval(<<'.,.,', 'cell_value.y', 36)
299
- def _reduce_16(val, _values, result)
300
- result = e(:function_call, :multiply, [val[0], val[2]])
301
- result
302
- end
303
- .,.,
304
-
305
- module_eval(<<'.,.,', 'cell_value.y', 37)
306
- def _reduce_17(val, _values, result)
307
- result = e(:function_call, :add, [val[0], val[2]])
308
- result
309
- end
310
- .,.,
311
-
312
292
  module_eval(<<'.,.,', 'cell_value.y', 38)
313
- def _reduce_18(val, _values, result)
314
- result = e(:function_call, :minus, [val[0], val[2]])
315
- result
316
- end
317
- .,.,
318
-
319
- module_eval(<<'.,.,', 'cell_value.y', 39)
320
- def _reduce_19(val, _values, result)
321
- result = e(:function_call, :divide, [val[0], val[2]])
293
+ def _reduce_15(val, _values, result)
294
+ result = function_call(val[1], [val[0], val[2]], infix: true)
322
295
  result
323
296
  end
324
297
  .,.,
@@ -6,15 +6,17 @@
6
6
 
7
7
  require 'racc/parser.rb'
8
8
 
9
- require_relative '../lexer'
10
- require_relative '../code_section'
9
+ require_relative '../lexer'
10
+ require_relative '../code_section'
11
+ require_relative '../language/ast_builder'
11
12
 
12
13
  module CSVPlusPlus
13
14
  module Language
14
15
  class CodeSectionParser < Racc::Parser
15
16
 
16
- module_eval(<<'...end code_section.y/module_eval...', 'code_section.y', 67)
17
+ module_eval(<<'...end code_section.y/module_eval...', 'code_section.y', 71)
17
18
  include ::CSVPlusPlus::Lexer
19
+ include ::CSVPlusPlus::Language::ASTBuilder
18
20
 
19
21
  def initialize
20
22
  super
@@ -35,7 +37,7 @@ module_eval(<<'...end code_section.y/module_eval...', 'code_section.y', 67)
35
37
 
36
38
  def tokenizer
37
39
  ::CSVPlusPlus::Lexer::Tokenizer.new(
38
- catchall: /[\(\)\{\}\/\*\+\-,=&]/,
40
+ catchall: /[\{\}\(\),]/, # TODO: do I even need this (oh I think brackets are for arrays
39
41
  ignore: /\s+|\#[^\n]+\n/,
40
42
  stop_fn: lambda do |scanner|
41
43
  return false unless scanner.scan(/#{::CSVPlusPlus::Lexer::END_OF_CODE_SECTION}/)
@@ -45,15 +47,16 @@ module_eval(<<'...end code_section.y/module_eval...', 'code_section.y', 67)
45
47
  true
46
48
  end,
47
49
  tokens: [
48
- [/\n/, :EOL],
50
+ [/\n/, :EOL], # XXX do I need this?
49
51
  [/:=/, :ASSIGN],
50
- [/\bdef\b/, :FN_DEF],
51
- [/\bTRUE\b/i, :TRUE],
52
- [/\bFALSE\b/i, :FALSE],
53
- [/"(?:[^"\\]|\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4}))*"/, :STRING],
54
- [/-?[\d.]+/, :NUMBER],
55
- [/\$\$/, :VAR_REF],
56
- [/[!:\w_]+/, :ID],
52
+ [/def/, :FN_DEF],
53
+ TOKEN_LIBRARY[:TRUE],
54
+ TOKEN_LIBRARY[:FALSE],
55
+ TOKEN_LIBRARY[:NUMBER],
56
+ TOKEN_LIBRARY[:STRING],
57
+ TOKEN_LIBRARY[:INFIX_OP],
58
+ TOKEN_LIBRARY[:VAR_REF],
59
+ TOKEN_LIBRARY[:ID]
57
60
  ],
58
61
  )
59
62
  end
@@ -64,12 +67,8 @@ module_eval(<<'...end code_section.y/module_eval...', 'code_section.y', 67)
64
67
 
65
68
  private
66
69
 
67
- def e(type, *entity_args)
68
- ::CSVPlusPlus::Language::TYPES[type].new(*entity_args)
69
- end
70
-
71
70
  def def_function(id, arguments, body)
72
- fn_def = e(:function, id, arguments, body)
71
+ fn_def = function(id, arguments, body)
73
72
  @code_section.def_function(fn_def.id, fn_def)
74
73
  end
75
74
 
@@ -80,112 +79,91 @@ module_eval(<<'...end code_section.y/module_eval...', 'code_section.y', 67)
80
79
  ##### State transition tables begin ###
81
80
 
82
81
  racc_action_table = [
83
- 45, 27, 3, 37, 51, 7, 38, 52, 28, 9,
84
- 19, 8, 29, 30, 31, 32, 33, 24, 25, 22,
85
- 21, 23, 20, 19, 29, 30, 31, 32, 33, 19,
86
- 24, 25, 22, 21, 23, 20, 24, 25, 22, 21,
87
- 23, 20, 19, 29, 30, 31, 32, 33, 19, 24,
88
- 25, 22, 21, 23, 20, 24, 25, 22, 21, 23,
89
- 20, 19, 29, 30, 31, 32, 33, 19, 24, 25,
90
- 22, 21, 23, 20, 24, 25, 22, 21, 23, 20,
91
- 19, 29, 30, 31, 32, 33, 12, 24, 25, 22,
92
- 21, 23, 20, 19, 48, 13, 14, 15, 35, 19,
93
- 24, 25, 22, 21, 23, 20, 24, 25, 22, 21,
94
- 23, 20, 19, 29, 30, 31, 32, 33, 36, 24,
95
- 25, 22, 21, 23, 20, 10, 50, nil, 7, 29,
96
- 30, 31, 32, 33, 8, 29, 30, 31, 32, 33,
97
- 29, 30, 31, 32, 33, 29, 30, 31, 32, 33,
98
- 29, 30, 31, 32, 33 ]
82
+ 20, 38, 35, 9, 12, 13, 14, 20, 16, 31,
83
+ 33, 34, 31, 42, 20, 31, 29, 36, 25, 26,
84
+ 31, 23, 22, 24, 21, 25, 26, 20, 23, 22,
85
+ 24, 21, 25, 26, 30, 23, 22, 24, 21, 20,
86
+ 41, 31, 31, nil, 43, 25, 26, 20, 23, 22,
87
+ 24, 21, 3, 10, nil, 7, 7, 25, 26, 44,
88
+ 23, 22, 24, 21, nil, 25, 26, nil, 23, 22,
89
+ 24, 21, 8, 8 ]
99
90
 
100
91
  racc_action_check = [
101
- 34, 15, 0, 26, 47, 0, 26, 47, 15, 1,
102
- 13, 0, 34, 34, 34, 34, 34, 13, 13, 13,
103
- 13, 13, 13, 19, 16, 16, 16, 16, 16, 27,
104
- 19, 19, 19, 19, 19, 19, 27, 27, 27, 27,
105
- 27, 27, 29, 39, 39, 39, 39, 39, 30, 29,
106
- 29, 29, 29, 29, 29, 30, 30, 30, 30, 30,
107
- 30, 31, 40, 40, 40, 40, 40, 32, 31, 31,
108
- 31, 31, 31, 31, 32, 32, 32, 32, 32, 32,
109
- 33, 41, 41, 41, 41, 41, 7, 33, 33, 33,
110
- 33, 33, 33, 36, 36, 8, 9, 12, 20, 37,
111
- 36, 36, 36, 36, 36, 36, 37, 37, 37, 37,
112
- 37, 37, 52, 42, 42, 42, 42, 42, 25, 52,
113
- 52, 52, 52, 52, 52, 2, 38, nil, 2, 43,
114
- 43, 43, 43, 43, 2, 44, 44, 44, 44, 44,
115
- 46, 46, 46, 46, 46, 49, 49, 49, 49, 49,
116
- 53, 53, 53, 53, 53 ]
92
+ 13, 32, 28, 1, 7, 8, 9, 15, 12, 17,
93
+ 21, 26, 27, 36, 20, 37, 16, 28, 13, 13,
94
+ 32, 13, 13, 13, 13, 15, 15, 31, 15, 15,
95
+ 15, 15, 20, 20, 16, 20, 20, 20, 20, 34,
96
+ 34, 39, 45, nil, 40, 31, 31, 44, 31, 31,
97
+ 31, 31, 0, 2, nil, 0, 2, 34, 34, 40,
98
+ 34, 34, 34, 34, nil, 44, 44, nil, 44, 44,
99
+ 44, 44, 0, 2 ]
117
100
 
118
101
  racc_action_pointer = [
119
- 0, 9, 123, nil, nil, nil, nil, 75, 89, 96,
120
- nil, nil, 94, 7, nil, -3, 8, nil, nil, 20,
121
- 87, nil, nil, nil, nil, 115, -1, 26, nil, 39,
122
- 45, 58, 64, 77, -4, nil, 90, 96, 115, 27,
123
- 46, 65, 97, 113, 119, nil, 124, 0, nil, 129,
124
- nil, nil, 109, 134 ]
102
+ 50, 3, 51, nil, nil, nil, nil, -18, -1, 6,
103
+ nil, nil, 5, -3, nil, 4, 12, -14, nil, nil,
104
+ 11, -12, nil, nil, nil, nil, 8, -11, -2, nil,
105
+ nil, 24, -3, nil, 36, nil, -9, -8, nil, 18,
106
+ 40, nil, nil, nil, 44, 19 ]
125
107
 
126
108
  racc_action_default = [
127
- -30, -30, -30, -2, -4, -5, -6, -30, -30, -30,
128
- -1, -3, -30, -30, 54, -30, -11, -12, -13, -30,
129
- -30, -16, -17, -18, -19, -20, -30, -30, -10, -30,
130
- -30, -30, -30, -30, -30, -15, -30, -30, -30, -8,
131
- -21, -22, -23, -24, -25, -14, -29, -30, -27, -7,
132
- -9, -26, -30, -28 ]
109
+ -27, -27, -27, -2, -4, -5, -6, -27, -27, -27,
110
+ -1, -3, -27, -27, 46, -27, -27, -12, -13, -14,
111
+ -27, -27, -17, -18, -19, -20, -21, -7, -27, -9,
112
+ -11, -27, -27, -16, -27, -8, -27, -22, -15, -26,
113
+ -27, -24, -10, -23, -27, -25 ]
133
114
 
134
115
  racc_goto_table = [
135
- 16, 4, 1, 11, 2, 26, 34, 47, nil, nil,
136
- nil, nil, nil, nil, 39, nil, 40, 41, 42, 43,
137
- 44, nil, nil, 46, 49, nil, nil, nil, nil, nil,
138
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 53 ]
116
+ 17, 4, 27, 11, 1, 2, 15, 32, 28, 40,
117
+ nil, nil, nil, nil, nil, nil, nil, nil, 37, nil,
118
+ nil, 39, nil, nil, nil, nil, nil, nil, nil, nil,
119
+ nil, 45 ]
139
120
 
140
121
  racc_goto_check = [
141
- 7, 3, 1, 3, 2, 6, 7, 10, nil, nil,
142
- nil, nil, nil, nil, 7, nil, 7, 7, 7, 7,
143
- 7, nil, nil, 7, 7, nil, nil, nil, nil, nil,
144
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 7 ]
122
+ 7, 3, 7, 3, 1, 2, 6, 7, 8, 11,
123
+ nil, nil, nil, nil, nil, nil, nil, nil, 7, nil,
124
+ nil, 7, nil, nil, nil, nil, nil, nil, nil, nil,
125
+ nil, 7 ]
145
126
 
146
127
  racc_goto_pointer = [
147
- nil, 2, 4, 1, nil, nil, -10, -13, nil, nil,
148
- -29 ]
128
+ nil, 4, 5, 1, nil, nil, -6, -13, -8, nil,
129
+ nil, -25 ]
149
130
 
150
131
  racc_goto_default = [
151
- nil, nil, nil, nil, 5, 6, nil, nil, 17, 18,
152
- nil ]
132
+ nil, nil, nil, nil, 5, 6, nil, nil, nil, 18,
133
+ 19, nil ]
153
134
 
154
135
  racc_reduce_table = [
155
136
  0, 0, :racc_error,
156
- 2, 22, :_reduce_none,
157
- 1, 22, :_reduce_none,
158
- 2, 23, :_reduce_none,
159
- 1, 23, :_reduce_none,
160
- 1, 24, :_reduce_none,
161
- 1, 24, :_reduce_none,
162
- 6, 25, :_reduce_7,
163
- 5, 25, :_reduce_8,
164
- 3, 27, :_reduce_9,
165
- 1, 27, :_reduce_10,
166
- 3, 26, :_reduce_11,
167
- 1, 28, :_reduce_none,
168
- 1, 28, :_reduce_none,
169
- 3, 28, :_reduce_14,
170
- 2, 28, :_reduce_15,
171
- 1, 28, :_reduce_16,
172
- 1, 28, :_reduce_17,
173
- 1, 28, :_reduce_18,
174
- 1, 28, :_reduce_19,
175
- 1, 28, :_reduce_20,
176
- 3, 30, :_reduce_21,
177
- 3, 30, :_reduce_22,
178
- 3, 30, :_reduce_23,
179
- 3, 30, :_reduce_24,
180
- 3, 30, :_reduce_25,
181
- 4, 29, :_reduce_26,
182
- 3, 29, :_reduce_27,
183
- 3, 31, :_reduce_28,
184
- 1, 31, :_reduce_29 ]
185
-
186
- racc_reduce_n = 30
187
-
188
- racc_shift_n = 54
137
+ 2, 29, :_reduce_none,
138
+ 1, 29, :_reduce_none,
139
+ 2, 30, :_reduce_none,
140
+ 1, 30, :_reduce_none,
141
+ 1, 31, :_reduce_none,
142
+ 1, 31, :_reduce_none,
143
+ 4, 32, :_reduce_7,
144
+ 3, 34, :_reduce_8,
145
+ 2, 34, :_reduce_9,
146
+ 3, 36, :_reduce_10,
147
+ 1, 36, :_reduce_11,
148
+ 3, 33, :_reduce_12,
149
+ 1, 35, :_reduce_none,
150
+ 1, 35, :_reduce_none,
151
+ 3, 35, :_reduce_15,
152
+ 2, 35, :_reduce_16,
153
+ 1, 35, :_reduce_17,
154
+ 1, 35, :_reduce_18,
155
+ 1, 35, :_reduce_19,
156
+ 1, 35, :_reduce_20,
157
+ 1, 35, :_reduce_21,
158
+ 3, 38, :_reduce_22,
159
+ 4, 37, :_reduce_23,
160
+ 3, 37, :_reduce_24,
161
+ 3, 39, :_reduce_25,
162
+ 1, 39, :_reduce_26 ]
163
+
164
+ racc_reduce_n = 27
165
+
166
+ racc_shift_n = 46
189
167
 
190
168
  racc_token_table = {
191
169
  false => 0,
@@ -195,22 +173,29 @@ racc_token_table = {
195
173
  ")" => 4,
196
174
  :FN_DEF => 5,
197
175
  :ASSIGN => 6,
198
- "," => 7,
199
- :CELL_REF => 8,
200
- :EOL => 9,
201
- :FALSE => 10,
202
- :ID => 11,
203
- :NUMBER => 12,
204
- :STRING => 13,
205
- :TRUE => 14,
206
- :VAR_REF => 15,
207
- "&" => 16,
208
- "*" => 17,
209
- "+" => 18,
210
- "-" => 19,
211
- "/" => 20 }
212
-
213
- racc_nt_base = 21
176
+ "^" => 7,
177
+ "*" => 8,
178
+ "/" => 9,
179
+ "+" => 10,
180
+ "-" => 11,
181
+ "&" => 12,
182
+ "=" => 13,
183
+ "<" => 14,
184
+ ">" => 15,
185
+ "<=" => 16,
186
+ ">=" => 17,
187
+ "<>" => 18,
188
+ "," => 19,
189
+ :EOL => 20,
190
+ :FALSE => 21,
191
+ :ID => 22,
192
+ :INFIX_OP => 23,
193
+ :NUMBER => 24,
194
+ :STRING => 25,
195
+ :TRUE => 26,
196
+ :VAR_REF => 27 }
197
+
198
+ racc_nt_base = 28
214
199
 
215
200
  racc_use_result_var = true
216
201
 
@@ -238,28 +223,36 @@ Racc_token_to_s_table = [
238
223
  "\")\"",
239
224
  "FN_DEF",
240
225
  "ASSIGN",
226
+ "\"^\"",
227
+ "\"*\"",
228
+ "\"/\"",
229
+ "\"+\"",
230
+ "\"-\"",
231
+ "\"&\"",
232
+ "\"=\"",
233
+ "\"<\"",
234
+ "\">\"",
235
+ "\"<=\"",
236
+ "\">=\"",
237
+ "\"<>\"",
241
238
  "\",\"",
242
- "CELL_REF",
243
239
  "EOL",
244
240
  "FALSE",
245
241
  "ID",
242
+ "INFIX_OP",
246
243
  "NUMBER",
247
244
  "STRING",
248
245
  "TRUE",
249
246
  "VAR_REF",
250
- "\"&\"",
251
- "\"*\"",
252
- "\"+\"",
253
- "\"-\"",
254
- "\"/\"",
255
247
  "$start",
256
248
  "code_section",
257
249
  "code",
258
250
  "def",
259
251
  "fn_def",
260
252
  "var_def",
261
- "fn_def_args",
253
+ "fn_def_args_or_not",
262
254
  "exp",
255
+ "fn_def_args",
263
256
  "fn_call",
264
257
  "infix_fn_call",
265
258
  "fn_call_args" ]
@@ -282,152 +275,131 @@ Racc_debug_parser = false
282
275
 
283
276
  # reduce 6 omitted
284
277
 
285
- module_eval(<<'.,.,', 'code_section.y', 29)
278
+ module_eval(<<'.,.,', 'code_section.y', 34)
286
279
  def _reduce_7(val, _values, result)
287
- def_function(val[1], val[3], val[5])
280
+ def_function(val[1], val[2], val[3])
288
281
  result
289
282
  end
290
283
  .,.,
291
284
 
292
- module_eval(<<'.,.,', 'code_section.y', 30)
285
+ module_eval(<<'.,.,', 'code_section.y', 36)
293
286
  def _reduce_8(val, _values, result)
294
- def_function(val[1], [], val[4])
287
+ result = val[1]
295
288
  result
296
289
  end
297
290
  .,.,
298
291
 
299
- module_eval(<<'.,.,', 'code_section.y', 32)
292
+ module_eval(<<'.,.,', 'code_section.y', 37)
300
293
  def _reduce_9(val, _values, result)
301
- result = val[0] << val[2]
294
+ result = []
302
295
  result
303
296
  end
304
297
  .,.,
305
298
 
306
- module_eval(<<'.,.,', 'code_section.y', 33)
299
+ module_eval(<<'.,.,', 'code_section.y', 39)
307
300
  def _reduce_10(val, _values, result)
308
- result = [val[0]]
301
+ result = val[0] << val[2]
309
302
  result
310
303
  end
311
304
  .,.,
312
305
 
313
- module_eval(<<'.,.,', 'code_section.y', 35)
306
+ module_eval(<<'.,.,', 'code_section.y', 40)
314
307
  def _reduce_11(val, _values, result)
315
- def_variable(val[0], val[2])
308
+ result = [val[0]]
316
309
  result
317
310
  end
318
311
  .,.,
319
312
 
320
- # reduce 12 omitted
321
-
322
- # reduce 13 omitted
323
-
324
- module_eval(<<'.,.,', 'code_section.y', 39)
325
- def _reduce_14(val, _values, result)
326
- result = val[1]
313
+ module_eval(<<'.,.,', 'code_section.y', 42)
314
+ def _reduce_12(val, _values, result)
315
+ def_variable(val[0], val[2])
327
316
  result
328
317
  end
329
318
  .,.,
330
319
 
331
- module_eval(<<'.,.,', 'code_section.y', 40)
320
+ # reduce 13 omitted
321
+
322
+ # reduce 14 omitted
323
+
324
+ module_eval(<<'.,.,', 'code_section.y', 46)
332
325
  def _reduce_15(val, _values, result)
333
- result = e(:variable, val[1])
326
+ result = val[1]
334
327
  result
335
328
  end
336
329
  .,.,
337
330
 
338
- module_eval(<<'.,.,', 'code_section.y', 41)
331
+ module_eval(<<'.,.,', 'code_section.y', 47)
339
332
  def _reduce_16(val, _values, result)
340
- result = e(:string, val[0])
333
+ result = variable(val[1])
341
334
  result
342
335
  end
343
336
  .,.,
344
337
 
345
- module_eval(<<'.,.,', 'code_section.y', 42)
338
+ module_eval(<<'.,.,', 'code_section.y', 48)
346
339
  def _reduce_17(val, _values, result)
347
- result = e(:number, val[0])
340
+ result = string(val[0])
348
341
  result
349
342
  end
350
343
  .,.,
351
344
 
352
- module_eval(<<'.,.,', 'code_section.y', 43)
345
+ module_eval(<<'.,.,', 'code_section.y', 49)
353
346
  def _reduce_18(val, _values, result)
354
- result = e(:boolean, true)
347
+ result = number(val[0])
355
348
  result
356
349
  end
357
350
  .,.,
358
351
 
359
- module_eval(<<'.,.,', 'code_section.y', 44)
352
+ module_eval(<<'.,.,', 'code_section.y', 50)
360
353
  def _reduce_19(val, _values, result)
361
- result = e(:boolean, false)
354
+ result = boolean(true)
362
355
  result
363
356
  end
364
357
  .,.,
365
358
 
366
- module_eval(<<'.,.,', 'code_section.y', 45)
359
+ module_eval(<<'.,.,', 'code_section.y', 51)
367
360
  def _reduce_20(val, _values, result)
368
- result = e(:cell_reference, val[0])
361
+ result = boolean(false)
369
362
  result
370
363
  end
371
364
  .,.,
372
365
 
373
- module_eval(<<'.,.,', 'code_section.y', 47)
366
+ module_eval(<<'.,.,', 'code_section.y', 52)
374
367
  def _reduce_21(val, _values, result)
375
- result = e(:function_call, :concat, [val[0], val[2]])
368
+ result = cell_reference(val[0])
376
369
  result
377
370
  end
378
371
  .,.,
379
372
 
380
- module_eval(<<'.,.,', 'code_section.y', 48)
373
+ module_eval(<<'.,.,', 'code_section.y', 54)
381
374
  def _reduce_22(val, _values, result)
382
- result = e(:function_call, :multiply, [val[0], val[2]])
375
+ result = function_call(val[1], [val[0], val[2]], infix: true)
383
376
  result
384
377
  end
385
378
  .,.,
386
379
 
387
- module_eval(<<'.,.,', 'code_section.y', 49)
380
+ module_eval(<<'.,.,', 'code_section.y', 56)
388
381
  def _reduce_23(val, _values, result)
389
- result = e(:function_call, :add, [val[0], val[2]])
382
+ result = function_call(val[0], val[2])
390
383
  result
391
384
  end
392
385
  .,.,
393
386
 
394
- module_eval(<<'.,.,', 'code_section.y', 50)
387
+ module_eval(<<'.,.,', 'code_section.y', 57)
395
388
  def _reduce_24(val, _values, result)
396
- result = e(:function_call, :minus, [val[0], val[2]])
389
+ result = function_call(val[0], [])
397
390
  result
398
391
  end
399
392
  .,.,
400
393
 
401
- module_eval(<<'.,.,', 'code_section.y', 51)
394
+ module_eval(<<'.,.,', 'code_section.y', 59)
402
395
  def _reduce_25(val, _values, result)
403
- result = e(:function_call, :divide, [val[0], val[2]])
404
- result
405
- end
406
- .,.,
407
-
408
- module_eval(<<'.,.,', 'code_section.y', 53)
409
- def _reduce_26(val, _values, result)
410
- result = e(:function_call, val[0], val[2])
411
- result
412
- end
413
- .,.,
414
-
415
- module_eval(<<'.,.,', 'code_section.y', 54)
416
- def _reduce_27(val, _values, result)
417
- result = e(:function_call, val[0], [])
418
- result
419
- end
420
- .,.,
421
-
422
- module_eval(<<'.,.,', 'code_section.y', 56)
423
- def _reduce_28(val, _values, result)
424
396
  result = val[0] << val[2]
425
397
  result
426
398
  end
427
399
  .,.,
428
400
 
429
- module_eval(<<'.,.,', 'code_section.y', 57)
430
- def _reduce_29(val, _values, result)
401
+ module_eval(<<'.,.,', 'code_section.y', 60)
402
+ def _reduce_26(val, _values, result)
431
403
  result = [val[0]]
432
404
  result
433
405
  end
@@ -1,12 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'csv'
4
- # TODO: move some of these out to csv_plus_plus.rb
5
- require_relative '../cell'
6
- require_relative '../modifier'
7
- require_relative '../modifier.tab'
8
- require_relative '../row'
9
- require_relative '../template'
4
+
10
5
  require_relative 'benchmarked_compiler'
11
6
  require_relative 'code_section.tab'
12
7
  require_relative 'entities'
@@ -63,7 +58,7 @@ module CSVPlusPlus
63
58
  parse_code_section!
64
59
  rows = parse_csv_section!
65
60
 
66
- ::CSVPlusPlus::Template.new(rows:).tap do |t|
61
+ ::CSVPlusPlus::Template.new(rows:, code_section: scope.code_section).tap do |t|
67
62
  t.validate_infinite_expands(@runtime)
68
63
  expanding { t.expand_rows! }
69
64
  resolve_all_cells!(t)
@@ -83,7 +78,7 @@ module CSVPlusPlus
83
78
  def parse_code_section!
84
79
  @runtime.start!
85
80
  parsing_code_section do |input|
86
- code_section, csv_section = ::CSVPlusPlus::Language::CodeSectionParser.new.parse(input, self)
81
+ code_section, csv_section = ::CSVPlusPlus::Language::CodeSectionParser.new.parse(input, @runtime)
87
82
  # TODO: infer a type
88
83
  # allow user-supplied key/values to override anything global or from the code section
89
84
  code_section.def_variables(
@@ -4,16 +4,27 @@ module CSVPlusPlus
4
4
  module Language
5
5
  module Entities
6
6
  # A function call
7
+ #
8
+ # @attr_reader infix [boolean] Whether or not this function call is infix (X * Y, A + B, etc)
7
9
  class FunctionCall < EntityWithArguments
10
+ attr_reader :infix
11
+
8
12
  # @param id [String] The name of the function
9
13
  # @param arguments [Array<Entity>] The arguments to the function
10
- def initialize(id, arguments)
14
+ # @param infix [boolean] Whether the function is infix
15
+ def initialize(id, arguments, infix: false)
11
16
  super(:function_call, id:, arguments:)
17
+
18
+ @infix = infix
12
19
  end
13
20
 
14
21
  # @return [String]
15
22
  def to_s
16
- "#{@id.to_s.upcase}(#{arguments_to_s})"
23
+ if @infix
24
+ "(#{arguments.join(" #{@id} ")})"
25
+ else
26
+ "#{@id.to_s.upcase}(#{arguments_to_s})"
27
+ end
17
28
  end
18
29
 
19
30
  # @return [boolean]
@@ -91,6 +91,7 @@ module CSVPlusPlus
91
91
  end
92
92
 
93
93
  # Make a copy of the AST represented by +node+ and replace +fn_id+ with +replacement+ throughout
94
+ # rubocop:disable Metrics/MethodLength
94
95
  def function_replace(node, fn_id, replacement)
95
96
  if node.function_call? && node.id == fn_id
96
97
  call_function_or_runtime_value(replacement, node)
@@ -98,12 +99,14 @@ module CSVPlusPlus
98
99
  # not our function, but continue our depth first search on it
99
100
  ::CSVPlusPlus::Language::Entities::FunctionCall.new(
100
101
  node.id,
101
- node.arguments.map { |n| function_replace(n, fn_id, replacement) }
102
+ node.arguments.map { |n| function_replace(n, fn_id, replacement) },
103
+ infix: node.infix
102
104
  )
103
105
  else
104
106
  node
105
107
  end
106
108
  end
109
+ # rubocop:enable Metrics/MethodLength
107
110
 
108
111
  def resolve_function(fn_id)
109
112
  id = fn_id.to_sym
@@ -133,7 +136,8 @@ module CSVPlusPlus
133
136
  def variable_replace(node, var_id, replacement)
134
137
  if node.function_call?
135
138
  arguments = node.arguments.map { |n| variable_replace(n, var_id, replacement) }
136
- ::CSVPlusPlus::Language::Entities::FunctionCall.new(node.id, arguments)
139
+ # TODO: refactor these places where we copy functions... it's brittle with the kwargs
140
+ ::CSVPlusPlus::Language::Entities::FunctionCall.new(node.id, arguments, infix: node.infix)
137
141
  elsif node.variable? && node.id == var_id
138
142
  replacement
139
143
  else
@@ -35,15 +35,16 @@ module CSVPlusPlus
35
35
  runtime.raise_syntax_error("Error parsing #{parse_subject}", e.message, wrapped_error: e)
36
36
  end
37
37
 
38
- protected
39
-
40
- # Given a +type+, instantiate the proper instance with the given +entity_args+
41
- #
42
- # @param type [Symbol]
43
- # @param entity_args
44
- def e(type, *entity_args)
45
- ::CSVPlusPlus::Language::TYPES[type].new(*entity_args)
46
- end
38
+ TOKEN_LIBRARY = {
39
+ TRUE: [/true/i, :TRUE],
40
+ FALSE: [/false/i, :FALSE],
41
+ NUMBER: [/-?[\d.]+/, :NUMBER],
42
+ STRING: [%r{"(?:[^"\\]|\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4}))*"}, :STRING],
43
+ INFIX_OP: [%r{\^|\+|-|\*|/|&|<|>|<=|>=|<>}, :INFIX_OP],
44
+ VAR_REF: [/\$\$/, :VAR_REF],
45
+ ID: [/[$!\w:]+/, :ID]
46
+ }.freeze
47
+ public_constant :TOKEN_LIBRARY
47
48
 
48
49
  private
49
50
 
@@ -1,10 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
- require_relative './color'
5
- require_relative './expand'
6
- require_relative './language/syntax_error'
7
-
8
3
  module CSVPlusPlus
9
4
  # A container representing the operations that can be applied to a cell or row
10
5
  #
@@ -31,12 +31,14 @@ module CSVPlusPlus
31
31
  #
32
32
  # @param sheet_id [String] The identifier used by Google's API to reference the sheet. You can find it in the URL
33
33
  # for the sheet
34
+ #
34
35
  # @return [String]
35
36
  def google_sheet_id=(sheet_id)
36
37
  @google = ::CSVPlusPlus::GoogleOptions.new(sheet_id)
37
38
  end
38
39
 
39
40
  # Returns an error string or nil if there are no validation problems
41
+ #
40
42
  # @return [String, nil]
41
43
  def validate
42
44
  return if @google || @output_filename
@@ -45,6 +47,7 @@ module CSVPlusPlus
45
47
  end
46
48
 
47
49
  # Return a string with a verbose description of what we're doing with the options
50
+ #
48
51
  # @return [String]
49
52
  def verbose_summary
50
53
  <<~SUMMARY
@@ -3,12 +3,15 @@
3
3
  module CSVPlusPlus
4
4
  # Contains the flow and data from a code section and CSV section
5
5
  #
6
+ # @attr_reader code_section [CodeSection] The +CodeSection+ containing the functions and variables defined herein
6
7
  # @attr_reader rows [Array<Row>] The +Row+s that comprise this +Template+
7
8
  class Template
8
- attr_reader :rows
9
+ attr_reader :code_section, :rows
9
10
 
11
+ # @param code_section [CodeSection] The +CodeSection+ containing the functions and variables
10
12
  # @param rows [Array<Row>] The +Row+s that comprise this +Template+
11
- def initialize(rows:)
13
+ def initialize(code_section:, rows:)
14
+ @code_section = code_section
12
15
  @rows = rows
13
16
  end
14
17
 
@@ -18,6 +21,7 @@ module CSVPlusPlus
18
21
  end
19
22
 
20
23
  # Apply any expand= modifiers to the parsed template
24
+ #
21
25
  # @return [Array<Row>]
22
26
  def expand_rows!
23
27
  expanded_rows = []
@@ -46,6 +50,18 @@ module CSVPlusPlus
46
50
  )
47
51
  end
48
52
 
53
+ # Provide a summary of the state of the template (and it's +@code_section+)
54
+ #
55
+ # @return [String]
56
+ def verbose_summary
57
+ # TODO: we can probably include way more stats in here
58
+ <<~SUMMARY
59
+ #{@code_section.verbose_summary}
60
+
61
+ > #{@rows.length} rows to be written
62
+ SUMMARY
63
+ end
64
+
49
65
  private
50
66
 
51
67
  def expand_rows(push_row_fn)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CSVPlusPlus
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.1'
5
5
  public_constant :VERSION
6
6
  end
data/lib/csv_plus_plus.rb CHANGED
@@ -5,13 +5,22 @@ require 'google/apis/sheets_v4'
5
5
  require 'googleauth'
6
6
  require 'rubyXL'
7
7
  require 'rubyXL/convenience_methods'
8
+ require 'set'
8
9
 
10
+ require_relative 'csv_plus_plus/cell'
9
11
  require_relative 'csv_plus_plus/cli'
12
+ require_relative 'csv_plus_plus/code_section'
13
+ require_relative 'csv_plus_plus/color'
10
14
  require_relative 'csv_plus_plus/error'
11
15
  require_relative 'csv_plus_plus/language/builtins'
12
16
  require_relative 'csv_plus_plus/language/compiler'
13
17
  require_relative 'csv_plus_plus/language/runtime'
18
+ require_relative 'csv_plus_plus/language/syntax_error'
19
+ require_relative 'csv_plus_plus/modifier'
20
+ require_relative 'csv_plus_plus/modifier.tab'
14
21
  require_relative 'csv_plus_plus/options'
22
+ require_relative 'csv_plus_plus/row'
23
+ require_relative 'csv_plus_plus/template'
15
24
  require_relative 'csv_plus_plus/writer'
16
25
 
17
26
  # A programming language for writing rich CSV files
@@ -21,23 +30,30 @@ module CSVPlusPlus
21
30
  # @param input [String] The csvpp input to compile
22
31
  # @param filename [String, nil] The filename the input was read from. +nil+ if it is read from stdin.
23
32
  # @param options [Options] The various options to compile with
24
- #
25
- # rubocop:disable Metrics/MethodLength
26
33
  def self.apply_template_to_sheet!(input, filename, options)
27
34
  warn(options.verbose_summary) if options.verbose
28
35
 
29
- ::CSVPlusPlus::Language::Compiler.with_compiler(
30
- options:,
31
- runtime: ::CSVPlusPlus::Language::Runtime.new(input:, filename:)
32
- ) do |c|
33
- template = c.compile_template
34
-
35
- output = ::CSVPlusPlus::Writer.writer(options)
36
- c.outputting! do
37
- output.write_backup if options.backup
38
- output.write(template)
39
- end
36
+ runtime = ::CSVPlusPlus::Language::Runtime.new(input:, filename:)
37
+
38
+ ::CSVPlusPlus::Language::Compiler.with_compiler(options:, runtime:) do |compiler|
39
+ template = compiler.compile_template
40
+
41
+ warn(template.verbose_summary) if options.verbose
42
+
43
+ write_template(template, compiler, options)
44
+ end
45
+ end
46
+
47
+ # Write the results (and possibly make a backup) of a compiled +template+
48
+ #
49
+ # @param template [Template] The compiled template
50
+ # @param compiler [Compiler] The compiler currently in use
51
+ # @param options [Options] The options we're running with
52
+ def self.write_template(template, compiler, options)
53
+ output = ::CSVPlusPlus::Writer.writer(options)
54
+ compiler.outputting! do
55
+ output.write_backup if options.backup
56
+ output.write(template)
40
57
  end
41
58
  end
42
- # rubocop:enable Metrics/MethodLength
43
59
  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.1
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-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-apis-drive_v3