class AutoC::Value::Parameter::Function

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 <<

Attributes

inline[W]
name[R]
parameters[R]
result[R]
visibility[R]

Public Class Methods

new(result, name, parameters, inline: false, visibility: :public, constraint: true, variadic: false, abstract: false) click to toggle source
# File lib/autoc/function.rb, line 93
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

Public Instance Methods

abstract?(= @abstract == true) click to toggle source
# File lib/autoc/function.rb, line 142
  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
  def [](name)
    raise "unknown parameter #{name} in function #{@function}()" unless has_key?(name)
call(*arguments) click to toggle source
# File lib/autoc/function.rb, line 156
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
code(code) click to toggle source
# File lib/autoc/function.rb, line 130
  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
  def [](name)
configure(&block) click to toggle source
# File lib/autoc/function.rb, line 167
def configure(&block)
  instance_eval(&block)
  self
end
definition(= '%s {%s}' % [prototype, @code]) click to toggle source
# File lib/autoc/function.rb, line 152
  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
  def [](name)
    raise "unknown parameter #{name} in function #{@function}()" unless has_key?(name)
    super
  end
end 
external_code(code) click to toggle source
# File lib/autoc/function.rb, line 121
def external_code(code)
  @inline = false
  code(code)
end
header(header) click to toggle source
# File lib/autoc/function.rb, line 128
  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
  def [](
inline?(= @inline == true) click to toggle source
# File lib/autoc/function.rb, line 134
  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
  def [](name)
    raise 
inline_code(code) click to toggle source
# File lib/autoc/function.rb, line 116
def inline_code(code)
  @inline = true
  code(code)
end
inspect(= " click to toggle source
# File lib/autoc/function.rb, line 132
  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
  def [](name)
    
internal?(= @visibility == :internal) click to toggle source
# File lib/autoc/function.rb, line 140
  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
  def [](name)
    raise "unknown parameter #{name} in function #{@function}()" unless has_key?(
live?(= (@constraint.is_a?(Proc) ? @constraint.() : @constraint) == true) click to toggle source
# File lib/autoc/function.rb, line 146
  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
  def [](name)
    raise "unknown parameter #{name} in function #{@function}()" unless has_key?(name)
    super
method_missing(meth, *args) click to toggle source

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

# File lib/autoc/function.rb, line 174
  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
parameter(name) click to toggle source
# File lib/autoc/function.rb, line 154
  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
  def [](name)
    raise "unknown parameter #{name} in function #{@function}()" unless has_key?(name)
    super
  end
end # Parameters

private?(= @visibility == :private) click to toggle source
# File lib/autoc/function.rb, line 138
  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
  def [](name)
    raise "unknown parameter #{name} in function #{@function}()" unless 
prototype(= '%s %s(%s)' % [result, name, (parameters.to_a.collect(&:declaration) << (variadic? ? '...' : nil)).compact.join(',')]) click to toggle source
# File lib/autoc/function.rb, line 150
  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
  def [](name)
    raise "unknown parameter #{name} in function #{@function}()" unless has_key?(name)
    super
  end
public?(= @visibility == :public) click to toggle source
# File lib/autoc/function.rb, line 136
  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
  def [](name)
    raise "unknown parameter #{name} in function #{@function}()" 
render_declaration_specifier(stream) click to toggle source

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

# File lib/autoc/function.rb, line 183
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_forward_declarations(stream) click to toggle source

Render function’s interface for non-public functions which should not appear in the public interface

# File lib/autoc/function.rb, line 231
def render_forward_declarations(stream)
  @render_interface = false
  render_function_declaration(stream) if live? && !(public? || private?)
end
render_function_declaration(stream) click to toggle source

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

# File lib/autoc/function.rb, line 203
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(stream) click to toggle source

Render function definition, both inline or extern This code never gets into public interface

# File lib/autoc/function.rb, line 215
def render_function_definition(stream)
  unless abstract?
    raise("missing function definition for #{name}()") if @code.nil?
    stream << definition
  end
end
render_function_header(stream) click to toggle source

Render the commentary block preceding the function declaration, both inline or external

# File lib/autoc/function.rb, line 190
def render_function_header(stream)
  if public?
    stream << %{
      /* #{@header} */
    } unless @header.nil?
  else
    stream << Composite::PRIVATE
  end
end
render_implementation(stream) click to toggle source

Render non-inline function definition regardless of function’s visibility status

# File lib/autoc/function.rb, line 237
def render_implementation(stream)
  @render_interface = false
  render_function_definition(stream) if live? && !inline?
end
render_interface(stream) click to toggle source

Render function’s public interface Render non-internal function declarations @render_interface is used internally to distinguish header-time rendering from source-time rendering

# File lib/autoc/function.rb, line 225
def render_interface(stream)
  @render_interface = true
  render_function_declaration(stream) if live? && (public? || private?)
end
signature(= '%s(%s)' % [result, (parameters.to_a.collect(&:signature) << (variadic? ? '...' : nil)).compact.join(',')]) click to toggle source
# File lib/autoc/function.rb, line 148
  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
  def [](name)
    raise "unknown parameter #{name} in function #{@function}()" unless has_key?(name)
    super
  end
to_s(= name) click to toggle source
# File lib/autoc/function.rb, line 126
  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
  def 
variadic?(= @variadic == true) click to toggle source
# File lib/autoc/function.rb, line 144
  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
  def [](name)
    raise "unknown parameter #{name} in function #{@function}()" unless has_key?(name)