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

Constants inherited from AST::TypeReference

AST::TypeReference::BlockType, AST::TypeReference::ErrorType, AST::TypeReference::NoType, AST::TypeReference::NullType, AST::TypeReference::UnreachableType

Instance Attribute Summary

Attributes inherited from Type

#inner_class

Attributes inherited from AST::TypeReference

#array, #meta

Attributes included from AST::Named

#name

Attributes inherited from AST::Node

#children, #inferred_type, #newline, #parent, #position

Instance Method Summary collapse

Methods inherited from PrimitiveType

#convertible_to?, #initialize, #interfaces, #newarray, #primitive?, #primitive_type, #superclass

Methods inherited from Type

#add_compiled_macro, #add_enumerable_macros, #add_macro, #add_method, #aload, #array?, #array_type, #assignable_from?, #astore, #basic_type, #compatible?, #component_type, #constructor, #declared_class_methods, #declared_constructors, #declared_instance_methods, #declared_intrinsics, #dynamic?, #expand_each, #field_getter, #field_setter, #full_name, #get_method, #include, #init_value, #initialize, #inner_class?, #inner_class_getter, #inspect, #interface?, #interfaces, #intrinsics, #is_parent, #iterable?, #java_method, #jvm_type, #load, #load_extensions, #log, #meta, #meta?, #newarray, #pop, #prefix, #primitive?, #return, #store, #superclass, #to_source, #unmeta, #void?, #wide?, #wrap_with_scoped_body

Methods included from MethodLookup

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

Methods inherited from AST::TypeReference

#==, #_dump, _load, #basic_type, #block?, #compatible?, #component_type, #eql?, #error?, #full_name, #hash, #initialize, #is_parent, #iterable?, #meta?, #narrow, #null?, #primitive?, #to_s, #type_reference, #unmeta, #unreachable?, #void?

Methods included from AST::Named

#string_value, #to_s, #validate_name

Methods inherited from AST::Node

#<<, ===, #[], #[]=, #_dump, _load, #_set_parent, child, child_name, #child_nodes, #each, #empty?, #expr?, #inferred_type!, #initialize, #initialize_copy, #insert, #inspect, #inspect_children, #line_number, #log, #precompile, #resolve_if, #resolved!, #resolved?, #simple_name, #string_value, #temp, #to_s, #top_level?, #validate_child, #validate_children

Constructor Details

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

Instance Method Details

#add_delegates(name, return_type = nil) ⇒ Object



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

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

#add_intrinsicsObject



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/mirah/jvm/types/number.rb', line 138

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



80
81
82
83
84
# File 'lib/mirah/jvm/types/number.rb', line 80

def boolean_operator(name, op)
  args = [math_type]
  add_method(name, args, ComparisonIntrinsic.new(self, name, op, args))
  add_delegates(name, Boolean)
end

#box(builder) ⇒ Object



154
155
156
# File 'lib/mirah/jvm/types/number.rb', line 154

def box(builder)
  builder.invokestatic box_type, "valueOf", [box_type, math_type]
end

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



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/mirah/jvm/types/number.rb', line 99

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.



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/mirah/jvm/types/number.rb', line 52

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))
  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



86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/mirah/jvm/types/number.rb', line 86

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



75
76
77
78
# File 'lib/mirah/jvm/types/number.rb', line 75

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

#math_operator(name, op) ⇒ Object



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

def math_operator(name, op)
  add_method(name, [math_type], 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_delegates(name)
end

#math_typeObject

The type returned by arithmetic operations with this type.



42
43
44
# File 'lib/mirah/jvm/types/number.rb', line 42

def math_type
  self
end

#suffixObject



46
47
48
# File 'lib/mirah/jvm/types/number.rb', line 46

def suffix
  ''
end

#unary_operator(name, op) ⇒ Object



129
130
131
132
133
134
135
136
# File 'lib/mirah/jvm/types/number.rb', line 129

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