class Dentaku::AST::RubyMath

def self.[](method)

def self.[](method)
  klass_name = method.to_s.capitalize
  klass = const_set(klass_name , Class.new(self))
  klass.implement(method)
  const_get(klass_name)
end

def self.arity

def self.arity
  @implementation.arity < 0 ? nil : @implementation.arity
end

def self.call(*args)

def self.call(*args)
  @implementation.call(*args)
rescue Math::DomainError => _e
  raise Dentaku::MathDomainError.new(name, args)
end

def self.implement(method)

def self.implement(method)
  @name = method
  @implementation = Math.method(method)
end

def self.max_param_count

def self.max_param_count
  @implementation.parameters.select { |type, _name| type == :rest }.any? ? Float::INFINITY : @implementation.parameters.count
end

def self.min_param_count

def self.min_param_count
  @implementation.parameters.select { |type, _name| type == :req }.count
end

def self.name

def self.name
  @name
end

def type

def type
  ARRAY_RETURN_TYPES.include?(@name) ? :array : :numeric
end

def value(context = {})

def value(context = {})
  args = @args.flatten.map { |a| Dentaku::AST::Function.numeric(a.value(context)) }
  self.class.call(*args)
end