# encoding: utf-8 # frozen_string_literal: true module Carbon module Concrete # Handles building requests. This is the step after all requests are # determined from the dependency build stage. The entire purpose of this # class is to consolidate state information for LLVM module building. # # @api semiprivate class Build # The types that have been defined. This is a mapping of the # {Concrete::Type} to an arry of the {Concrete::Item} and the # corresponding `LLVM::Type`. This is so that no information is lost # when converting the item to the type. # # @return [{Concrete::Type => (Concrete::Item, ::LLVM::Type)}] attr_reader :types # The functions that have been defined. This is a mapping of the # {Concrete::Type} to the `LLVM::Function` that was defined. # # @return [{Concrete::Type => ::LLVM::Function}] attr_reader :functions # The LLVM module that is being used for compilation. # # @return [::LLVM::Module] attr_reader :module # Initialize the build process. This only initializes instance # variables. # # @param requests [::Enumerable] An enumerable over # each request that needs to be built. The requests should be # resolved, i.e. the generics for the request should resolve to a # valid type. # @param index [Concrete::Index] The index that is being built from. def initialize(requests, index) @requests = requests @index = index end # Performs the build process. Builds each request in order by calling # {Concrete::Item::Base#call} on each. # # @return [::LLVM::Module] The built module. def call @types = {} @functions = {} @module = ::LLVM::Module.new("__carbon_main") @requests.each do |request| item = @index.fetch(request.intern) generics = item.generics.zip(request.generics).to_h item.call(self, generics) end @module end end end end