class AutoC::Value::Parameter

@private Function parameter

Attributes

name[R]
value[R]

Public Class Methods

new(value, name) click to toggle source
# File lib/autoc/function.rb, line 59
def initialize(value, name)
  @value = value.to_value
  @name = name.to_sym
end

Public Instance Methods

declaration(= '%s %s' % [signature, name]) click to toggle source
# File lib/autoc/function.rb, line 70
  def declaration = '%s %s' % [signature, name]

end
signature(= value.signature) click to toggle source
# File lib/autoc/function.rb, line 68
  def signature = value.signature

  def declaration = '%s %s' % [signature, name]

end # Parameter


# Standalone C side function
# The generated function is meant to be the C89-compliant
# NOTE: This function does not track parameter and result types as its dependencies
# This can be done manually by appending to #dependencies property with <<
class Function

  include Entity
  
  attr_reader :name

  attr_reader :result

  attr_reader :parameters

  attr_reader :visibility

  attr_writer :inline

  def initialize(result, name, parameters, inline: false, visibility: :public, constraint: true, variadic: false, abstract: false)
    @name = name.to_s
    @result = result
    @inline = inline
    @visibility = visibility
    @constraint = constraint
    @abstract = abstract
    @variadic = variadic
    @parameters = Parameters.new(self)
    if parameters.is_a?(Hash)
      parameters.each do |name, descriptor|
        x = Parameter.new(descriptor, name)
        @parameters[x.name] = x
      end
    else
      i = -1
      parameters.each do |descriptor|
        x = Parameter.new(descriptor, "_#{i+=1}")
        @parameters[x.name] = x
      end
    end
  end

  def inline_code(code)
    @inline = true
    code(code)
  end

  def external_code(code)
    @inline = false
    code(code)
  end

  def to_s = name

  def header(header) = @header = header

  def code(code) = @code = code

  def inspect = "#{prototype} <#{self.class}>"

  def inline? = @inline == true

  def public? = @visibility == :public

  def private? = @visibility == :private

  def internal? = @visibility == :internal
  
  def abstract? = @abstract == true

  def variadic? = @variadic == true

  def live? = (@constraint.is_a?(Proc) ? @constraint.() : @constraint) == true
  
  def signature = '%s(%s)' % [result, (parameters.to_a.collect(&:signature) << (variadic? ? '...' : nil)).compact.join(',')]

  def prototype = '%s %s(%s)' % [result, name, (parameters.to_a.collect(&:declaration) << (variadic? ? '...' : nil)).compact.join(',')]

  def definition = '%s {%s}' % [prototype, @code]

  def parameter(name) = @values[name]

  def call(*arguments)
    xs = []
    ps = parameters.to_a
    (0...arguments.size).each do |i|
      a = arguments[i]
      v = a.is_a?(Parameter) ? a.to_value_argument : a
      xs << (i < ps.size ? ps[i].value.(v) : v)
    end
    '%s(%s)' % [name, xs.join(',')]
  end

  def configure(&block)
    instance_eval(&block)
    self
  end
  
  # This allows to call other functions with this function's individual parameters as arguments
  # A call to unknown method results in the method's name being emitted
  def method_missing(meth, *args) = parameters.has_key?(meth) ? parameters[meth] : meth

private

  # On function inlining in C: http://www.greenend.org.uk/rjk/tech/inline.html

  # static inline seems to be THE most portable way without resorting to preprocessor
  # but consider the possible code bloat it incurs

  def render_declaration_specifier(stream)
    # The inline specifier is not a part of C89 yet descent compilers do inlining at will
    # given the function definition is available at the function call
    stream << 'static ' if inline?
  end

  # Render the commentary block preceding the function declaration, both inline or external
  def render_function_header(stream)
    if public?
      stream << %{
        /* #{@header} */
      } unless @header.nil?
    else
      stream << Composite::PRIVATE
    end
  end

  # Render full function declaration statement including the commentary block
  # For inline functions this also renders a function body effectively making this also a function definition
  # The declaration comes into either public interface of forward declaration block depending on the function's visibility status
  def render_function_declaration(stream)
    render_function_header(stream) if @render_interface
    render_declaration_specifier(stream)
    if inline?
      render_function_definition(stream)
    else
      stream << prototype << ';'
    end
  end

  # Render function definition, both inline or extern
  # This code never gets into public interface
  def render_function_definition(stream)
    unless abstract?
      raise("missing function definition for #{name}()") if @code.nil?
      stream << definition
    end
  end

  # Render function's public interface
  # Render non-internal function declarations
  # @render_interface is used internally to distinguish header-time rendering from source-time rendering
  def render_interface(stream)
    @render_interface = true
    render_function_declaration(stream) if live? && (public? || private?)
  end

  # Render function's interface for non-public functions which should not appear in the public interface
  def render_forward_declarations(stream)
    @render_interface = false
    render_function_declaration(stream) if live? && !(public? || private?)
  end

  # Render non-inline function definition regardless of function's visibility status
  def render_implementation(stream)
    @render_interface = false
    render_function_definition(stream) if live? && !inline?
  end

