class Keisan::Functions::Reduce

Public Class Methods

new() click to toggle source

Reduces (list, initial, accumulator, variable, expression) e.g. reduce(, 0, total, x, total+x) should give 10 When hash: (hash, initial, accumulator, key, value, expression)

# File lib/keisan/functions/reduce.rb, line 10
def initialize
  super("reduce")
end

Protected Instance Methods

shadowing_variable_names(children) click to toggle source
# File lib/keisan/functions/reduce.rb, line 16
def shadowing_variable_names(children)
  children.size == 5 ? children[2..3] : children[2..4]
end
verify_arguments!(arguments) click to toggle source
# File lib/keisan/functions/reduce.rb, line 20
def verify_arguments!(arguments)
  unless arguments[1..-1].all? {|argument| argument.is_a?(AST::Variable)}
    raise Exceptions::InvalidFunctionError.new("Middle arguments to #{name} must be variables")
  end
end

Private Instance Methods

evaluate_hash(hash, arguments, expression, context) click to toggle source
# File lib/keisan/functions/reduce.rb, line 47
def evaluate_hash(hash, arguments, expression, context)
  unless arguments.count == 4
    raise Exceptions::InvalidFunctionError.new("Reduce on list must take 3 arguments")
  end

  initial, accumulator, key, value = arguments[0...4]

  local = context.spawn_child(transient: false, shadowed: [accumulator.name, key.name, value.name])
  local.register_variable!(accumulator, initial.simplify(context))

  hash.each do |cur_key, cur_value|
    local.register_variable!(key, cur_key)
    local.register_variable!(value, cur_value)
    result = expression.simplified(local)
    local.register_variable!(accumulator, result)
  end

  local.variable(accumulator.name)
end
evaluate_list(list, arguments, expression, context) click to toggle source
# File lib/keisan/functions/reduce.rb, line 28
def evaluate_list(list, arguments, expression, context)
  unless arguments.count == 3
    raise Exceptions::InvalidFunctionError.new("Reduce on list must take 3 arguments")
  end

  initial, accumulator, variable = arguments[0...3]

  local = context.spawn_child(transient: false, shadowed: [accumulator.name, variable.name])
  local.register_variable!(accumulator, initial.simplify(context))

  list.children.each do |element|
    local.register_variable!(variable, element)
    result = expression.simplified(local)
    local.register_variable!(accumulator, result)
  end

  local.variable(accumulator.name)
end