excel_to_code 0.3.3 → 0.3.4
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/README.md +1 -0
- data/src/commands/excel_to_c.rb +2 -3
- data/src/commands/excel_to_x.rb +13 -1
- data/src/compile/c/a.out +0 -0
- data/src/compile/c/excel_to_c_runtime.c +39 -0
- data/src/compile/c/excel_to_c_runtime_test.c +21 -0
- data/src/compile/c/map_formulae_to_c.rb +5 -0
- data/src/compile/ruby/map_formulae_to_ruby.rb +1 -0
- data/src/excel/excel_functions.rb +2 -0
- data/src/excel/excel_functions/npv.rb +20 -0
- data/src/excel_to_code.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a337c16718282fa8bbce1da4a51cb81d2ad6651
|
4
|
+
data.tar.gz: fbfa6de417b5b4f8fe626244b234876cd00f430c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf150004e0ad6ad4cf8d17d4abc740c4b5e33e3224c39091a2d9b9edc65d4e66de2ba047446c9cbc04fe7c33f680ed156300dc10ca568f38e7c6e97a70896a7e
|
7
|
+
data.tar.gz: 28bbe1191e5da2bbcbc63d4bda866f6f1720c619212659d6aeaece6c9e21baa7597b95ec7e6d77718895ff9bed54f9cc07c4cd5674a8918fb73874ebfbd12044
|
data/README.md
CHANGED
@@ -48,3 +48,4 @@ There are some how to guides in the doc folder.
|
|
48
48
|
7. Newlines are removed from strings
|
49
49
|
8. The generated code uses floating point, rather than fully precise arithmetic, so results can differ slightly
|
50
50
|
9. The generated code uses the sprintf approach to rounding (even-odd) rather than excel's 0.5 rounds away from zero.
|
51
|
+
10. Ranges like this: Sheet1!A10:Sheet1!B20 and 3D ranges don't work
|
data/src/commands/excel_to_c.rb
CHANGED
@@ -380,9 +380,8 @@ END
|
|
380
380
|
return unless actually_compile_code || actually_run_tests
|
381
381
|
name = output_name.downcase
|
382
382
|
log.info "Compiling"
|
383
|
-
puts `
|
384
|
-
puts `gcc -fPIC -o #{name}
|
385
|
-
puts `gcc -shared -fPIC -o #{FFI.map_library_name(name)} #{name}.o`
|
383
|
+
puts `gcc -fPIC -o #{File.join(output_directory, name)}.o -c #{File.join(output_directory, name)}.c`
|
384
|
+
puts `gcc -shared -fPIC -o #{File.join(output_directory, FFI.map_library_name(name))} #{File.join(output_directory, name)}.o`
|
386
385
|
end
|
387
386
|
|
388
387
|
def run_tests
|
data/src/commands/excel_to_x.rb
CHANGED
@@ -142,6 +142,7 @@ class ExcelToX
|
|
142
142
|
# format and refer to sheets and references that actually exist
|
143
143
|
clean_cells_that_can_be_set_at_runtime
|
144
144
|
clean_cells_to_keep
|
145
|
+
convert_named_references_into_simple_form
|
145
146
|
clean_named_references_to_keep
|
146
147
|
clean_named_references_that_can_be_set_at_runtime
|
147
148
|
|
@@ -308,11 +309,22 @@ class ExcelToX
|
|
308
309
|
raise
|
309
310
|
end
|
310
311
|
end
|
312
|
+
|
313
|
+
end
|
314
|
+
|
315
|
+
# Named references can be simple cell references,
|
316
|
+
# or they can be ranges, or errors, or table references
|
317
|
+
# this function converts all the different types into
|
318
|
+
# arrays of cell references
|
319
|
+
def convert_named_references_into_simple_form
|
311
320
|
# Replace A$1:B2 with [A1, A2, B1, B2]
|
312
321
|
@replace_ranges_with_array_literals_replacer ||= ReplaceRangesWithArrayLiteralsAst.new
|
322
|
+
table_reference_replacer = ReplaceTableReferenceAst.new(@tables)
|
313
323
|
|
314
324
|
@named_references.each do |name, reference|
|
315
|
-
|
325
|
+
reference = table_reference_replacer.map(reference)
|
326
|
+
reference = @replace_ranges_with_array_literals_replacer.map(reference)
|
327
|
+
@named_references[name] = reference
|
316
328
|
end
|
317
329
|
|
318
330
|
end
|
data/src/compile/c/a.out
CHANGED
Binary file
|
@@ -83,6 +83,7 @@ static ExcelValue min(int number_of_arguments, ExcelValue *arguments);
|
|
83
83
|
static ExcelValue mmult(ExcelValue a_v, ExcelValue b_v);
|
84
84
|
static ExcelValue mod(ExcelValue a_v, ExcelValue b_v);
|
85
85
|
static ExcelValue negative(ExcelValue a_v);
|
86
|
+
static ExcelValue npv(ExcelValue rate, int number_of_arguments, ExcelValue *arguments);
|
86
87
|
static ExcelValue pmt(ExcelValue rate_v, ExcelValue number_of_periods_v, ExcelValue present_value_v);
|
87
88
|
static ExcelValue power(ExcelValue a_v, ExcelValue b_v);
|
88
89
|
static ExcelValue pv_3(ExcelValue a_v, ExcelValue b_v, ExcelValue c_v);
|
@@ -1310,6 +1311,44 @@ static ExcelValue sum(int array_size, ExcelValue *array) {
|
|
1310
1311
|
return new_excel_number(total);
|
1311
1312
|
}
|
1312
1313
|
|
1314
|
+
static ExcelValue npv(ExcelValue rate_v, int number_of_arguments, ExcelValue *arguments) {
|
1315
|
+
CHECK_FOR_PASSED_ERROR(rate_v)
|
1316
|
+
NUMBER(rate_v, rate)
|
1317
|
+
CHECK_FOR_CONVERSION_ERROR
|
1318
|
+
if(rate == -1) { return DIV0; }
|
1319
|
+
|
1320
|
+
double npv = 0;
|
1321
|
+
int n = 1;
|
1322
|
+
int i;
|
1323
|
+
int j;
|
1324
|
+
double v;
|
1325
|
+
ExcelValue r;
|
1326
|
+
ExcelValue r2;
|
1327
|
+
ExcelValue *range;
|
1328
|
+
|
1329
|
+
for(i=0;i<number_of_arguments;i++) {
|
1330
|
+
r = arguments[i];
|
1331
|
+
if(r.type == ExcelError) { return r; }
|
1332
|
+
if(r.type == ExcelRange) {
|
1333
|
+
range = r.array;
|
1334
|
+
for(j=0;j<(r.columns*r.rows);j++) {
|
1335
|
+
r2 = range[j];
|
1336
|
+
if(r2.type == ExcelError) { return r2; }
|
1337
|
+
v = number_from(r2);
|
1338
|
+
if(conversion_error) { conversion_error = 0; return VALUE; }
|
1339
|
+
npv = npv + (v/pow(1+rate, n));
|
1340
|
+
n++;
|
1341
|
+
}
|
1342
|
+
} else {
|
1343
|
+
v = number_from(r);
|
1344
|
+
if(conversion_error) { conversion_error = 0; return VALUE; }
|
1345
|
+
npv = npv + (v/pow(1+rate, n));
|
1346
|
+
n++;
|
1347
|
+
}
|
1348
|
+
}
|
1349
|
+
return new_excel_number(npv);
|
1350
|
+
}
|
1351
|
+
|
1313
1352
|
static ExcelValue max(int number_of_arguments, ExcelValue *arguments) {
|
1314
1353
|
double biggest_number_found;
|
1315
1354
|
int any_number_found = 0;
|
@@ -959,6 +959,27 @@ int test_functions() {
|
|
959
959
|
assert(value(new_excel_string("1")).number == 1);
|
960
960
|
assert(value(new_excel_string("A1A")).type == ExcelError);
|
961
961
|
|
962
|
+
|
963
|
+
// NPV(rate, flow1, flow2)
|
964
|
+
ExcelValue npv_array1[] = { new_excel_number(110) };
|
965
|
+
assert(npv(new_excel_number(0.1), 1, npv_array1).type == ExcelNumber);
|
966
|
+
assert(npv(new_excel_number(0.1), 1, npv_array1).number-100 < 0.001);
|
967
|
+
|
968
|
+
ExcelValue npv_array2[] = { new_excel_number(110), new_excel_number(121) };
|
969
|
+
assert((npv(new_excel_number(0.1), 2, npv_array2).number - 200) < 0.001);
|
970
|
+
|
971
|
+
ExcelValue npv_array3[] = { new_excel_number(110), new_excel_number(121)};
|
972
|
+
ExcelValue npv_array3_v = new_excel_range(npv_array3,2,1);
|
973
|
+
ExcelValue npv_array4[] = { npv_array3_v };
|
974
|
+
|
975
|
+
assert((npv(new_excel_number(0.1), 1, npv_array4).number - 200) < 0.001);
|
976
|
+
|
977
|
+
assert(npv(new_excel_number(-1.0), 1, npv_array1).type == ExcelError);
|
978
|
+
assert(npv(BLANK, 1, npv_array1).number == 110);
|
979
|
+
|
980
|
+
ExcelValue npv_array5[] = { BLANK };
|
981
|
+
assert(npv(new_excel_number(0.1), 1, npv_array5).number == 0);
|
982
|
+
|
962
983
|
// Release memory
|
963
984
|
free_all_allocated_memory();
|
964
985
|
|
@@ -66,6 +66,7 @@ class MapFormulaeToC < MapValuesToC
|
|
66
66
|
:'MIN' => 'min',
|
67
67
|
:'MMULT' => 'mmult',
|
68
68
|
:'MOD' => 'mod',
|
69
|
+
:'NPV' => 'npv',
|
69
70
|
:'PMT' => 'pmt',
|
70
71
|
:'PV3' => 'pv_3',
|
71
72
|
:'PV4' => 'pv_4',
|
@@ -156,6 +157,10 @@ class MapFormulaeToC < MapValuesToC
|
|
156
157
|
"#{FUNCTIONS[:AVERAGEIFS]}(#{map(average_range)}, #{map_arguments_to_array(criteria)})"
|
157
158
|
end
|
158
159
|
|
160
|
+
def function_npv(rate,*cash_flows)
|
161
|
+
"#{FUNCTIONS[:NPV]}(#{map(rate)}, #{map_arguments_to_array(cash_flows)})"
|
162
|
+
end
|
163
|
+
|
159
164
|
def function_if(condition, true_case, false_case = [:boolean_false])
|
160
165
|
true_code = map(true_case)
|
161
166
|
false_code = map(false_case)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ExcelFunctions
|
2
|
+
|
3
|
+
def npv(rate, *values)
|
4
|
+
# Turn the arguments into numbers
|
5
|
+
rate = number_argument(rate)
|
6
|
+
values = values.flatten.map { |v| number_argument(v) }
|
7
|
+
|
8
|
+
# Check for errors
|
9
|
+
return rate if rate.is_a?(Symbol)
|
10
|
+
return :div0 if rate == -1
|
11
|
+
values.each { |v| return v if v.is_a?(Symbol) }
|
12
|
+
|
13
|
+
npv = 0
|
14
|
+
|
15
|
+
values.each.with_index { |v, i| npv = npv + (v/((1+rate)**(i+1))) }
|
16
|
+
|
17
|
+
npv
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
data/src/excel_to_code.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: excel_to_code
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Counsell, Green on Black Ltd
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubypeg
|
@@ -105,7 +105,8 @@ description: "# excel_to_code\n\nConverts some excel spreadsheets (.xlsx, not .x
|
|
105
105
|
multithread and will give bad results if you try\n7. Newlines are removed from strings\n8.
|
106
106
|
The generated code uses floating point, rather than fully precise arithmetic, so
|
107
107
|
results can differ slightly\n9. The generated code uses the sprintf approach to
|
108
|
-
rounding (even-odd) rather than excel's 0.5 rounds away from zero.\
|
108
|
+
rounding (even-odd) rather than excel's 0.5 rounds away from zero.\n10. Ranges like
|
109
|
+
this: Sheet1!A10:Sheet1!B20 and 3D ranges don't work\n"
|
109
110
|
email: tamc@greenonblack.com
|
110
111
|
executables:
|
111
112
|
- excel_to_c
|
@@ -189,6 +190,7 @@ files:
|
|
189
190
|
- src/excel/excel_functions/multiply.rb
|
190
191
|
- src/excel/excel_functions/negative.rb
|
191
192
|
- src/excel/excel_functions/not_equal.rb
|
193
|
+
- src/excel/excel_functions/npv.rb
|
192
194
|
- src/excel/excel_functions/number_argument.rb
|
193
195
|
- src/excel/excel_functions/pi.rb
|
194
196
|
- src/excel/excel_functions/pmt.rb
|