Class: Mirah::JVM::Types::Number

Inherits:
PrimitiveType show all
Defined in:
lib/mirah/jvm/types/number.rb

Direct Known Subclasses

FloatType, IntegerType, LongType

Constant Summary collapse

TYPE_ORDERING =
['byte', 'short', 'int', 'long', 'float', 'double']

Constants inherited from PrimitiveType

PrimitiveType::WIDENING_CONVERSIONS

Constants included from Logging::Logged

Logging::Logged::VLEVELS

Instance Attribute Summary

Attributes inherited from Type

#inner_class, #name, #type_system

Instance Method Summary collapse

Methods inherited from PrimitiveType

#box, #box_type, #convertible_to?, #initialize, #interfaces, #newarray, #primitive?, #primitive_type, #superclass, #wrapper_name

Methods inherited from Type

#abstract?, #add_compiled_macro, #add_enumerable_macros, #add_method, #add_method_listener, #aload, #ancestors_and_interfaces, #array?, #array_type, #assignableFrom, #assignable_from?, #astore, #basic_type, #class_id, #compatible?, #component_type, #constructor, #declared_class_methods, #declared_constructors, #declared_instance_methods, #declared_intrinsics, #declared_macros, #dynamic?, #error?, #expand_each, #field_getter, #field_setter, #find_callable_macros, #find_callable_macros2, #find_callable_methods, #find_callable_methods2, #find_callable_static_methods, #flags, #full_name, #generic, #generic?, #getAsmType, #getDeclaredField, #getDeclaredFields, #get_method, #hasStaticField, #include, #init_value, #initialize, #inner_class?, #inner_class_getter, #inspect, #interface?, #interfaces, #internal_name, #intrinsics, #isAnnotation, #isArray, #isBlock, #isEnum, #isError, #isGeneric, #isMeta, #isPrimitive, #is_parent, #iterable?, #java_method, #jvm_type, #load, #load_extensions, #macro, #macros, #matchesAnything, #meta, #meta?, #method_listeners, #method_updated, #newarray, #pop, #prefix, #primitive?, #read_macrodef_annotation, #retention, #return, #store, #superclass, #to_s, #type_parameters, #ungeneric, #unmeta, #void?, #wide?, #widen

Methods included from Logging::Logged

#error, #info, #log, #logger, #logger_name, #logging?, #vlog, #warning

Methods included from MethodLookup

#each_is_exact, #each_is_exact_or_subtype_or_convertible, #field_lookup, #find_jls, #find_jls2, #find_method, #find_method2, #inner_class, #is_more_specific?, #phase1, #phase2, #phase3, #primitive_convertible?

Constructor Details

This class inherits a constructor from Mirah::JVM::Types::PrimitiveType

Instance Method Details

#add_delegates(name, return_type = nil) ⇒ Object



93
94
95
96
97
98
99
100
# File 'lib/mirah/jvm/types/number.rb', line 93

def add_delegates(name, return_type = nil)
  index = TYPE_ORDERING.index(math_type.name)
  larger_types = TYPE_ORDERING[index + 1, TYPE_ORDERING.size]
  larger_types.each do |type|
    type = @type_system.type(nil, type)
    delegate_intrinsic(name, type, return_type || type)
  end
end

#add_intrinsicsObject



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/mirah/jvm/types/number.rb', line 168

def add_intrinsics
  boolean_operator('<', :lt)
  boolean_operator('<=', :le)
  boolean_operator('==', :eq)
  boolean_operator('!=', :ne)
  boolean_operator('>=', :ge)
  boolean_operator('>', :gt)
  math_operator('+', :add)
  math_operator('-', :sub)
  math_operator('*', :mul)
  math_operator('/', :div)
  math_operator('%', :rem)
  unary_operator('-@', :neg)
  unary_operator('+@', nil)
end

#boolean_operator(name, op) ⇒ Object



108
109
110
111
112
# File 'lib/mirah/jvm/types/number.rb', line 108

def boolean_operator(name, op)
  args = [math_type]
  add_method(name, args, ComparisonIntrinsic.new(self, name, op, args))
  add_delegates(name, @type_system.type(nil, 'boolean'))
end

#compile_boolean_operator(compiler, op, negated, call, label) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/mirah/jvm/types/number.rb', line 127

def compile_boolean_operator(compiler, op, negated, call, label)
  # Promote the target or the argument if necessary
  convert_args(compiler,
               [call.target, *call.parameters],
               [math_type, math_type])
  if negated
    op = invert_op(op)
  end
  if label
    jump_if(compiler.method, op, label)
  else
    compiler.method.op_to_bool do |label|
      jump_if(compiler.method, op, label)
    end
  end
end

#delegate_intrinsic(name, type, return_type) ⇒ Object

Adds an intrinsic that delegates to an intrinsic in another primitive type. That type must support promoting the “this” argument.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/mirah/jvm/types/number.rb', line 72

def delegate_intrinsic(name, type, return_type)
  args = [type]
  delegate = type.intrinsics[name][args]
  if delegate.kind_of?(ComparisonIntrinsic)
    add_method(name, args, ComparisonIntrinsic.new(type, name, delegate.op, args))
  elsif delegate.kind_of?(MathIntrinsic)
    method = MathIntrinsic.new(self, name, args, return_type) do |compiler, call, expression|
      if expression
        delegate.call(compiler, call, expression)
      end
    end
    add_method(name, args, method)
  else
    add_method(name, args, return_type) do |compiler, call, expression|
      if expression
        delegate.call(compiler, call, expression)
      end
    end
  end
end

#invert_op(op) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/mirah/jvm/types/number.rb', line 114

def invert_op(op)
  inverted = {
    :lt => :ge,
    :le => :gt,
    :eq => :ne,
    :ne => :eq,
    :gt => :le,
    :ge => :lt
  }[op]
  raise "Can't invert #{op}." unless inverted
  inverted
end

#jump_if(builder, op, label) ⇒ Object

if_cmpxx for non-ints



103
104
105
106
# File 'lib/mirah/jvm/types/number.rb', line 103

def jump_if(builder, op, label)
  builder.send "#{prefix}cmp#{suffix}"
  builder.send "if#{op}", label
end

#math_operator(name, op) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/mirah/jvm/types/number.rb', line 144

def math_operator(name, op)
  args = [math_type]
  method = MathIntrinsic.new(self, name, args, math_type) do |compiler, call, expression|
    if expression
      # Promote the target or the argument if necessary
      convert_args(compiler,
                   [call.target, *call.parameters],
                   [math_type, math_type])
      compiler.method.send "#{prefix}#{op}"
    end
  end
  add_method(name, args, method)
  add_delegates(name)
end

#math_typeObject

The type returned by arithmetic operations with this type.



62
63
64
# File 'lib/mirah/jvm/types/number.rb', line 62

def math_type
  self
end

#suffixObject



66
67
68
# File 'lib/mirah/jvm/types/number.rb', line 66

def suffix
  ''
end

#unary_operator(name, op) ⇒ Object



159
160
161
162
163
164
165
166
# File 'lib/mirah/jvm/types/number.rb', line 159

def unary_operator(name, op)
  add_method(name, [], math_type) do |compiler, call, expression|
    if expression
      call.target.compile(compiler, true)
      compiler.method.send("#{prefix}#{op}") if op
    end
  end
end