end # Function


# @private
# Named parameter list for the function
class Function::Parameters < ::Hash
  def initialize(function)
    @function = function
    super()
  end
  def to_a = values
to_s(= name.to_s) click to toggle source
# File lib/autoc/function.rb, line 64
  def to_s = name.to_s

  def to_value_argument = value.reference? ? "*#{name}" : name

  def signature = value.signature

  def declaration = '%s %s' % [signature, name]

end # Parameter


# Standalone C side function
# The generated function is meant to be the C89-compliant
# NOTE: This function does not track parameter and result types as its dependencies
# This can be done manually by appending to #dependencies property with <<
class Function

  include Entity
  
  attr_reader :name

  attr_reader :result

  attr_reader :parameters

  attr_reader :visibility

  attr_writer :inline

  def initialize(result, name, parameters, inline: false, visibility: :public, constraint: true, variadic: false, abstract: false)
    @name = name.to_s
    @result = result
    @inline = inline
    @visibility = visibility
    @constraint = constraint
    @abstract = abstract
    @variadic = variadic
    @parameters = Parameters.new(self)
    if parameters.is_a?(Hash)
      parameters.each do |name, descriptor|
        x = Parameter.new(descriptor, name)
        @parameters[x.name] = x
      end
    else
      i = -1
      parameters.each do |descriptor|
        x = Parameter.new(descriptor, "_#{i+=1}")
        @parameters[x.name] = x
      end
    end
  end

  def inline_code(code)
    @inline = true
    code(code)
  end

  def external_code(code)
    @inline = false
    code(code)
  end

  def to_s = name

  def header(header) = @header = header

  def code(code) = @code = code

  def inspect = "#{prototype} <#{self.class}>"

  def inline? = @inline == true

  def public? = @visibility == :public

  def private? = @visibility == :private

  def internal? = @visibility == :internal
  
  def abstract? = @abstract == true

  def variadic? = @variadic == true

  def live? = (@constraint.is_a?(Proc) ? @constraint.() : @constraint) == true
  
  def signature = '%s(%s)' % [result, (parameters.to_a.collect(&:signature) << (variadic? ? '...' : nil)).compact.join(',')]

  def prototype = '%s %s(%s)' % [result, name, (parameters.to_a.collect(&:declaration) << (variadic? ? '...' : nil)).compact.join(',')]

  def definition = '%s {%s}' % [prototype, @code]

  def parameter(name) = @values[name]

  def call(*arguments)
    xs = []
    ps = parameters.to_a
    (0...arguments.size).each do |i|
      a = arguments[i]
      v = a.is_a?(Parameter) ? a.to_value_argument : a
      xs << (i < ps.size ? ps[i].value.(v) : v)
    end
    '%s(%s)' % [name, xs.join(',')]
  end

  def configure(&block)
    instance_eval(&block)
    self
  end
  
  # This allows to call other functions with this function's individual parameters as arguments
  # A call to unknown method results in the method's name being emitted
  def method_missing(meth, *args) = parameters.has_key?(meth) ? parameters[meth] : meth

private

  # On function inlining in C: http://www.greenend.org.uk/rjk/tech/inline.html

  # static inline seems to be THE most portable way without resorting to preprocessor
  # but consider the possible code bloat it incurs

  def render_declaration_specifier(stream)
    # The inline specifier is not a part of C89 yet descent compilers do inlining at will
    # given the function definition is available at the function call
    stream << 'static ' if inline?
  end

  # Render the commentary block preceding the function declaration, both inline or external
  def render_function_header(stream)
    if public?
      stream << %{
        /* #{@header} */
      } unless @header.nil?
    else
      stream << Composite::PRIVATE
    end
  end

  # Render full function declaration statement including the commentary block
  # For inline functions this also renders a function body effectively making this also a function definition
  # The declaration comes into either public interface of forward declaration block depending on the function's visibility status
  def render_function_declaration(stream)
    render_function_header(stream) if @render_interface
    render_declaration_specifier(stream)
    if inline?
      render_function_definition(stream)
    else
      stream << prototype << ';'
    end
  end

  # Render function definition, both inline or extern
  # This code never gets into public interface
  def render_function_definition(stream)
    unless abstract?
      raise("missing function definition for #{name}()") if @code.nil?
      stream << definition
    end
  end

  # Render function's public interface
  # Render non-internal function declarations
  # @render_interface is used internally to distinguish header-time rendering from source-time rendering
  def render_interface(stream)
    @render_interface = true
    render_function_declaration(stream) if live? && (public? || private?)
  end

  # Render function's interface for non-public functions which should not appear in the public interface
  def render_forward_declarations(stream)
    @render_interface = false
    render_function_declaration(stream) if live? && !(public? || private?)
  end

  # Render non-inline function definition regardless of function's visibility status
  def render_implementation(stream)
    @render_interface = false
    render_function_definition(stream) if live? && !inline?
  end

end # Function


