class Carbon::Tacky::Function

A pseudo function. This is used for definitions in order to better serialize them. However, each instruction uses a {Concrete::Type} instead of the LLVM type that it corresponds to, allowing expansion only upon generation.

@api semiprivate

Attributes

blocks[R]

The basic blocks of the function. The first block is expected to be the entry block; the rest can be in any order.

@return [<Tacky::Block>]

counter[R]

The instruction id counter.

@return [Counter]

Public Class Methods

new(parameters, blocks = []) click to toggle source

Creates a function with the given parameters and blocks. The parameters are required; the blocks should not be given.

@param parameters [<Concrete::Type>] The parameters that are passed

to the function.

@param blocks [<Tacky::Block>] Should not be used.

# File lib/carbon/tacky/function.rb, line 30
def initialize(parameters, blocks = [])
  @blocks = blocks
  @parameters = parameters
  @counter = Counter.new
  params
  freeze
  build(&Proc.new) if block_given?
end

Public Instance Methods

add(name = "") click to toggle source

Creates a new {Tacky::Block} with the given name, adding it to the block list, and returns it.

@param name [::String] The name of the new block. @return [Tacky::Block] The new block.

# File lib/carbon/tacky/function.rb, line 44
def add(name = "")
  block = Block.new(self, name)
  @blocks << block
  block
end
call(function, build, generics) click to toggle source

Creates the function for LLVM. This has three main steps: first, mark the function parameters with names. Second, create the function blocks for instructional use. Third, call the constituant blocks for them to build themselves.

@api private @param function [::LLVM::Function] The LLVM function. @param build [Concrete::Build] The build. This should contain all

relevant information for building this function.

@param generics [{::String => Concrete::Type}] The generics that are

being applied to the function.

@return [void]

# File lib/carbon/tacky/function.rb, line 83
def call(function, build, generics)
  context = Context.new(self, build, generics)
  mark_function_params(context, function)

  @blocks.each do |block|
    context.blocks[block] = function.basic_blocks.append(block.name)
  end.each { |block| block.call(context) }
end
dependencies() click to toggle source

Returns a set of dependencies that the function depends on. The set is built by asking the constituant blocks for their dependencies, and merging them all into one set. If no blocks exist, or there are no dependencies, an empty set is returned.

@api private @return [Set<Concrete::Type>] The dependencies of the function.

# File lib/carbon/tacky/function.rb, line 67
def dependencies
  @blocks.map(&:dependencies).inject(Set.new, :merge)
end
find(name) click to toggle source

Finds the block with the given name, if it exists. Note that multiple blocks can have the same name and still be disparate.

@param name [::String] The name of the block to find. @return [Tacky::Block] If the block can be found. @return [nil] Otherwise.

# File lib/carbon/tacky/function.rb, line 56
def find(name)
  @blocks.find { |b| b.name == name }
end
params() click to toggle source

The parameters of the function. These are enclosed with a {Tacky::Parameter} to allow the name of said parameters to be set. The parameters are given an index and a type.

@return [Tacky::Parameter]

# File lib/carbon/tacky/function.rb, line 97
def params
  @params ||= @parameters.each_with_index.map do |type, i|
    Tacky::Parameter.new(i, type)
  end
end

Private Instance Methods

mark_function_params(context, function) click to toggle source
# File lib/carbon/tacky/function.rb, line 105
def mark_function_params(context, function)
  params.zip(function.params).each do |(param, arg)|
    arg.name = param.name
    context.params << arg
  end
end