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 +4 -4
- data/CHANGELOG.md +8 -1
- data/lib/csv_plus_plus/code_section.rb +33 -0
- data/lib/csv_plus_plus/language/ast_builder.rb +2 -2
- data/lib/csv_plus_plus/language/cell_value.tab.rb +105 -132
- data/lib/csv_plus_plus/language/code_section.tab.rb +162 -190
- data/lib/csv_plus_plus/language/compiler.rb +3 -8
- data/lib/csv_plus_plus/language/entities/function_call.rb +13 -2
- data/lib/csv_plus_plus/language/scope.rb +6 -2
- data/lib/csv_plus_plus/lexer/lexer.rb +10 -9
- data/lib/csv_plus_plus/modifier.rb +0 -5
- data/lib/csv_plus_plus/options.rb +3 -0
- data/lib/csv_plus_plus/template.rb +18 -2
- data/lib/csv_plus_plus/version.rb +1 -1
- data/lib/csv_plus_plus.rb +30 -14
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ef86258faa82b75114acc715e9cb68bb312dc55194d533270fce0a796e02362
|
4
|
+
data.tar.gz: 9316f43dd4169a779efc6d8f447002434c4fc5984064b1f22f1448baee0f4522
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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, *
|
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(*
|
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
|
-
[
|
38
|
-
[
|
39
|
-
[
|
40
|
-
[
|
41
|
-
[
|
42
|
-
[
|
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
|
-
|
51
|
-
|
52
|
-
8, 12, 13, 10, 9, 11, 8,
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
64
|
-
|
65
|
-
2, 7, 7, 7, 7, 7, 7, 16,
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
77
|
-
nil, nil, nil,
|
78
|
-
|
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
|
-
-
|
83
|
-
-7, -8, -9, -10,
|
84
|
-
-
|
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,
|
89
|
-
nil, nil, nil, nil,
|
90
|
-
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,
|
96
|
-
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, -
|
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,
|
108
|
-
1,
|
109
|
-
1,
|
110
|
-
3,
|
111
|
-
2,
|
112
|
-
1,
|
113
|
-
1,
|
114
|
-
1,
|
115
|
-
1,
|
116
|
-
1,
|
117
|
-
4,
|
118
|
-
3,
|
119
|
-
3,
|
120
|
-
1,
|
121
|
-
3,
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
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
|
-
"
|
123
|
+
"^" => 4,
|
137
124
|
"*" => 5,
|
138
125
|
"/" => 6,
|
139
126
|
"+" => 7,
|
140
127
|
"-" => 8,
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
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',
|
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',
|
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',
|
222
|
+
module_eval(<<'.,.,', 'cell_value.y', 25)
|
222
223
|
def _reduce_5(val, _values, result)
|
223
|
-
result =
|
224
|
+
result = variable(val[1])
|
224
225
|
result
|
225
226
|
end
|
226
227
|
.,.,
|
227
228
|
|
228
|
-
module_eval(<<'.,.,', 'cell_value.y',
|
229
|
+
module_eval(<<'.,.,', 'cell_value.y', 26)
|
229
230
|
def _reduce_6(val, _values, result)
|
230
|
-
result =
|
231
|
+
result = string(val[0])
|
231
232
|
result
|
232
233
|
end
|
233
234
|
.,.,
|
234
235
|
|
235
|
-
module_eval(<<'.,.,', 'cell_value.y',
|
236
|
+
module_eval(<<'.,.,', 'cell_value.y', 27)
|
236
237
|
def _reduce_7(val, _values, result)
|
237
|
-
result =
|
238
|
+
result = number(val[0])
|
238
239
|
result
|
239
240
|
end
|
240
241
|
.,.,
|
241
242
|
|
242
|
-
module_eval(<<'.,.,', 'cell_value.y',
|
243
|
+
module_eval(<<'.,.,', 'cell_value.y', 28)
|
243
244
|
def _reduce_8(val, _values, result)
|
244
|
-
result =
|
245
|
+
result = boolean(true)
|
245
246
|
result
|
246
247
|
end
|
247
248
|
.,.,
|
248
249
|
|
249
|
-
module_eval(<<'.,.,', 'cell_value.y',
|
250
|
+
module_eval(<<'.,.,', 'cell_value.y', 29)
|
250
251
|
def _reduce_9(val, _values, result)
|
251
|
-
result =
|
252
|
+
result = boolean(false)
|
252
253
|
result
|
253
254
|
end
|
254
255
|
.,.,
|
255
256
|
|
256
|
-
module_eval(<<'.,.,', 'cell_value.y',
|
257
|
+
module_eval(<<'.,.,', 'cell_value.y', 30)
|
257
258
|
def _reduce_10(val, _values, result)
|
258
|
-
result =
|
259
|
+
result = cell_reference(val[0])
|
259
260
|
result
|
260
261
|
end
|
261
262
|
.,.,
|
262
263
|
|
263
|
-
module_eval(<<'.,.,', 'cell_value.y',
|
264
|
+
module_eval(<<'.,.,', 'cell_value.y', 32)
|
264
265
|
def _reduce_11(val, _values, result)
|
265
|
-
result =
|
266
|
+
result = function_call(val[0], val[2])
|
266
267
|
result
|
267
268
|
end
|
268
269
|
.,.,
|
269
270
|
|
270
|
-
module_eval(<<'.,.,', 'cell_value.y',
|
271
|
+
module_eval(<<'.,.,', 'cell_value.y', 33)
|
271
272
|
def _reduce_12(val, _values, result)
|
272
|
-
result =
|
273
|
+
result = function_call(val[0], [])
|
273
274
|
result
|
274
275
|
end
|
275
276
|
.,.,
|
276
277
|
|
277
|
-
module_eval(<<'.,.,', 'cell_value.y',
|
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',
|
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
|
314
|
-
result =
|
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',
|
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
|
-
[
|
51
|
-
[
|
52
|
-
[
|
53
|
-
[
|
54
|
-
[
|
55
|
-
[
|
56
|
-
[
|
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 =
|
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
|
-
|
84
|
-
|
85
|
-
|
86
|
-
24, 25,
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
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
|
-
|
120
|
-
nil, nil,
|
121
|
-
|
122
|
-
|
123
|
-
|
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
|
-
-
|
128
|
-
-1, -3, -
|
129
|
-
-
|
130
|
-
-
|
131
|
-
-
|
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
|
-
|
136
|
-
nil, nil, nil, nil,
|
137
|
-
|
138
|
-
nil,
|
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,
|
142
|
-
nil, nil, nil, nil,
|
143
|
-
7, nil, nil,
|
144
|
-
nil,
|
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,
|
148
|
-
-
|
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,
|
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,
|
157
|
-
1,
|
158
|
-
2,
|
159
|
-
1,
|
160
|
-
1,
|
161
|
-
1,
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
1,
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
1,
|
173
|
-
1,
|
174
|
-
1,
|
175
|
-
1,
|
176
|
-
|
177
|
-
3,
|
178
|
-
|
179
|
-
3,
|
180
|
-
3,
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
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
|
-
"
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
"
|
208
|
-
"
|
209
|
-
"
|
210
|
-
"
|
211
|
-
|
212
|
-
|
213
|
-
|
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
|
-
"
|
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',
|
278
|
+
module_eval(<<'.,.,', 'code_section.y', 34)
|
286
279
|
def _reduce_7(val, _values, result)
|
287
|
-
def_function(val[1], val[
|
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',
|
285
|
+
module_eval(<<'.,.,', 'code_section.y', 36)
|
293
286
|
def _reduce_8(val, _values, result)
|
294
|
-
|
287
|
+
result = val[1]
|
295
288
|
result
|
296
289
|
end
|
297
290
|
.,.,
|
298
291
|
|
299
|
-
module_eval(<<'.,.,', 'code_section.y',
|
292
|
+
module_eval(<<'.,.,', 'code_section.y', 37)
|
300
293
|
def _reduce_9(val, _values, result)
|
301
|
-
result =
|
294
|
+
result = []
|
302
295
|
result
|
303
296
|
end
|
304
297
|
.,.,
|
305
298
|
|
306
|
-
module_eval(<<'.,.,', 'code_section.y',
|
299
|
+
module_eval(<<'.,.,', 'code_section.y', 39)
|
307
300
|
def _reduce_10(val, _values, result)
|
308
|
-
result =
|
301
|
+
result = val[0] << val[2]
|
309
302
|
result
|
310
303
|
end
|
311
304
|
.,.,
|
312
305
|
|
313
|
-
module_eval(<<'.,.,', 'code_section.y',
|
306
|
+
module_eval(<<'.,.,', 'code_section.y', 40)
|
314
307
|
def _reduce_11(val, _values, result)
|
315
|
-
|
308
|
+
result = [val[0]]
|
316
309
|
result
|
317
310
|
end
|
318
311
|
.,.,
|
319
312
|
|
320
|
-
|
321
|
-
|
322
|
-
|
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
|
-
|
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 =
|
326
|
+
result = val[1]
|
334
327
|
result
|
335
328
|
end
|
336
329
|
.,.,
|
337
330
|
|
338
|
-
module_eval(<<'.,.,', 'code_section.y',
|
331
|
+
module_eval(<<'.,.,', 'code_section.y', 47)
|
339
332
|
def _reduce_16(val, _values, result)
|
340
|
-
result =
|
333
|
+
result = variable(val[1])
|
341
334
|
result
|
342
335
|
end
|
343
336
|
.,.,
|
344
337
|
|
345
|
-
module_eval(<<'.,.,', 'code_section.y',
|
338
|
+
module_eval(<<'.,.,', 'code_section.y', 48)
|
346
339
|
def _reduce_17(val, _values, result)
|
347
|
-
result =
|
340
|
+
result = string(val[0])
|
348
341
|
result
|
349
342
|
end
|
350
343
|
.,.,
|
351
344
|
|
352
|
-
module_eval(<<'.,.,', 'code_section.y',
|
345
|
+
module_eval(<<'.,.,', 'code_section.y', 49)
|
353
346
|
def _reduce_18(val, _values, result)
|
354
|
-
result =
|
347
|
+
result = number(val[0])
|
355
348
|
result
|
356
349
|
end
|
357
350
|
.,.,
|
358
351
|
|
359
|
-
module_eval(<<'.,.,', 'code_section.y',
|
352
|
+
module_eval(<<'.,.,', 'code_section.y', 50)
|
360
353
|
def _reduce_19(val, _values, result)
|
361
|
-
result =
|
354
|
+
result = boolean(true)
|
362
355
|
result
|
363
356
|
end
|
364
357
|
.,.,
|
365
358
|
|
366
|
-
module_eval(<<'.,.,', 'code_section.y',
|
359
|
+
module_eval(<<'.,.,', 'code_section.y', 51)
|
367
360
|
def _reduce_20(val, _values, result)
|
368
|
-
result =
|
361
|
+
result = boolean(false)
|
369
362
|
result
|
370
363
|
end
|
371
364
|
.,.,
|
372
365
|
|
373
|
-
module_eval(<<'.,.,', 'code_section.y',
|
366
|
+
module_eval(<<'.,.,', 'code_section.y', 52)
|
374
367
|
def _reduce_21(val, _values, result)
|
375
|
-
result =
|
368
|
+
result = cell_reference(val[0])
|
376
369
|
result
|
377
370
|
end
|
378
371
|
.,.,
|
379
372
|
|
380
|
-
module_eval(<<'.,.,', 'code_section.y',
|
373
|
+
module_eval(<<'.,.,', 'code_section.y', 54)
|
381
374
|
def _reduce_22(val, _values, result)
|
382
|
-
result =
|
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',
|
380
|
+
module_eval(<<'.,.,', 'code_section.y', 56)
|
388
381
|
def _reduce_23(val, _values, result)
|
389
|
-
result =
|
382
|
+
result = function_call(val[0], val[2])
|
390
383
|
result
|
391
384
|
end
|
392
385
|
.,.,
|
393
386
|
|
394
|
-
module_eval(<<'.,.,', 'code_section.y',
|
387
|
+
module_eval(<<'.,.,', 'code_section.y', 57)
|
395
388
|
def _reduce_24(val, _values, result)
|
396
|
-
result =
|
389
|
+
result = function_call(val[0], [])
|
397
390
|
result
|
398
391
|
end
|
399
392
|
.,.,
|
400
393
|
|
401
|
-
module_eval(<<'.,.,', 'code_section.y',
|
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',
|
430
|
-
def
|
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
|
-
|
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,
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
|
@@ -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)
|
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::
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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.
|
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-
|
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
|