module Carbon::Core::Pointer::Math

Defines pointer arithmatic. This allows for addition and subtraction, as well as comparison. This module defines the following functions:

These are defined for all integers except boolean.

Constants

COMP_OPERATIONS

The comparison operations that can be applied to pointers.

@return [<::Symbol>]

MATH_OPERATIONS

The math operations that can be applied to pointers.

@return [<::Symbol>]

Public Instance Methods

define_comp_function(int, op) click to toggle source

Defines a given comparison operation on a pointer.

@param int [Core::Int] The integer type that the operation uses. @param op [::Symbol] The comparison operation to perform. This should

be one of {COMP_OPERATIONS}.
# File lib/carbon/core/pointer/math.rb, line 124
def define_comp_function(int, op)
  function_name = PTYPE.call(op, [PTYPE, int.name])
  Core.define(function: function_name) do |function|
    function[:return] = Carbon::Boolean
    define_comp_definition(int, op, function[:definition])
  end
end
define_comp_pointer_function(op) click to toggle source

Defines a comparison function for two pointers.

@param op [::Symbol] The operation that the function performs.

This should be one of {COMP_OPERATIONS}.

@return [void]

# File lib/carbon/core/pointer/math.rb, line 83
def define_comp_pointer_function(op)
  function_name = PTYPE.call(op, [PTYPE, PTYPE])
  Core.define(function: function_name) do |function|
    function[:return] = Carbon::Boolean
    define_comp_pointer_definition(op, function[:definition])
  end
end
define_math_function(int, op) click to toggle source

Defines a given math function on a pointer.

@param int [Core::Int] The integer type that the operation uses. @param op [::Symbol] The math operation to perform. This should be

one of {MATH_OPERATIONS}.

@return [void]

# File lib/carbon/core/pointer/math.rb, line 111
def define_math_function(int, op)
  function_name = PTYPE.call(op, [PTYPE, int.name])
  Core.define(function: function_name) do |function|
    function[:return] = PTYPE
    define_math_definition(int, op, function[:definition])
  end
end
define_math_functions() click to toggle source

Comprehensively defines all of the math, comparison, and spaceship operations for pointers.

@see define_math_function @see define_comp_function @see define_space_function @see define_comp_pointer_function @see define_space_pointer_function @return [void]

# File lib/carbon/core/pointer/math.rb, line 44
def define_math_functions
  Ints.each do |int|
    next if int.size == 1
    MATH_OPERATIONS.each { |op| define_math_function(int, op) }
    COMP_OPERATIONS.each { |op| define_comp_function(int, op) }
    define_space_function(int)
  end

  COMP_OPERATIONS.each { |op| define_comp_pointer_function(op) }
  define_space_pointer_function
  define_null_function
end
define_null_function() click to toggle source
# File lib/carbon/core/pointer/math.rb, line 57
def define_null_function
  function_name = PTYPE.call(:null, [])
  Core.define(function: function_name) do |function|
    function[:return] = PTYPE
    define_null_definition(function[:definition])
  end
end
define_space_function(int) click to toggle source

Defines the space function (`<=>`) for a pointer and an integer. It returns `-1`, `0`, or `1`, if the receiver is less than, equal to, or greater than the parameter, respectively.

@param int [Core::Int] The integer type to compare to. @return [void]

# File lib/carbon/core/pointer/math.rb, line 97
def define_space_function(int)
  function_name = PTYPE.call(:<=>, [PTYPE, int.name])
  Core.define(function: function_name) do |function|
    function[:return] = Carbon::Type("Carbon::Int8")
    define_space_definition(int, function[:definition])
  end
end
define_space_pointer_function() click to toggle source

Defines the `<=>` function for two pointers. This returns `-1`, `0`, or `1`, if the receiver is less than, equal to, or greater than the parameter, respectively.

@return [void]

# File lib/carbon/core/pointer/math.rb, line 70
def define_space_pointer_function
  function_name = PTYPE.call(:<=>, [PTYPE, PTYPE])
  Core.define(function: function_name) do |function|
    function[:return] = Carbon::Type("Carbon::Int8")
    define_space_pointer_definition(function[:definition])
  end
end

Private Instance Methods

define_comp_definition(int, op, definition) click to toggle source
# File lib/carbon/core/pointer/math.rb, line 176
def define_comp_definition(int, op, definition)
  entry = definition.add("entry").build
  this, other = definition.params
  this.name, other.name = %w(self other)

  fname = PTYPE.call(int.cast, [PTYPE])
  intptr = entry.call(fname, this).as(int.name)
  icmp = Integer::Math::COMP_OPERATIONS_MAP.fetch([int.sign, op])
  entry.ret(entry.icmp(icmp, intptr, other).as(Carbon::Boolean))
end
define_comp_pointer_definition(op, definition) click to toggle source
# File lib/carbon/core/pointer/math.rb, line 154
def define_comp_pointer_definition(op, definition)
  entry = definition.add("entry").build
  params = definition.params
  int = Ints.find { |i| i.sign == :signed && i.size == 64 }
  this, other = perform_pointer_cast(entry, params, int)
  icmp = Integer::Math::COMP_OPERATIONS_MAP.fetch([:signed, op])

  entry.ret(entry.icmp(icmp, this, other).as(Carbon::Boolean))
end
define_math_definition(_int, op, definition) click to toggle source
# File lib/carbon/core/pointer/math.rb, line 187
def define_math_definition(_int, op, definition)
  entry = definition.add("entry").build
  this, other = definition.params
  this.name, other.name = %w(self other)
  other = entry.mul(other, -1).as(other.type) if op == :-

  entry.ret(entry.gep(this, other).as(PTYPE))
end
define_null_definition(definition) click to toggle source
# File lib/carbon/core/pointer/math.rb, line 196
def define_null_definition(definition)
  entry = definition.add("entry").build
  entry.ret(entry.null(PTYPE).as(PTYPE))
end
define_space_definition(int, definition) click to toggle source
# File lib/carbon/core/pointer/math.rb, line 164
def define_space_definition(int, definition)
  entry = definition.add("entry").build
  this, other = definition.params
  this.name, other.name = %w(self other)

  fname = PTYPE.call(int.cast, [PTYPE])
  intptr = entry.call(fname, this).as(int.name)
  fname = PTYPE.call(:<=>, [int.name, int.name])
  compare = entry.call(fname, intptr, other)
  entry.ret(compare.as(Carbon::Type("Carbon::Int8")))
end
define_space_pointer_definition(definition) click to toggle source
# File lib/carbon/core/pointer/math.rb, line 143
def define_space_pointer_definition(definition)
  entry = definition.add("entry").build
  params = definition.params
  int = Int.find(sign: :signed, size: 64)
  this, other = perform_pointer_cast(entry, params, int)

  fname = PTYPE.call(:<=>, [int.name, int.name])
  call = entry.call(fname, this, other)
  entry.ret(call.as(Carbon::Type("Carbon::Int8")))
end
perform_pointer_cast(entry, params, int) click to toggle source
# File lib/carbon/core/pointer/math.rb, line 134
def perform_pointer_cast(entry, params, int)
  this, other = params
  this.name, other.name = %w(self other)
  fname = PTYPE.call(int.cast, [PTYPE])
  thisint = entry.call(fname, this).as(int.name)
  otherint = entry.call(fname, other).as(int.name)
  [thisint, otherint]
end