module Carbon::Core::Integer::Ship

Defines the “spaceship” function on all integers except booleans. The spaceship operator compares two integers, and returns three possible values depending on the order of the integers: `1` if the receiver (`this`) is greater than the right (`other`), `0` if `this` is equal to `other`, and `-1` if `this` is less than `other`. This is useful for determining the order of things. This module defines a single function on all integers except boolean:

The function returns `Carbon::Int8` because it is the smallest possible integer type that retains sign information.

Public Instance Methods

define_ship_function(left, right) click to toggle source

Defines the spaceship function (`:<=>`). The left and right integer types are given. The spaceship function works the same as the one in Ruby:

  • If the left value is less than the right value, return -1; otherwise,

  • If the left value is equal to the right value, return 0; otherwise,

  • The left value is greater than the right value, return 1.

@param left [Core::Int] The left (receiver) value. @param right [Core::Int] The right value. @return [void]

# File lib/carbon/core/integer/ship.rb, line 33
def define_ship_function(left, right)
  return if left.size == 1 || right.size == 1
  function_name = left.name.call(:<=>, [left.name, right.name])
  Core.define(function: function_name) do |function|
    function[:return] = Carbon::Type("Carbon::Int8")
    define_ship_definition(left, right, function[:definition])
  end
end

Private Instance Methods

define_ship_definition(left, right, definition) click to toggle source
# File lib/carbon/core/integer/ship.rb, line 44
def define_ship_definition(left, right, definition)
  blocks =
    %w(entry this<other this!<other this=other this>other)
      .map { |n| definition.add(n) }
  params = definition.params
  params[0].name, params[1].name = %w(self other)
  params = force_same_cast(params, blocks[0].build, left, right)

  define_ship_definition_returns(blocks)
  define_ship_definition_compare(params, blocks)
end
define_ship_definition_compare(params, blocks) click to toggle source
# File lib/carbon/core/integer/ship.rb, line 62
def define_ship_definition_compare(params, blocks)
  blocks[0]
    .build do |b|
      b.br(b.icmp(:lt, *params).as(Carbon::Boolean),
        blocks[1], blocks[2])
    end
  blocks[2]
    .build do |b|
      b.br(b.icmp(:eq, *params).as(Carbon::Boolean),
        blocks[3], blocks[4])
    end
end
define_ship_definition_returns(blocks) click to toggle source
# File lib/carbon/core/integer/ship.rb, line 56
def define_ship_definition_returns(blocks)
  blocks[1].build.ret(1)
  blocks[3].build.ret(0)
  blocks[4].build.ret(-1)
end