# encoding: utf-8 # frozen_string_literal: true module Carbon module Compiler module Visitor class Generation module Class Generation.on Node::Definition::Class => :visit_class def visit_class(node) @index.define(class: @name) do |cl| cl[:elements] = node.each end class_accessors(node) class_allocate(node) end private def class_allocate(node) fname = @name.call("allocate", []) @index.define(function: fname) do |function| function[:return] = @name class_allocate_definition(function[:definition]) end end def class_accessors(node) node.each_with_index do |element, index| class_read_accessor(element, index, node) class_write_accessor(element, index, node) end end def class_read_accessor(element, index, node) fname = @name.call(element.name.value, [@name]) @index.define(function: fname) do |function| function[:return] = element.type class_read_accessor_definition(function[:definition], element, index) end fname = @name.call("@#{element.name.value}", [@name]) @index.define(function: fname) do |function| function[:return] = element.type class_read_accessor_definition(function[:definition], element, index) end end def class_write_accessor(element, index, node) fname = @name.call("#{element.name.value}=", [@name, element.type]) @index.define(function: fname) do |function| function[:return] = element.type class_write_accessor_definition(function[:definition], element, index) end fname = @name.call("@#{element.name.value}=", [@name, element.type]) @index.define(function: fname) do |function| function[:return] = element.type class_write_accessor_definition(function[:definition], element, index) end end def class_read_accessor_definition(definition, element, index) entry = definition.add("entry").build this = definition.params[0] this.name = "self" gep = entry.class_gep(this, index).as(this.type) entry.ret(entry.load(gep).as(element.type)) end def class_write_accessor_definition(definition, element, index) entry = definition.add("entry").build this, value = definition.params this.name, value.name = %w(self value) gep = entry.class_gep(this, index).as(this.type) entry.store(value, gep) entry.ret(value) end def class_allocate_definition(definition) entry = definition.add("entry").build entry.ret(entry.malloc(entry.deref(@name).as(@name)).as(@name)) end end end end end end