excel_to_code 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/README +41 -0
  2. data/bin/excel_to_c +63 -0
  3. data/bin/excel_to_ruby +9 -0
  4. data/src/commands.rb +2 -0
  5. data/src/commands/excel_to_c.rb +858 -0
  6. data/src/commands/excel_to_ruby.rb +620 -0
  7. data/src/compile.rb +2 -0
  8. data/src/compile/c.rb +5 -0
  9. data/src/compile/c/compile_to_c.rb +62 -0
  10. data/src/compile/c/compile_to_c_header.rb +26 -0
  11. data/src/compile/c/compile_to_c_unit_test.rb +42 -0
  12. data/src/compile/c/excel_to_c_runtime.c +2029 -0
  13. data/src/compile/c/map_formulae_to_c.rb +184 -0
  14. data/src/compile/c/map_sheet_names_to_c_names.rb +19 -0
  15. data/src/compile/c/map_values_to_c.rb +85 -0
  16. data/src/compile/c/map_values_to_c_structs.rb +37 -0
  17. data/src/compile/ruby.rb +3 -0
  18. data/src/compile/ruby/compile_to_ruby.rb +33 -0
  19. data/src/compile/ruby/compile_to_ruby_unit_test.rb +28 -0
  20. data/src/compile/ruby/excel_to_ruby_runtime.rb +1 -0
  21. data/src/compile/ruby/map_formulae_to_ruby.rb +95 -0
  22. data/src/compile/ruby/map_sheet_names_to_ruby_names.rb +19 -0
  23. data/src/compile/ruby/map_values_to_ruby.rb +65 -0
  24. data/src/excel.rb +5 -0
  25. data/src/excel/area.rb +93 -0
  26. data/src/excel/excel_functions.rb +84 -0
  27. data/src/excel/excel_functions/abs.rb +14 -0
  28. data/src/excel/excel_functions/add.rb +18 -0
  29. data/src/excel/excel_functions/and.rb +30 -0
  30. data/src/excel/excel_functions/apply_to_range.rb +17 -0
  31. data/src/excel/excel_functions/average.rb +12 -0
  32. data/src/excel/excel_functions/choose.rb +18 -0
  33. data/src/excel/excel_functions/cosh.rb +9 -0
  34. data/src/excel/excel_functions/count.rb +9 -0
  35. data/src/excel/excel_functions/counta.rb +8 -0
  36. data/src/excel/excel_functions/divide.rb +23 -0
  37. data/src/excel/excel_functions/excel_equal.rb +20 -0
  38. data/src/excel/excel_functions/excel_if.rb +8 -0
  39. data/src/excel/excel_functions/excel_match.rb +51 -0
  40. data/src/excel/excel_functions/find.rb +39 -0
  41. data/src/excel/excel_functions/iferror.rb +10 -0
  42. data/src/excel/excel_functions/index.rb +48 -0
  43. data/src/excel/excel_functions/left.rb +12 -0
  44. data/src/excel/excel_functions/less_than.rb +26 -0
  45. data/src/excel/excel_functions/less_than_or_equal.rb +26 -0
  46. data/src/excel/excel_functions/max.rb +12 -0
  47. data/src/excel/excel_functions/min.rb +12 -0
  48. data/src/excel/excel_functions/mod.rb +15 -0
  49. data/src/excel/excel_functions/more_than.rb +26 -0
  50. data/src/excel/excel_functions/more_than_or_equal.rb +26 -0
  51. data/src/excel/excel_functions/multiply.rb +24 -0
  52. data/src/excel/excel_functions/negative.rb +12 -0
  53. data/src/excel/excel_functions/not_equal.rb +19 -0
  54. data/src/excel/excel_functions/number_argument.rb +30 -0
  55. data/src/excel/excel_functions/pi.rb +7 -0
  56. data/src/excel/excel_functions/pmt.rb +16 -0
  57. data/src/excel/excel_functions/power.rb +18 -0
  58. data/src/excel/excel_functions/round.rb +13 -0
  59. data/src/excel/excel_functions/rounddown.rb +14 -0
  60. data/src/excel/excel_functions/roundup.rb +17 -0
  61. data/src/excel/excel_functions/string_join.rb +19 -0
  62. data/src/excel/excel_functions/subtotal.rb +13 -0
  63. data/src/excel/excel_functions/subtract.rb +18 -0
  64. data/src/excel/excel_functions/sum.rb +8 -0
  65. data/src/excel/excel_functions/sumif.rb +7 -0
  66. data/src/excel/excel_functions/sumifs.rb +74 -0
  67. data/src/excel/excel_functions/sumproduct.rb +32 -0
  68. data/src/excel/excel_functions/vlookup.rb +49 -0
  69. data/src/excel/formula_peg.rb +238 -0
  70. data/src/excel/formula_peg.txt +45 -0
  71. data/src/excel/reference.rb +56 -0
  72. data/src/excel/table.rb +108 -0
  73. data/src/excel_to_code.rb +7 -0
  74. data/src/extract.rb +13 -0
  75. data/src/extract/check_for_unknown_functions.rb +20 -0
  76. data/src/extract/extract_array_formulae.rb +23 -0
  77. data/src/extract/extract_formulae.rb +36 -0
  78. data/src/extract/extract_named_references.rb +38 -0
  79. data/src/extract/extract_relationships.rb +10 -0
  80. data/src/extract/extract_shared_formulae.rb +23 -0
  81. data/src/extract/extract_shared_strings.rb +20 -0
  82. data/src/extract/extract_simple_formulae.rb +18 -0
  83. data/src/extract/extract_table.rb +24 -0
  84. data/src/extract/extract_values.rb +29 -0
  85. data/src/extract/extract_worksheet_dimensions.rb +11 -0
  86. data/src/extract/extract_worksheet_names.rb +10 -0
  87. data/src/extract/extract_worksheet_table_relationships.rb +10 -0
  88. data/src/extract/simple_extract_from_xml.rb +19 -0
  89. data/src/rewrite.rb +10 -0
  90. data/src/rewrite/ast_copy_formula.rb +42 -0
  91. data/src/rewrite/ast_expand_array_formulae.rb +180 -0
  92. data/src/rewrite/rewrite_array_formulae.rb +71 -0
  93. data/src/rewrite/rewrite_array_formulae_to_arrays.rb +18 -0
  94. data/src/rewrite/rewrite_cell_references_to_include_sheet.rb +56 -0
  95. data/src/rewrite/rewrite_formulae_to_ast.rb +24 -0
  96. data/src/rewrite/rewrite_merge_formulae_and_values.rb +18 -0
  97. data/src/rewrite/rewrite_relationship_id_to_filename.rb +22 -0
  98. data/src/rewrite/rewrite_shared_formulae.rb +38 -0
  99. data/src/rewrite/rewrite_values_to_ast.rb +28 -0
  100. data/src/rewrite/rewrite_whole_row_column_references_to_areas.rb +90 -0
  101. data/src/rewrite/rewrite_worksheet_names.rb +20 -0
  102. data/src/simplify.rb +16 -0
  103. data/src/simplify/count_formula_references.rb +58 -0
  104. data/src/simplify/identify_dependencies.rb +56 -0
  105. data/src/simplify/identify_repeated_formula_elements.rb +37 -0
  106. data/src/simplify/inline_formulae.rb +77 -0
  107. data/src/simplify/map_formulae_to_values.rb +157 -0
  108. data/src/simplify/remove_cells.rb +18 -0
  109. data/src/simplify/replace_arrays_with_single_cells.rb +27 -0
  110. data/src/simplify/replace_blanks.rb +58 -0
  111. data/src/simplify/replace_common_elements_in_formulae.rb +19 -0
  112. data/src/simplify/replace_formulae_with_calculated_values.rb +21 -0
  113. data/src/simplify/replace_indirects_with_references.rb +44 -0
  114. data/src/simplify/replace_named_references.rb +82 -0
  115. data/src/simplify/replace_ranges_with_array_literals.rb +54 -0
  116. data/src/simplify/replace_shared_strings.rb +49 -0
  117. data/src/simplify/replace_table_references.rb +71 -0
  118. data/src/simplify/replace_values_with_constants.rb +47 -0
  119. data/src/simplify/simplify_arithmetic.rb +54 -0
  120. data/src/util.rb +2 -0
  121. data/src/util/not_supported_exception.rb +2 -0
  122. data/src/util/try.rb +9 -0
  123. metadata +207 -0
