module Carbon::Core::Integer::Cast

Defines cast functions for integers. This applies to all integers. This guarentees that the following functions exist on all integers:

These functions upcast and downcast as nessicary, but use the sign of the original number to determine how the casting should be handled. For example, an `Int32` is upcast to a `UInt64` using the sign-extension instruction; however, a `UInt32` is upcast to a `Int32` using the zero-extension instruction. This is to keep the same number as the value, but just converted to a longer number. This is in line with the behavior of C.

@api private

Public Instance Methods

define_cast_function(from, to) click to toggle source

Defines a cast function for a single pair of integers.

@param from [Core::Int] The source integer. @param to [Core::Int] The destination integer. @return [void]

# File lib/carbon/core/integer/cast.rb, line 34
def define_cast_function(from, to)
  function_name = from.name.call(to.cast, [from.name])
  Core.define(function: function_name) do |function|
    function[:return] = to.name
    perform_cast(from, to, function[:definition])
  end
end

Private Instance Methods

downcast(entry, this, to) click to toggle source
# File lib/carbon/core/integer/cast.rb, line 73
def downcast(entry, this, to)
  entry.ret(entry.trunc(this, to).as(this.type))
end
perform_cast(from, to, definition) click to toggle source

rubocop:disable Metrics/AbcSize rubocop:disable Metrics/MethodLength

# File lib/carbon/core/integer/cast.rb, line 46
def perform_cast(from, to, definition)
  entry = definition.add("entry").build
  this = definition.params[0]
  this.name = "self"

  # from <=> to -> from - to
  case [from.sign, from.size <=> to.size]
  when [:unsigned, 0], [:signed, 0]
    sidecast(entry, this, to.name)
  when [:unsigned, 1], [:signed, 1]
    downcast(entry, this, to.name)
  when [:unsigned, -1]
    upcast_unsigned(entry, this, to.name)
  when [:signed, -1]
    upcast_signed(entry, this, to.name)
  else fail # no way you can get here
  end
end
sidecast(entry, this, to) click to toggle source
# File lib/carbon/core/integer/cast.rb, line 77
def sidecast(entry, this, to)
  entry.ret(entry.int_cast(this, to).as(this.type))
end
upcast_signed(entry, this, to) click to toggle source
# File lib/carbon/core/integer/cast.rb, line 65
def upcast_signed(entry, this, to)
  entry.ret(entry.sext(this, to).as(this.type))
end
upcast_unsigned(entry, this, to) click to toggle source
# File lib/carbon/core/integer/cast.rb, line 69
def upcast_unsigned(entry, this, to)
  entry.ret(entry.zext(this, to).as(this.type))
end