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
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>]
The instruction id counter.
@return [Counter]
Public Class Methods
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
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
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
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
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
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
# 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