@@ -0,0 +1,20 @@
1
+ require_relative 'apply_to_range'
2
+
3
+ module ExcelFunctions
4
+
5
+ def excel_equal?(a,b)
6
+ return apply_to_range(a,b) { |a,b| excel_equal?(a,b) } if a.is_a?(Array) || b.is_a?(Array)
7
+
8
+ return a if a.is_a?(Symbol)
9
+ return b if b.is_a?(Symbol)
10
+
11
+ case a
12
+ when String
13
+ a.downcase == b.downcase
14
+ else
15
+ a == b
16
+ end
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,8 @@
1
+ module ExcelFunctions
2
+
3
+ def excel_if(condition,true_value,false_value = false)
4
+ return condition if condition.is_a?(Symbol)
5
+ condition ? true_value : false_value
6
+ end
7
+
8
+ end
@@ -0,0 +1,51 @@
1
+ module ExcelFunctions
2
+
3
+ def excel_match(lookup_value,lookup_array,match_type = 0)
4
+ return lookup_value if lookup_value.is_a?(Symbol)
5
+ return lookup_array if lookup_array.is_a?(Symbol)
6
+ return match_type if match_type.is_a?(Symbol)
7
+
8
+ lookup_value ||= 0
9
+ lookup_array ||= [0]
10
+ match_type ||= 0
11
+ lookup_array = [lookup_array] unless lookup_array.is_a?(Array)
12
+ lookup_array = lookup_array.flatten
13
+
14
+ lookup_value = lookup_value.downcase if lookup_value.respond_to?(:downcase)
15
+ case match_type
16
+ when 0, 0.0, false
17
+ lookup_array.each_with_index do |item,index|
18
+ item ||= 0
19
+ item = item.downcase if item.respond_to?(:downcase)
20
+ return index+1 if lookup_value == item
21
+ end
22
+ return :na
23
+ when 1, 1.0, true
24
+ lookup_array.each_with_index do |item, index|
25
+ item ||= 0
26
+ next if lookup_value.is_a?(String) && !item.is_a?(String)
27
+ next if lookup_value.is_a?(Numeric) && !item.is_a?(Numeric)
28
+ item = item.downcase if item.respond_to?(:downcase)
29
+ if item > lookup_value
30
+ return :na if index == 0
31
+ return index
32
+ end
33
+ end
34
+ return lookup_array.to_a.size
35
+ when -1, -1.0
36
+ lookup_array.each_with_index do |item, index|
37
+ item ||= 0
38
+ next if lookup_value.is_a?(String) && !item.is_a?(String)
39
+ next if lookup_value.is_a?(Numeric) && !item.is_a?(Numeric)
40
+ item = item.downcase if item.respond_to?(:downcase)
41
+ if item < lookup_value
42
+ return :na if index == 0
43
+ return index
44
+ end
45
+ end
46
+ return lookup_array.to_a.size - 1
47
+ end
48
+ return :na
49
+ end
50
+
51
+ end
@@ -0,0 +1,39 @@
1
+ module ExcelFunctions
2
+
3
+ def find(find_text,within_text,start_number = 1)
4
+ return find_text if find_text.is_a?(Symbol)
5
+ return within_text if within_text.is_a?(Symbol)
6
+ return start_number if start_number.is_a?(Symbol)
7
+
8
+ # nils are treated as empty strings
9
+ find_text ||= ""
10
+ within_text ||= ""
11
+
12
+ # there are some cases where the start_number is remapped
13
+ case start_number
14
+ when nil; return :value
15
+ when String;
16
+ begin
17
+ start_number = Float(start_number)
18
+ rescue ArgumentError
19
+ return :value
20
+ end
21
+ when true; start_number = 1
22
+ when false; return :value
23
+ when Numeric; # ok
24
+ else; return :value
25
+ end
26
+
27
+ # edge case
28
+ return 1 if find_text == "" && within_text == "" && start_number == 1
29
+
30
+ # length check
31
+ return :value if start_number < 1
32
+ return :value if start_number > within_text.length
33
+
34
+ # Ok, lets go
35
+ result = within_text.index(find_text,start_number - 1 )
36
+ result ? result + 1 : :value
37
+ end
38
+
39
+ end
@@ -0,0 +1,10 @@
1
+ module ExcelFunctions
2
+
3
+ def iferror(value,value_if_error)
4
+ value_if_error ||= 0
5
+ return value_if_error if value.is_a?(Symbol)
6
+ return value_if_error if value.is_a?(Float) && value.nan?
7
+ value
8
+ end
9
+
10
+ end
@@ -0,0 +1,48 @@
1
+ module ExcelFunctions
2
+
3
+ def index(array, row_number, column_number = :not_specified)
4
+
5
+ return array if array.is_a?(Symbol)
6
+ return row_number if row_number.is_a?(Symbol)
7
+ return column_number if column_number.is_a?(Symbol) && column_number != :not_specified
8
+
9
+ array = [[array]] unless array.is_a?(Array)
10
+
11
+ if column_number == :not_specified
12
+ if array.length == 1 # It is a single row
13
+ index_for_row_column(array,1,row_number)
14
+ elsif array.first.length == 1 # it is a single column
15
+ index_for_row_column(array,row_number,1)
16
+ else
17
+ return :ref
18
+ end
19
+ else
20
+ if row_number == nil || row_number == 0
21
+ index_for_whole_column(array,column_number)
22
+ elsif column_number == nil || column_number == 0
23
+ index_for_whole_row(array,row_number)
24
+ else
25
+ index_for_row_column(array,row_number,column_number)
26
+ end
27
+ end
28
+ end
29
+
30
+ def index_for_row_column(array,row_number,column_number)
31
+ return :ref if row_number < 1 || row_number > array.length
32
+ row = array[row_number-1]
33
+ return :ref if column_number < 1 || column_number > row.length
34
+ row[column_number-1] || 0
35
+ end
36
+
37
+ def index_for_whole_row(array,row_number)
38
+ return :ref if row_number < 1
39
+ return :ref if row_number > array.length
40
+ [array[row_number-1]]
41
+ end
42
+
43
+ def index_for_whole_column(array,column_number)
44
+ return :ref if column_number < 1
45
+ return :ref if column_number > array[0].length
46
+ array.map { |row| [row[column_number-1]]}
47
+ end
48
+ end
@@ -0,0 +1,12 @@
1
+ module ExcelFunctions
2
+
3
+ def left(string,characters = 1)
4
+ return string if string.is_a?(Symbol)
5
+ return characters if characters.is_a?(Symbol)
6
+ return nil if string == nil || characters == nil
7
+ string = "TRUE" if string == true
8
+ string = "FALSE" if string == false
9
+ string.to_s.slice(0,characters)
10
+ end
11
+
12
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'apply_to_range'
2
+
3
+ module ExcelFunctions
4
+
5
+ def less_than?(a,b)
6
+ # return apply_to_range(a,b) { |a,b| less_than?(a,b) } if a.is_a?(Array) || b.is_a?(Array)
7
+
8
+ return a if a.is_a?(Symbol)
9
+ return b if b.is_a?(Symbol)
10
+
11
+ a = 0 if a == nil
12
+ b = 0 if b == nil
13
+
14
+ case a
15
+ when String
16
+ a.downcase < b.downcase
17
+ when TrueClass, FalseClass
18
+ a = a ? 1 : 0
19
+ b = b ? 1 : 0 if (b.is_a?(TrueClass) || b.is_a?(FalseClass))
20
+ a < b
21
+ else
22
+ a < b
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'apply_to_range'
2
+
3
+ module ExcelFunctions
4
+
5
+ def less_than_or_equal?(a,b)
6
+ # return apply_to_range(a,b) { |a,b| less_than_or_equal?(a,b) } if a.is_a?(Array) || b.is_a?(Array)
7
+
8
+ return a if a.is_a?(Symbol)
9
+ return b if b.is_a?(Symbol)
10
+
11
+ a = 0 if a == nil
12
+ b = 0 if b == nil
13
+
14
+ case a
15
+ when String
16
+ a.downcase <= b.downcase
17
+ when TrueClass, FalseClass
18
+ a = a ? 1 : 0
19
+ b = b ? 1 : 0 if (b.is_a?(TrueClass) || b.is_a?(FalseClass))
20
+ a <= b
21
+ else
22
+ a <= b
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,12 @@
1
+ module ExcelFunctions
2
+
3
+ def max(*args)
4
+ args = args.flatten
5
+ error = args.find {|a| a.is_a?(Symbol)}
6
+ return error if error
7
+ args.delete_if { |a| !a.is_a?(Numeric) }
8
+ return 0 if args.empty?
9
+ args.max
10
+ end
11
+
12
+ end
@@ -0,0 +1,12 @@
1
+ module ExcelFunctions
2
+
3
+ def min(*args)
4
+ args = args.flatten
5
+ error = args.find {|a| a.is_a?(Symbol)}
6
+ return error if error
7
+ args.delete_if { |a| !a.is_a?(Numeric) }
8
+ return 0 if args.empty?
9
+ args.min
10
+ end
11
+
12
+ end
@@ -0,0 +1,15 @@
1
+ module ExcelFunctions
2
+
3
+ def mod(a,b)
4
+ a = number_argument(a)
5
+ b = number_argument(b)
6
+
7
+ return a if a.is_a?(Symbol)
8
+ return b if b.is_a?(Symbol)
9
+
10
+ return :div0 if b == 0
11
+
12
+ a % b
13
+ end
14
+
15
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'apply_to_range'
2
+
3
+ module ExcelFunctions
4
+
5
+ def more_than?(a,b)
6
+ # return apply_to_range(a,b) { |a,b| more_than?(a,b) } if a.is_a?(Array) || b.is_a?(Array)
7
+
8
+ return a if a.is_a?(Symbol)
9
+ return b if b.is_a?(Symbol)
10
+
11
+ a = 0 if a == nil
12
+ b = 0 if b == nil
13
+
14
+ case a
15
+ when String
16
+ a.downcase > b.downcase
17
+ when TrueClass, FalseClass
18
+ a = a ? 1 : 0
19
+ b = b ? 1 : 0 if (b.is_a?(TrueClass) || b.is_a?(FalseClass))
20
+ a > b
21
+ else
22
+ a > b
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'apply_to_range'
2
+
3
+ module ExcelFunctions
4
+
5
+ def more_than_or_equal?(a,b)
6
+ # return apply_to_range(a,b) { |a,b| more_than_or_equal?(a,b) } if a.is_a?(Array) || b.is_a?(Array)
7
+
8
+ return a if a.is_a?(Symbol)
9
+ return b if b.is_a?(Symbol)
10
+
11
+ a = 0 if a == nil
12
+ b = 0 if b == nil
13
+
14
+ case a
15
+ when String
16
+ a.downcase >= b.downcase
17
+ when TrueClass, FalseClass
18
+ a = a ? 1 : 0
19
+ b = b ? 1 : 0 if (b.is_a?(TrueClass) || b.is_a?(FalseClass))
20
+ a >= b
21
+ else
22
+ a >= b
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,24 @@
1
+ require_relative 'number_argument'
2
+ require_relative 'apply_to_range'
3
+
4
+ module ExcelFunctions
5
+
6
+ def multiply(a,b)
7
+ begin
8
+ # return apply_to_range(a,b) { |a,b| multiply(a,b) } if a.is_a?(Array) || b.is_a?(Array)
9
+
10
+ a = number_argument(a)
11
+ b = number_argument(b)
12
+
13
+ return a if a.is_a?(Symbol)
14
+ return b if b.is_a?(Symbol)
15
+
16
+ a * b
17
+
18
+ rescue Error => e
19
+ print e.backtrace.join('\n')
20
+ raise
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,12 @@
1
+ module ExcelFunctions
2
+
3
+ def negative(a)
4
+ a = number_argument(a)
5
+
6
+ return a if a.is_a?(Symbol)
7
+
8
+ -a
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'apply_to_range'
2
+
3
+ module ExcelFunctions
4
+
5
+ def not_equal?(a,b)
6
+ # return apply_to_range(a,b) { |a,b| not_equal?(a,b) } if a.is_a?(Array) || b.is_a?(Array)
7
+
8
+ return a if a.is_a?(Symbol)
9
+ return b if b.is_a?(Symbol)
10
+
11
+ case a
12
+ when String
13
+ a.downcase != b.downcase
14
+ else
15
+ a != b
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,30 @@
1
+ module ExcelFunctions
2
+
3
+ # This is a support function for mapping arguments that are numbers to numeric values
4
+ # deals with the fact that in Excel "2.14" == 2.14, TRUE == 1, FALSE == 0 and nil == 0
5
+ def number_argument(a)
6
+ case a
7
+ when Symbol
8
+ return a
9
+ when String
10
+ begin
11
+ return Float(a)
12
+ rescue ArgumentError
13
+ return :value
14
+ end
15
+ when nil
16
+ return 0
17
+ when true
18
+ return 1
19
+ when false
20
+ return 0
21
+ when Numeric
22
+ return a
23
+ when Array
24
+ return a[0][0]
25
+ else
26
+ return :value
27
+ end
28
+ end
29
+
30
+ end