# encoding: utf-8 # frozen_string_literal: true module Carbon module Compiler module Visitor class Preparation include Base require "carbon/compiler/visitor/preparation/expressions" require "carbon/compiler/visitor/preparation/function" require "carbon/compiler/visitor/preparation/statements" require "carbon/compiler/visitor/preparation/struct" include Preparation::Expressions include Preparation::Function include Preparation::Statements include Preparation::Struct def initialize(file, index) @index = index @file = file @name = @file.module @directives = [] @_funcs = {} @context = :normal end def call(node) accept(node) end Preparation.on Concrete::Type => :visit_type def visit_type(node) node.sub(@file.aliases) end Preparation.on Node::Root => :visit_root def visit_root(node) node.map! { |c| accept(c) } end Preparation.on Node::Definition::Module => :visit_module def visit_module(node) error_mismatched_name(node) if node.name != @name error_multiple_modules(node) if @_name @_name = node @file.module = @name = node.name node end Preparation.on Node::Definition::Directive => :visit_directive def visit_directive(node) directive = Compiler::Directive.new(node, @file, @index) @directives << node if directive.attach? directive.call node end private def directives_pop directives = @directives.clone @directives.clear directives end def error_mismatched_name(node) @file.emit("Module/Definition/MismatchedName", node.location, [@name, node.name]) end def error_multiple_modules(node) @file.emit("Module/Definition/MultipleNames", node.location) @file.emit("Trace/Location", @_name.location, "previous name here") end def error_multiple_data(node) @file.emit("Module/Definition/MultipleData", node.location) @file.emit("Trace/Location", @_data.location, "previous data definition here") end end end end end