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 =