# @private
# Named parameter list for the function
class Function::Parameters < ::Hash
  def initialize(function)
    @function = function
    super()
  end
  def to_a
to_value_argument(= value.reference? ? "* click to toggle source
# File lib/autoc/function.rb, line 66
  def to_value_argument = value.reference? ? "*#{name}" : name

  def signature = value.signature

  def declaration = '%s %s' % [signature, name]

end # Parameter


# Standalone C side function
# The generated function is meant to be the C89-compliant
# NOTE: This function does not track parameter and result types as its dependencies
# This can be done manually by appending to #dependencies property with <<
class Function

  include Entity
  
  attr_reader :name

  attr_reader :result

  attr_reader :parameters

  attr_reader :visibility

  attr_writer :inline

  def initialize(result, name, parameters, inline: false, visibility: :public, constraint: true, variadic: false, abstract: false)
    @name = name.to_s
    @result = result
    @inline = inline
    @visibility = visibility
    @constraint = constraint
    @abstract = abstract
    @variadic = variadic
    @parameters = Parameters.new(self)
    if parameters.is_a?(Hash)
      parameters.each do |name, descriptor|
        x = Parameter.new(descriptor, name)
        @parameters[x.name] = x
      end
    else
      i = -1
      parameters.each do |descriptor|
        x = Parameter.new(descriptor, "_#{i+=1}")
        @parameters[x.name] = x
      end
    end
  end

  def inline_code(code)
    @inline = true
    code(code)
  end

  def external_code(code)
    @inline = false
    code(code)
  end

  def to_s = name

  def header(header) = @header = header

  def code(code) = @code = code

  def inspect = "#{prototype} <#{self.class}>"

  def inline? = @inline == true

  def public? = @visibility == :public

  def private? = @visibility == :private

  def internal? = @visibility == :internal
  
  def abstract? = @abstract == true

  def variadic? = @variadic == true

  def live? = (@constraint.is_a?(Proc) ? @constraint.() : @constraint) == true
  
  def signature = '%s(%s)' % [result, (parameters.to_a.collect(&:signature) << (variadic? ? '...' : nil)).compact.join(',')]

  def prototype = '%s %s(%s)' % [result, name, (parameters.to_a.collect(&:declaration) << (variadic? ? '...' : nil)).compact.join(',')]

  def definition = '%s {%s}' % [prototype, @code]

  def parameter(name) = @values[name]

  def call(*arguments)
    xs = []
    ps = parameters.to_a
    (0...arguments.size).each do |i|
      a = arguments[i]
      v = a.is_a?(Parameter) ? a.to_value_argument : a
      xs << (i < ps.size ? ps[i].value.(v) : v)
    end
    '%s(%s)' % [name, xs.join(',')]
  end

  def configure(&block)
    instance_eval(&block)
    self
  end
  
  # This allows to call other functions with this function's individual parameters as arguments
  # A call to unknown method results in the method's name being emitted
  def method_missing(meth, *args) = parameters.has_key?(meth) ? parameters[meth] : meth

private

  # On function inlining in C: http://www.greenend.org.uk/rjk/tech/inline.html

  # static inline seems to be THE most portable way without resorting to preprocessor
  # but consider the possible code bloat it incurs

  def render_declaration_specifier(stream)
    # The inline specifier is not a part of C89 yet descent compilers do inlining at will
    # given the function definition is available at the function call
    stream << 'static ' if inline?
  end

  # Render the commentary block preceding the function declaration, both inline or external
  def render_function_header(stream)
    if public?
      stream << %{
        /* #{@header} */
      } unless @header.nil?
    else
      stream << Composite::PRIVATE
    end
  end

  # Render full function declaration statement including the commentary block
  # For inline functions this also renders a function body effectively making this also a function definition
  # The declaration comes into either public interface of forward declaration block depending on the function's visibility status
  def render_function_declaration(stream)
    render_function_header(stream) if @render_interface
    render_declaration_specifier(stream)
    if inline?
      render_function_definition(stream)
    else
      stream << prototype << ';'
    end
  end

  # Render function definition, both inline or extern
  # This code never gets into public interface
  def render_function_definition(stream)
    unless abstract?
      raise("missing function definition for #{name}()") if @code.nil?
      stream << definition
    end
  end

  # Render function's public interface
  # Render non-internal function declarations
  # @render_interface is used internally to distinguish header-time rendering from source-time rendering
  def render_interface(stream)
    @render_interface = true
    render_function_declaration(stream) if live? && (public? || private?)
  end

  # Render function's interface for non-public functions which should not appear in the public interface
  def render_forward_declarations(stream)
    @render_interface = false
    render_function_declaration(stream) if live? && !(public? || private?)
  end

  # Render non-inline function definition regardless of function's visibility status
  def render_implementation(stream)
    @render_interface = false
    render_function_definition(stream) if live? && !inline?
  end

end # Function


# @private
# Named parameter list for the function
class Function::Parameters < ::Hash
  def initialize(function)
    @function = function
    super()
  end
  def to_a =