module Risc

  # A label is a placeholder for it's next Instruction
  # It's function is not to turn into code, but to be a valid branch target
  # Labels have the same position as their next instruction (See positioning code)
  #
  # So branches and Labels are pairs, fan out, fan in
  #
  # For a return, the address (position) of the label has to be loaded.
  # So a Label carries the ReturnAddress constant that holds the address (it's own
  # position, again see positioning code).
  # But currently the label is used in the Risc abstraction layer, and in the
  # arm/interpreter layer. The integer is only used in the lower layer, but needs
  # to be created (and positioned)

  class Label < Instruction
    # See class description. also factory method Risc.label below
    def initialize( source , name , addr , nekst = nil)
      super(source , nekst)
      @name = name
      @address = addr
      raise "Not address #{addr}" unless addr.is_a?(Parfait::ReturnAddress)
    end
    attr_reader :name , :address

    def to_cpu(translator)
      @cpu_label ||= super
    end

    def to_s
      class_source "#{@name} (next: #{self.next.class.name.split("::").last})"
    end

    def rxf_reference_name
      @name
    end

    # a method start has a label of the form Class.method , test for that
    def is_method
      @name.split(".").length == 2
    end

    def assemble_all( io )
      self.each {|ins| ins.assemble(io)}
    end

    def assemble io
    end

    def total_byte_length
      ret = 0
      self.each{|ins| ret += ins.byte_length}
      ret
    end

    # shame we need this, just for logging
    def byte_length
      0
    end
    alias :padded_length  :byte_length
  end

  # Labels carry what is esentially an integer constant
  # The int holds the labels position for use at runtime (return address)
  # An integer is plucked from object_space abd added to the machine constant pool
  # if none was given
  def self.label( source , name , position = nil , nekst = nil)
    position = Parfait.object_space.get_address unless position
    Label.new( source , name , position, nekst )
  end
end