class MapFormulaeToC

Constants

FUNCTIONS
FUNCTIONS_WITH_ANY_NUMBER_OF_ARGUMENTS

Attributes

allow_unknown_functions[RW]
counter[R]
initializers[R]
sheet_names[RW]
worksheet[RW]

Public Class Methods

new() click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 11
def initialize
  reset
end

Public Instance Methods

any_number_of_argument_function(function_name,arguments) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 251
def any_number_of_argument_function(function_name,arguments)
  "#{FUNCTIONS[function_name.to_sym]}(#{map_arguments_to_array(arguments)})"
end
arithmetic(left,operator,right) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 134
def arithmetic(left,operator,right)
  "#{FUNCTIONS[operator.last]}(#{map(left)},#{map(right)})"
end
array(*rows) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 278
def array(*rows)
  # Make sure we get the right dimensions
  number_of_rows = rows.size
  number_of_columns = rows[0].size - 1
  size = number_of_rows * number_of_columns

  # First we have to create an excel array
  array_name = "array#{@counter}"
  @counter +=1

  initializers << "static ExcelValue #{array_name}[#{size}];"
  i = 0
  rows.each do |row|
    row.each do |cell|
      next if cell.is_a?(Symbol)
      initializers << "#{array_name}[#{i}] = #{map(cell)};"
      i += 1
    end
  end

  # Then we need to assign it to an excel value
  range_name = array_name+"_ev"
  initializers << "ExcelValue #{range_name} = EXCEL_RANGE(#{array_name},#{number_of_rows},#{number_of_columns});"

  range_name
end
brackets(*contents) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 130
def brackets(*contents)
  "(#{contents.map { |a| map(a) }.join(',')})"
end
cell(reference) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 265
def cell(reference)
  # FIXME: What a cludge.
  if reference =~ /common\d+/
    "#{reference}()"
  else
    reference.to_s.downcase.gsub('$','')
  end
end
comparison(left,operator,right) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 142
def comparison(left,operator,right)
  "#{FUNCTIONS[operator.last]}(#{map(left)},#{map(right)})"
end
function(function_name,*arguments) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 146
def function(function_name,*arguments)
  # Some functions are special cases
  if self.respond_to?("function_#{function_name.to_s.downcase}")
    send("function_#{function_name.to_s.downcase}",*arguments)
  # Some arguments can take any number of arguments, which we need to treat separately
  elsif FUNCTIONS_WITH_ANY_NUMBER_OF_ARGUMENTS.include?(function_name.to_s)
    any_number_of_argument_function(function_name,arguments)

  # Check for whether this function has variants based on the number of arguments
  elsif FUNCTIONS.has_key?("#{function_name.to_s}#{arguments.size}".to_sym)
    "#{FUNCTIONS["#{function_name.to_s}#{arguments.size}".to_sym]}(#{arguments.map { |a| map(a) }.join(",")})"

  # Then check for whether it is just a standard type
  elsif FUNCTIONS.has_key?(function_name.to_sym)
    "#{FUNCTIONS[function_name.to_sym]}(#{arguments.map { |a| map(a) }.join(",")})"

  # Optionally, can dump unknown functions
elsif self.allow_unknown_functions
    "#{function_name.to_s.downcase}(#{arguments.map { |a| map(a) }.join(",")})"

  # But default is to raise an error
  else
    raise NotSupportedException.new("Function #{function_name} with #{arguments.size} arguments not supported")
  end
end
function_averageifs(average_range,*criteria) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 203
def function_averageifs(average_range,*criteria)
  "#{FUNCTIONS[:AVERAGEIFS]}(#{map(average_range)}, #{map_arguments_to_array(criteria)})"
end
function_choose(index,*arguments) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 191
def function_choose(index,*arguments)
  "#{FUNCTIONS[:CHOOSE]}(#{map(index)}, #{map_arguments_to_array(arguments)})"
end
function_if(condition, true_case, false_case = [:boolean_false]) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 211
def function_if(condition, true_case, false_case = [:boolean_false])
  true_code = map(true_case)
  false_code = map(false_case)

  condition_name = "condition#{@counter}"
  result_name = "ifresult#{@counter}"
  @counter += 1

  initializers << "ExcelValue #{condition_name} = #{map(condition)};"
  initializers << "ExcelValue #{result_name};"
  initializers << "switch(#{condition_name}.type) {"
  initializers << "case ExcelBoolean:"
      initializers << "  if(#{condition_name}.number == true) {"
  initializers << "    #{result_name} = #{true_code};"
  initializers << "  } else {"
  initializers << "    #{result_name} = #{false_code};"
  initializers << "  }"
  initializers << "  break;"
      initializers << "case ExcelNumber:"
  initializers << "  if(#{condition_name}.number == 0) {"
  initializers << "    #{result_name} = #{false_code};"
  initializers << "  } else {"
  initializers << "    #{result_name} = #{true_code};"
  initializers << "  }"
  initializers << "  break;"
        initializers << "case ExcelEmpty: "
  initializers << "  #{result_name} = #{false_code};"
  initializers << "  break;"
        initializers << "case ExcelString:"
  initializers << "case ExcelRange:"
  initializers << "  #{result_name} = VALUE;"
  initializers << "  break;"
      initializers << "case ExcelError:"
  initializers << "  #{result_name} = #{condition_name};"
  initializers << "  break;"
  initializers << "}"

  return result_name
end
function_npv(rate,*cash_flows) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 207
def function_npv(rate,*cash_flows)
  "#{FUNCTIONS[:NPV]}(#{map(rate)}, #{map_arguments_to_array(cash_flows)})"
end
function_pi() click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 187
def function_pi()
  "M_PI"
end
function_subtotal(type,*arguments) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 195
def function_subtotal(type,*arguments)
  "#{FUNCTIONS[:SUBTOTAL]}(#{map(type)}, #{map_arguments_to_array(arguments)})"
end
function_sumifs(sum_range,*criteria) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 199
def function_sumifs(sum_range,*criteria)
  "#{FUNCTIONS[:SUMIFS]}(#{map(sum_range)}, #{map_arguments_to_array(criteria)})"
end
map_arguments_to_array(arguments) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 255
def map_arguments_to_array(arguments)
  # First we have to create an excel array
  array_name = "array#{@counter}"
  @counter +=1
  arguments_size = arguments.size
  arguments = arguments.map { |a| map(a) }.join(',')
  initializers << "ExcelValue #{array_name}[] = {#{arguments}};"
  "#{arguments_size}, #{array_name}"
end
prefix(symbol,ast) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 125
def prefix(symbol,ast)
  return map(ast) if symbol == "+"
  return "negative(#{map(ast)})"
end
reset() click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 15
def reset
  @initializers = []
  @counter = 0
end
sheet_reference(sheet,reference) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 274
def sheet_reference(sheet,reference)
  "#{sheet_names[sheet]}_#{map(reference).to_s.downcase}()"
end
string_join(*strings) click to toggle source
# File src/compile/c/map_formulae_to_c.rb, line 138
def string_join(*strings)
  any_number_of_argument_function('string_join',strings)
end