mirah 0.0.12-java → 0.1.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +372 -0
- data/README.txt +4 -5
- data/Rakefile +178 -55
- data/examples/appengine/Readme +3 -3
- data/examples/appengine/src/org/mirah/MirahApp.mirah +1 -1
- data/examples/appengine/src/org/mirah/list.dhtml +1 -1
- data/examples/bintrees.mirah +1 -1
- data/examples/edb.mirah +1 -1
- data/examples/fib.mirah +1 -1
- data/examples/interfaces.mirah +1 -1
- data/examples/macros/{string-each-char.mirah → string_each_char.mirah} +4 -5
- data/examples/maven/README.txt +1 -1
- data/examples/maven/src/main/mirah/hello_mirah.mirah +1 -1
- data/examples/plugins/appengine/Rakefile +1 -1
- data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/MetaModel.mirah +1 -1
- data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/Model.duby +1 -1
- data/examples/plugins/appengine/test/com/google/appengine/ext/duby/db/ModelTest.duby +1 -1
- data/examples/rosettacode/100-doors.mirah +6 -6
- data/examples/rosettacode/README.txt +3 -3
- data/examples/rosettacode/boolean-values.mirah +1 -1
- data/examples/rosettacode/comments.mirah +1 -1
- data/examples/rosettacode/count-occurrences-of-a-substring.mirah +1 -1
- data/examples/rosettacode/factorial.mirah +1 -1
- data/examples/rosettacode/fibonacci.mirah +1 -1
- data/examples/rosettacode/fizz-buzz.mirah +2 -2
- data/examples/rosettacode/flatten-a-list.mirah +4 -4
- data/examples/rosettacode/guess-the-number.mirah +2 -2
- data/examples/rosettacode/hamming-numbers.mirah +4 -4
- data/examples/rosettacode/is-string-numeric.mirah +22 -22
- data/examples/rosettacode/palindrome.mirah +2 -2
- data/examples/rosettacode/random-numbers.mirah +1 -1
- data/examples/rosettacode/repeat-a-string.mirah +1 -1
- data/examples/rosettacode/reverse-a-string.mirah +1 -1
- data/examples/rosettacode/rot-13.mirah +5 -5
- data/examples/rosettacode/secure-temporary-file.mirah +2 -2
- data/examples/rosettacode/sleep.mirah +1 -1
- data/examples/rosettacode/string-length.mirah +5 -5
- data/examples/swing.mirah +1 -1
- data/examples/test.edb +1 -1
- data/javalib/mirah-bootstrap.jar +0 -0
- data/javalib/mirah-builtins.jar +0 -0
- data/javalib/mirah-parser.jar +0 -0
- data/javalib/mirah-util.jar +0 -0
- data/lib/duby.rb +1 -1
- data/lib/mirah.rb +50 -28
- data/lib/mirah/ast.rb +15 -605
- data/lib/mirah/ast/scope.rb +98 -69
- data/lib/mirah/commands.rb +1 -1
- data/lib/mirah/commands/base.rb +7 -7
- data/lib/mirah/commands/compile.rb +3 -3
- data/lib/mirah/commands/parse.rb +7 -5
- data/lib/mirah/commands/run.rb +12 -19
- data/lib/mirah/compiler.rb +15 -23
- data/lib/mirah/errors.rb +16 -1
- data/lib/mirah/generator.rb +79 -39
- data/lib/mirah/jvm/compiler.rb +1 -19
- data/lib/mirah/jvm/compiler/base.rb +233 -90
- data/lib/mirah/jvm/compiler/jvm_bytecode.rb +675 -363
- data/lib/mirah/jvm/method_lookup.rb +134 -65
- data/lib/mirah/jvm/typer.rb +10 -5
- data/lib/mirah/jvm/types.rb +10 -2
- data/lib/mirah/jvm/types/array_type.rb +10 -12
- data/lib/mirah/{compiler/type.rb → jvm/types/ast_ext.rb} +12 -8
- data/lib/mirah/jvm/types/basic_types.rb +26 -33
- data/lib/mirah/jvm/types/bitescript_ext.rb +1 -1
- data/lib/mirah/jvm/types/block_type.rb +15 -0
- data/lib/mirah/jvm/types/boolean.rb +8 -4
- data/lib/mirah/jvm/types/dynamic_type.rb +12 -13
- data/lib/mirah/jvm/types/enumerable.rb +7 -7
- data/lib/mirah/jvm/types/extensions.rb +11 -6
- data/lib/mirah/jvm/types/factory.rb +624 -94
- data/lib/mirah/jvm/types/floats.rb +21 -15
- data/lib/mirah/jvm/types/generic_type.rb +72 -0
- data/lib/mirah/jvm/types/implicit_nil_type.rb +29 -0
- data/lib/mirah/jvm/types/integers.rb +26 -71
- data/lib/mirah/jvm/types/interface_definition.rb +3 -3
- data/lib/mirah/jvm/types/intrinsics.rb +203 -168
- data/lib/mirah/jvm/types/literals.rb +6 -6
- data/lib/mirah/jvm/types/meta_type.rb +13 -4
- data/lib/mirah/jvm/types/methods.rb +281 -93
- data/lib/mirah/jvm/types/null_type.rb +17 -5
- data/lib/mirah/jvm/types/number.rb +10 -7
- data/lib/mirah/jvm/types/primitive_type.rb +17 -6
- data/lib/mirah/jvm/types/source_mirror.rb +12 -7
- data/lib/mirah/jvm/types/type.rb +107 -23
- data/lib/mirah/jvm/types/type_definition.rb +25 -10
- data/lib/mirah/jvm/types/unreachable_type.rb +1 -1
- data/lib/mirah/jvm/types/void_type.rb +3 -3
- data/lib/mirah/parser.rb +154 -16
- data/lib/mirah/plugin/edb.rb +1 -1
- data/lib/mirah/transform.rb +1 -2
- data/lib/mirah/transform/ast_ext.rb +24 -43
- data/lib/mirah/transform/transformer.rb +29 -224
- data/lib/mirah/typer.rb +2 -16
- data/lib/mirah/util/argument_processor.rb +25 -10
- data/lib/mirah/util/class_loader.rb +1 -1
- data/lib/mirah/util/compilation_state.rb +16 -17
- data/lib/mirah/util/delegate.rb +2 -2
- data/lib/mirah/util/logging.rb +110 -0
- data/lib/mirah/util/process_errors.rb +69 -11
- data/lib/mirah/version.rb +1 -1
- data/test/core/commands_test.rb +6 -24
- data/test/core/env_test.rb +5 -5
- data/{lib/mirah/jvm/source_generator/typer.rb → test/core/generator_test.rb} +9 -9
- data/test/core/typer_test.rb +196 -158
- data/test/core/util/argument_processor_test.rb +10 -10
- data/test/core/util/class_loader_test.rb +6 -5
- data/test/fixtures/org/foo/LowerCaseInnerClass$inner.class +0 -0
- data/test/fixtures/org/foo/LowerCaseInnerClass.class +0 -0
- data/test/fixtures/org/foo/LowerCaseInnerClass.java +7 -0
- data/test/jvm/annotations_test.rb +5 -5
- data/test/jvm/blocks_test.rb +140 -88
- data/test/jvm/bytecode_test_helper.rb +112 -94
- data/test/jvm/cast_test.rb +162 -0
- data/test/jvm/constructors_test.rb +18 -8
- data/test/jvm/enumerable_test.rb +77 -44
- data/test/jvm/example_test.rb +53 -0
- data/test/jvm/factory_test.rb +7 -1
- data/test/jvm/generics_test.rb +57 -0
- data/test/jvm/hash_test.rb +106 -0
- data/test/jvm/import_test.rb +81 -0
- data/test/jvm/interface_test.rb +73 -0
- data/test/jvm/java_typer_test.rb +92 -66
- data/{lib/mirah/typer/base.rb → test/jvm/jvm_commands_test.rb} +6 -10
- data/test/jvm/jvm_compiler_test.rb +170 -604
- data/test/jvm/list_extensions_test.rb +23 -0
- data/test/jvm/macros_test.rb +197 -32
- data/test/jvm/main_method_test.rb +4 -4
- data/test/jvm/numeric_extensions_test.rb +13 -0
- data/test/jvm/rescue_test.rb +73 -16
- data/test/jvm/varargs_test.rb +65 -0
- data/test/test_helper.rb +1 -2
- metadata +234 -251
- data/examples/SortClosure$__xform_tmp_1.class +0 -0
- data/examples/SortClosure$__xform_tmp_2.class +0 -0
- data/examples/SortClosure.class +0 -0
- data/examples/macros/StringEachChar$Extension1.class +0 -0
- data/lib/mirah/ast/call.rb +0 -345
- data/lib/mirah/ast/class.rb +0 -359
- data/lib/mirah/ast/flow.rb +0 -381
- data/lib/mirah/ast/intrinsics.rb +0 -563
- data/lib/mirah/ast/literal.rb +0 -178
- data/lib/mirah/ast/local.rb +0 -112
- data/lib/mirah/ast/method.rb +0 -408
- data/lib/mirah/ast/structure.rb +0 -387
- data/lib/mirah/ast/type.rb +0 -146
- data/lib/mirah/commands/base.rb~ +0 -57
- data/lib/mirah/compiler/call.rb +0 -45
- data/lib/mirah/compiler/class.rb +0 -81
- data/lib/mirah/compiler/flow.rb +0 -109
- data/lib/mirah/compiler/literal.rb +0 -130
- data/lib/mirah/compiler/local.rb +0 -59
- data/lib/mirah/compiler/method.rb +0 -44
- data/lib/mirah/compiler/structure.rb +0 -65
- data/lib/mirah/jvm/compiler/java_source.rb +0 -787
- data/lib/mirah/jvm/method_lookup.rb~ +0 -247
- data/lib/mirah/jvm/source_generator/builder.rb +0 -468
- data/lib/mirah/jvm/source_generator/loops.rb +0 -131
- data/lib/mirah/jvm/source_generator/precompile.rb +0 -210
- data/lib/mirah/plugin/gwt.rb +0 -189
- data/lib/mirah/plugin/java.rb +0 -70
- data/lib/mirah/transform/error.rb +0 -13
- data/lib/mirah/transform/helper.rb +0 -765
- data/lib/mirah/typer/simple.rb +0 -384
- data/lib/mirah/version.rb~ +0 -18
- data/test/core/ast_test.rb +0 -382
- data/test/core/compilation_test.rb +0 -130
- data/test/core/macros_test.rb +0 -61
- data/test/jvm/javac_test_helper.rb +0 -89
- data/test/jvm/jvm_compiler_test.rb~ +0 -2181
- data/test/plugins/gwt_test.rb +0 -69
|
@@ -20,13 +20,13 @@ module Mirah::JVM::Types
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def math_type
|
|
23
|
-
|
|
23
|
+
@type_system.type(nil, 'float')
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def box_type
|
|
27
|
-
java.lang.Float
|
|
27
|
+
@type_system.type(nil, 'java.lang.Float')
|
|
28
28
|
end
|
|
29
|
-
|
|
29
|
+
|
|
30
30
|
def suffix
|
|
31
31
|
'g'
|
|
32
32
|
end
|
|
@@ -47,30 +47,32 @@ module Mirah::JVM::Types
|
|
|
47
47
|
builder.ldc_float(value)
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
|
-
|
|
51
|
-
def
|
|
52
|
-
case type
|
|
53
|
-
when
|
|
50
|
+
|
|
51
|
+
def compile_widen(builder, type)
|
|
52
|
+
case type.name
|
|
53
|
+
when 'float'
|
|
54
54
|
# Do nothing
|
|
55
|
-
when
|
|
55
|
+
when 'double'
|
|
56
56
|
builder.f2d
|
|
57
|
+
when @wrapper.java_class.name, 'java.lang.Object'
|
|
58
|
+
builder.invokestatic @wrapper, "valueOf", [@wrapper, builder.send(name)]
|
|
57
59
|
else
|
|
58
60
|
raise ArgumentError, "Invalid widening conversion from float to #{type}"
|
|
59
61
|
end
|
|
60
62
|
end
|
|
61
63
|
end
|
|
62
|
-
|
|
64
|
+
|
|
63
65
|
class DoubleType < FloatType
|
|
64
66
|
def prefix
|
|
65
67
|
'd'
|
|
66
68
|
end
|
|
67
69
|
|
|
68
70
|
def math_type
|
|
69
|
-
|
|
71
|
+
@type_system.type(nil, 'double')
|
|
70
72
|
end
|
|
71
73
|
|
|
72
74
|
def box_type
|
|
73
|
-
java.lang.Double
|
|
75
|
+
@type_system.type(nil, 'java.lang.Double')
|
|
74
76
|
end
|
|
75
77
|
|
|
76
78
|
def wide?
|
|
@@ -91,11 +93,15 @@ module Mirah::JVM::Types
|
|
|
91
93
|
builder.ldc_double(value)
|
|
92
94
|
end
|
|
93
95
|
end
|
|
94
|
-
|
|
95
|
-
def
|
|
96
|
-
|
|
96
|
+
|
|
97
|
+
def compile_widen(builder, type)
|
|
98
|
+
case type.name
|
|
99
|
+
when 'double'
|
|
100
|
+
when @wrapper.java_class.name, 'java.lang.Object'
|
|
101
|
+
builder.invokestatic @wrapper, "valueOf", [@wrapper, builder.send(name)]
|
|
102
|
+
else
|
|
97
103
|
raise ArgumentError, "Invalid widening conversion from double to #{type}"
|
|
98
104
|
end
|
|
99
105
|
end
|
|
100
106
|
end
|
|
101
|
-
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module Mirah
|
|
2
|
+
module JVM
|
|
3
|
+
module Types
|
|
4
|
+
class GenericType < Type
|
|
5
|
+
java_import 'java.util.HashMap'
|
|
6
|
+
java_import 'org.mirah.typer.GenericType'
|
|
7
|
+
include GenericType
|
|
8
|
+
|
|
9
|
+
attr_reader :ungeneric
|
|
10
|
+
|
|
11
|
+
def initialize(ungeneric)
|
|
12
|
+
super(ungeneric.type_system, ungeneric.name)
|
|
13
|
+
@ungeneric = ungeneric
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def basic_type
|
|
17
|
+
@ungeneric.basic_type
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def generic?
|
|
21
|
+
true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def generic
|
|
25
|
+
self
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def ungeneric
|
|
29
|
+
@ungeneric
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def superclass
|
|
33
|
+
@ungeneric.superclass.generic if @ungeneric.superclass
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def declared_macros(name=nil)
|
|
37
|
+
@ungeneric.declared_macros(name)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def interfaces(include_parent=true)
|
|
41
|
+
ungeneric.interfaces
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def jvm_type
|
|
45
|
+
@ungeneric.jvm_type
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def inner_class?
|
|
49
|
+
basic_type.inner_class?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def type_parameter_map
|
|
53
|
+
unless @type_parameter_map
|
|
54
|
+
@type_parameter_map = HashMap.new
|
|
55
|
+
end
|
|
56
|
+
@type_parameter_map
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def assignable_from?(other)
|
|
60
|
+
@ungeneric.assignable_from?(other)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def inspect(indent=0)
|
|
64
|
+
"#{' ' * indent}#<#{self.class.name.split(/::/)[-1]} #{name} #{type_parameter_map}>"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
class TypeDefGeneric < GenericType
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Mirah
|
|
2
|
+
module JVM
|
|
3
|
+
module Types
|
|
4
|
+
class ImplicitNilType < Type
|
|
5
|
+
def initialize(types)
|
|
6
|
+
super(types, types.get_mirror('java.lang.Object'))
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def to_s
|
|
10
|
+
"Type(implicit_nil)"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def widen(other)
|
|
14
|
+
other
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def compatible?(other)
|
|
18
|
+
true
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def assignable_from?(other)
|
|
22
|
+
true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def matchesAnything; true; end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -20,81 +20,48 @@ module Mirah::JVM::Types
|
|
|
20
20
|
def literal(builder, value)
|
|
21
21
|
builder.push_int(value)
|
|
22
22
|
end
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
def init_value(builder)
|
|
25
25
|
builder.iconst_0
|
|
26
26
|
end
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
def load(builder, index)
|
|
29
29
|
builder.iload(index)
|
|
30
30
|
end
|
|
31
|
-
|
|
32
|
-
def
|
|
33
|
-
case type
|
|
34
|
-
when
|
|
31
|
+
|
|
32
|
+
def compile_widen(builder, type)
|
|
33
|
+
case type.name
|
|
34
|
+
when 'byte', 'short', 'int'
|
|
35
35
|
# do nothing
|
|
36
|
-
when
|
|
36
|
+
when 'long'
|
|
37
37
|
builder.i2l
|
|
38
|
-
when
|
|
38
|
+
when 'float'
|
|
39
39
|
builder.i2f
|
|
40
|
-
when
|
|
40
|
+
when 'double'
|
|
41
41
|
builder.i2d
|
|
42
|
+
when @wrapper.java_class.name, 'java.lang.Object'
|
|
43
|
+
builder.invokestatic @wrapper, "valueOf", [@wrapper, builder.send(name)]
|
|
42
44
|
else
|
|
43
45
|
raise ArgumentError, "Invalid widening conversion from #{name} to #{type}"
|
|
44
46
|
end
|
|
45
47
|
end
|
|
46
|
-
|
|
48
|
+
|
|
47
49
|
def prefix
|
|
48
50
|
'i'
|
|
49
51
|
end
|
|
50
|
-
|
|
52
|
+
|
|
51
53
|
def math_type
|
|
52
|
-
|
|
54
|
+
@type_system.type(nil, 'int')
|
|
53
55
|
end
|
|
54
56
|
|
|
55
57
|
def box_type
|
|
56
|
-
java.lang.Integer
|
|
58
|
+
@type_system.type(nil, 'java.lang.Integer')
|
|
57
59
|
end
|
|
58
60
|
|
|
59
61
|
def jump_if(builder, op, label)
|
|
60
62
|
builder.send "if_icmp#{op}", label
|
|
61
63
|
end
|
|
62
64
|
|
|
63
|
-
def build_loop(parent, position, duby, block, first_value,
|
|
64
|
-
last_value, ascending, inclusive)
|
|
65
|
-
if ascending
|
|
66
|
-
comparison = "<"
|
|
67
|
-
op = "+="
|
|
68
|
-
else
|
|
69
|
-
comparison = ">"
|
|
70
|
-
op = "-="
|
|
71
|
-
end
|
|
72
|
-
comparison << "=" if inclusive
|
|
73
|
-
forloop = Mirah::AST::Loop.new(parent, position, true, false) do |forloop|
|
|
74
|
-
first, last = duby.tmp, duby.tmp
|
|
75
|
-
init = duby.eval("#{first} = 0; #{last} = 0;")
|
|
76
|
-
init.children[-2].value = first_value
|
|
77
|
-
init.children[-1].value = last_value
|
|
78
|
-
forloop.init << init
|
|
79
|
-
|
|
80
|
-
var = (block.args.args || [])[0]
|
|
81
|
-
if var
|
|
82
|
-
forloop.pre << duby.eval(
|
|
83
|
-
"#{var.name} = #{first}", '', forloop, first, last)
|
|
84
|
-
end
|
|
85
|
-
forloop.post << duby.eval("#{first} #{op} 1")
|
|
86
|
-
[
|
|
87
|
-
Mirah::AST::Condition.new(forloop, position) do |c|
|
|
88
|
-
[duby.eval("#{first} #{comparison} #{last}",
|
|
89
|
-
'', forloop, first, last)]
|
|
90
|
-
end,
|
|
91
|
-
nil
|
|
92
|
-
]
|
|
93
|
-
end
|
|
94
|
-
forloop.body = block.body
|
|
95
|
-
forloop
|
|
96
|
-
end
|
|
97
|
-
|
|
98
65
|
def add_intrinsics
|
|
99
66
|
super
|
|
100
67
|
math_operator('<<', 'shl')
|
|
@@ -104,20 +71,6 @@ module Mirah::JVM::Types
|
|
|
104
71
|
math_operator('&', 'and')
|
|
105
72
|
math_operator('^', 'xor')
|
|
106
73
|
unary_operator('~', 'not')
|
|
107
|
-
|
|
108
|
-
add_macro('downto', Int, Mirah::AST.block_type) do |transformer, call|
|
|
109
|
-
build_loop(call.parent, call.position, transformer,
|
|
110
|
-
call.block, call.target, call.parameters[0], false, true)
|
|
111
|
-
end
|
|
112
|
-
add_macro('upto', Int, Mirah::AST.block_type) do |transformer, call|
|
|
113
|
-
build_loop(call.parent, call.position, transformer,
|
|
114
|
-
call.block, call.target, call.parameters[0], true, true)
|
|
115
|
-
end
|
|
116
|
-
add_macro('times', Mirah::AST.block_type) do |transformer, call|
|
|
117
|
-
build_loop(call.parent, call.position, transformer,
|
|
118
|
-
call.block, Mirah::AST::fixnum(nil, call.position, 0),
|
|
119
|
-
call.target, true, false)
|
|
120
|
-
end
|
|
121
74
|
end
|
|
122
75
|
end
|
|
123
76
|
|
|
@@ -127,11 +80,11 @@ module Mirah::JVM::Types
|
|
|
127
80
|
end
|
|
128
81
|
|
|
129
82
|
def math_type
|
|
130
|
-
|
|
83
|
+
@type_system.type(nil, 'long')
|
|
131
84
|
end
|
|
132
85
|
|
|
133
86
|
def box_type
|
|
134
|
-
java.lang.Long
|
|
87
|
+
@type_system.type(nil, 'java.lang.Long')
|
|
135
88
|
end
|
|
136
89
|
|
|
137
90
|
def literal(builder, value)
|
|
@@ -141,24 +94,26 @@ module Mirah::JVM::Types
|
|
|
141
94
|
def init_value(builder)
|
|
142
95
|
builder.lconst_0
|
|
143
96
|
end
|
|
144
|
-
|
|
97
|
+
|
|
145
98
|
def wide?
|
|
146
99
|
true
|
|
147
100
|
end
|
|
148
101
|
|
|
149
|
-
def
|
|
150
|
-
case type
|
|
151
|
-
when
|
|
102
|
+
def compile_widen(builder, type)
|
|
103
|
+
case type.name
|
|
104
|
+
when 'long'
|
|
152
105
|
# do nothing
|
|
153
|
-
when
|
|
106
|
+
when 'float'
|
|
154
107
|
builder.l2f
|
|
155
|
-
when
|
|
108
|
+
when 'double'
|
|
156
109
|
builder.l2d
|
|
110
|
+
when @wrapper.java_class.name, 'java.lang.Object'
|
|
111
|
+
builder.invokestatic @wrapper, "valueOf", [@wrapper, builder.send(name)]
|
|
157
112
|
else
|
|
158
113
|
raise ArgumentError, "Invalid widening conversion from Int to #{type}"
|
|
159
114
|
end
|
|
160
115
|
end
|
|
161
|
-
|
|
116
|
+
|
|
162
117
|
def add_intrinsics
|
|
163
118
|
super
|
|
164
119
|
math_operator('<<', 'shl')
|
|
@@ -2,8 +2,8 @@ module Mirah
|
|
|
2
2
|
module JVM
|
|
3
3
|
module Types
|
|
4
4
|
class InterfaceDefinition < TypeDefinition
|
|
5
|
-
def initialize(name, node)
|
|
6
|
-
super(name, node)
|
|
5
|
+
def initialize(types, scope, name, node)
|
|
6
|
+
super(types, scope, name, node)
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
def define(builder)
|
|
@@ -17,4 +17,4 @@ module Mirah
|
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
|
-
end
|
|
20
|
+
end
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
16
|
require 'bitescript'
|
|
17
|
-
require 'mirah/jvm/types/enumerable'
|
|
18
17
|
require 'mirah/jvm/types/bitescript_ext'
|
|
19
18
|
|
|
20
19
|
module Mirah::JVM::Types
|
|
21
20
|
class Type
|
|
21
|
+
java_import 'org.mirah.macros.anno.MacroDef'
|
|
22
22
|
|
|
23
23
|
def load(builder, index)
|
|
24
24
|
builder.send "#{prefix}load", index
|
|
@@ -44,6 +44,10 @@ module Mirah::JVM::Types
|
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
+
def macros
|
|
48
|
+
@macros ||= Hash.new {|h, k| h[k] = {}}
|
|
49
|
+
end
|
|
50
|
+
|
|
47
51
|
def add_method(name, args, method_or_type=nil, &block)
|
|
48
52
|
if block_given?
|
|
49
53
|
method_or_type = Intrinsic.new(self, name, args,
|
|
@@ -52,53 +56,79 @@ module Mirah::JVM::Types
|
|
|
52
56
|
intrinsics[name][args] = method_or_type
|
|
53
57
|
end
|
|
54
58
|
|
|
55
|
-
def
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
def add_compiled_macro(klass)
|
|
60
|
+
name, arg_types, is_static = read_macrodef_annotation(klass)
|
|
61
|
+
if arg_types.nil?
|
|
62
|
+
return
|
|
63
|
+
elsif is_static && !self.meta?
|
|
64
|
+
self.meta.add_compiled_macro(klass)
|
|
65
|
+
return
|
|
59
66
|
end
|
|
60
|
-
end
|
|
61
67
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
#
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
log "Adding macro #{self.name}.#{name}(#{arg_types.map{|t| t.full_name}.join(', ')})"
|
|
69
|
+
# TODO separate static and instance macros
|
|
70
|
+
macro = Macro.new(self, name, arg_types) do |call, typer|
|
|
71
|
+
#TODO scope
|
|
72
|
+
# We probably need to set the scope on all the parameters, plus the
|
|
73
|
+
# arguments and body of any block params. Also make sure scope is copied
|
|
74
|
+
# when cloned.
|
|
75
|
+
scope = typer.scoper.get_scope(call)
|
|
76
|
+
# call.parameters.each do |arg|
|
|
77
|
+
# arg.scope = scope
|
|
78
|
+
# end
|
|
79
|
+
|
|
80
|
+
begin
|
|
81
|
+
expander = klass.constructors[0].newInstance(typer.macro_compiler, call)
|
|
82
|
+
ast = expander.expand
|
|
83
|
+
# rescue
|
|
84
|
+
# puts "Unable to expand macro #{name.inspect} from #{klass} with #{call}"
|
|
75
85
|
end
|
|
76
|
-
|
|
77
|
-
expander = klass.constructors[0].newInstance(mirah, call)
|
|
78
|
-
ast = expander.expand
|
|
79
86
|
if ast
|
|
80
|
-
body = Mirah::AST::
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
#
|
|
84
|
-
|
|
85
|
-
#
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
body = Mirah::AST::NodeList.new(ast.position.to_java(Mirah::AST::Position))
|
|
88
|
+
# TODO scope
|
|
89
|
+
# static_scope = typer.scoper.add_scope(body)
|
|
90
|
+
# static_scope.parent = typer.scoper.get_scope(call)
|
|
91
|
+
body.add(ast)
|
|
92
|
+
# if call.target
|
|
93
|
+
# static_scope.self_type = call.target.inferred_type!
|
|
94
|
+
# static_scope.self_node = call.target
|
|
95
|
+
# else
|
|
96
|
+
# static_scope.self_type = scope.self_type
|
|
97
|
+
# end
|
|
98
|
+
|
|
91
99
|
body
|
|
92
100
|
else
|
|
93
|
-
Mirah::AST::Noop.new
|
|
101
|
+
Mirah::AST::Noop.new
|
|
94
102
|
end
|
|
95
103
|
end
|
|
104
|
+
macros[name][arg_types] = macro
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def declared_macros(name=nil)
|
|
108
|
+
result = []
|
|
109
|
+
each_name = lambda do |name, hash|
|
|
110
|
+
hash.each do |args, macro|
|
|
111
|
+
result << macro
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
if name
|
|
115
|
+
each_name.call(name, self.macros[name])
|
|
116
|
+
else
|
|
117
|
+
self.macros.each &each_name
|
|
118
|
+
end
|
|
119
|
+
result
|
|
96
120
|
end
|
|
97
|
-
|
|
98
|
-
def
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
121
|
+
|
|
122
|
+
def macro(name, types)
|
|
123
|
+
macro = macros[name][types]
|
|
124
|
+
return macro if macro
|
|
125
|
+
macro = superclass.macro(name, types) if (superclass && !superclass.isError)
|
|
126
|
+
return macro if macro
|
|
127
|
+
interfaces.each do |interface|
|
|
128
|
+
macro = interface.macro(name, types) unless interface.isError
|
|
129
|
+
return macro if macro
|
|
130
|
+
end
|
|
131
|
+
nil
|
|
102
132
|
end
|
|
103
133
|
|
|
104
134
|
def declared_intrinsics(name=nil)
|
|
@@ -114,8 +144,7 @@ module Mirah::JVM::Types
|
|
|
114
144
|
end
|
|
115
145
|
end
|
|
116
146
|
interfaces.each do |interface|
|
|
117
|
-
|
|
118
|
-
methods.concat(interface.declared_intrinsics(name))
|
|
147
|
+
methods.concat(interface.declared_intrinsics(name)) unless interface.isError
|
|
119
148
|
end
|
|
120
149
|
methods
|
|
121
150
|
end
|
|
@@ -123,240 +152,245 @@ module Mirah::JVM::Types
|
|
|
123
152
|
def load_extensions(klass=nil)
|
|
124
153
|
mirror = nil
|
|
125
154
|
if klass
|
|
126
|
-
|
|
127
|
-
mirror = factory.get_mirror(klass.getName)
|
|
155
|
+
mirror = @type_system.mirror_class(klass)
|
|
128
156
|
elsif jvm_type
|
|
129
157
|
mirror = jvm_type
|
|
130
158
|
end
|
|
131
159
|
if mirror
|
|
132
|
-
extensions = mirror.getDeclaredAnnotation('
|
|
160
|
+
extensions = mirror.getDeclaredAnnotation('org.mirah.macros.anno.Extensions')
|
|
133
161
|
return self if extensions.nil?
|
|
134
162
|
macros = extensions['macros']
|
|
135
163
|
return self if macros.nil?
|
|
136
|
-
macros.each do |
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
else
|
|
144
|
-
Mirah::AST.type(nil, type)
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
klass = JRuby.runtime.jruby_class_loader.loadClass(class_name)
|
|
148
|
-
add_compiled_macro(klass, macro_name, args)
|
|
164
|
+
macros.each do |macro_class|
|
|
165
|
+
klass = begin
|
|
166
|
+
JRuby.runtime.jruby_class_loader.loadClass(macro_class)
|
|
167
|
+
rescue java.lang.NoClassDefFoundError => ex
|
|
168
|
+
raise ex
|
|
169
|
+
end
|
|
170
|
+
add_compiled_macro(klass)
|
|
149
171
|
end
|
|
150
172
|
end
|
|
151
173
|
self
|
|
152
174
|
end
|
|
153
175
|
|
|
176
|
+
def read_macrodef_annotation(klass)
|
|
177
|
+
macro = klass.getAnnotation(MacroDef.java_class)
|
|
178
|
+
if macro.nil?
|
|
179
|
+
error("Unable to load macro #{klass.name}: no MacroDef annotation")
|
|
180
|
+
return
|
|
181
|
+
end
|
|
182
|
+
macro_name = macro.name
|
|
183
|
+
# TODO optional, rest args
|
|
184
|
+
args = macro.arguments.required.map do |typename|
|
|
185
|
+
type = @type_system.get_type(typename)
|
|
186
|
+
raise "Unable to find class #{typename}" unless type
|
|
187
|
+
type
|
|
188
|
+
end
|
|
189
|
+
[macro_name, args, macro.is_static]
|
|
190
|
+
end
|
|
191
|
+
|
|
154
192
|
def add_intrinsics
|
|
155
|
-
|
|
193
|
+
boolean = @type_system.type(nil, 'boolean')
|
|
194
|
+
object_type = @type_system.type(nil, 'java.lang.Object')
|
|
195
|
+
class_type = @type_system.type(nil, 'java.lang.Class')
|
|
196
|
+
|
|
197
|
+
add_method('nil?', [], boolean) do |compiler, call, expression|
|
|
156
198
|
if expression
|
|
157
|
-
call.target
|
|
199
|
+
compiler.visit(call.target, true)
|
|
158
200
|
compiler.method.op_to_bool do |target|
|
|
159
201
|
compiler.method.ifnull(target)
|
|
160
202
|
end
|
|
161
203
|
end
|
|
162
204
|
end
|
|
163
205
|
|
|
164
|
-
add_method('==', [
|
|
206
|
+
add_method('==', [object_type], boolean) do |compiler, call, expression|
|
|
165
207
|
# Should this call Object.equals for consistency with Ruby?
|
|
166
208
|
if expression
|
|
167
|
-
call.target
|
|
168
|
-
call.parameters
|
|
209
|
+
compiler.visit(call.target, true)
|
|
210
|
+
compiler.visit(call.parameters(0), true)
|
|
169
211
|
compiler.method.op_to_bool do |target|
|
|
170
212
|
compiler.method.if_acmpeq(target)
|
|
171
213
|
end
|
|
172
214
|
end
|
|
173
215
|
end
|
|
174
216
|
|
|
175
|
-
add_method('!=', [
|
|
217
|
+
add_method('!=', [object_type], boolean) do |compiler, call, expression|
|
|
176
218
|
# Should this call Object.equals for consistency with Ruby?
|
|
177
219
|
if expression
|
|
178
|
-
call.target
|
|
179
|
-
call.parameters
|
|
220
|
+
compiler.visit(call.target, true)
|
|
221
|
+
compiler.visit(call.parameters(0), true)
|
|
180
222
|
compiler.method.op_to_bool do |target|
|
|
181
223
|
compiler.method.if_acmpne(target)
|
|
182
224
|
end
|
|
183
225
|
end
|
|
184
226
|
end
|
|
185
227
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
Mirah::AST::Call.new(call.parent, call.position, 'isInstance') do |call2|
|
|
189
|
-
klass.parent = object.parent = call2
|
|
190
|
-
[
|
|
191
|
-
klass,
|
|
192
|
-
[object]
|
|
193
|
-
]
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
add_method('kind_of?', [Object.meta], Boolean) do |compiler, call, expression|
|
|
198
|
-
call.target.compile(compiler, expression)
|
|
228
|
+
add_method('kind_of?', [object_type.meta], boolean) do |compiler, call, expression|
|
|
229
|
+
compiler.visit(call.target, expression)
|
|
199
230
|
if expression
|
|
200
|
-
klass = call.parameters
|
|
231
|
+
klass = compiler.inferred_type(call.parameters(0))
|
|
201
232
|
compiler.method.instanceof(klass.unmeta)
|
|
202
233
|
end
|
|
203
234
|
end
|
|
235
|
+
|
|
236
|
+
# add_macro('kind_of?', class_type) do |transformer, call|
|
|
237
|
+
# klass, object = call.parameters(0), call.target
|
|
238
|
+
# Mirah::AST::Call.new(call.parent, call.position, 'isInstance') do |call2|
|
|
239
|
+
# klass.parent = object.parent = call2
|
|
240
|
+
# [
|
|
241
|
+
# klass,
|
|
242
|
+
# [object]
|
|
243
|
+
# ]
|
|
244
|
+
# end
|
|
245
|
+
# end
|
|
246
|
+
#
|
|
204
247
|
end
|
|
205
248
|
end
|
|
206
249
|
|
|
207
250
|
class ArrayType
|
|
251
|
+
begin
|
|
252
|
+
java_import 'org.mirah.builtins.ArrayExtensions'
|
|
253
|
+
java_import 'org.mirah.builtins.EnumerableExtensions'
|
|
254
|
+
rescue NameError
|
|
255
|
+
ArrayExtensions = nil
|
|
256
|
+
EnumerableExtensions = nil
|
|
257
|
+
end
|
|
258
|
+
|
|
208
259
|
def add_intrinsics
|
|
209
260
|
super
|
|
210
|
-
|
|
211
|
-
|
|
261
|
+
load_extensions(EnumerableExtensions.java_class) if EnumerableExtensions
|
|
262
|
+
load_extensions(ArrayExtensions.java_class) if ArrayExtensions
|
|
263
|
+
int_type = @type_system.type(nil, 'int')
|
|
212
264
|
add_method(
|
|
213
|
-
'[]', [
|
|
265
|
+
'[]', [int_type], component_type) do |compiler, call, expression|
|
|
214
266
|
if expression
|
|
215
|
-
call.target
|
|
216
|
-
call.parameters
|
|
267
|
+
compiler.visit(call.target, true)
|
|
268
|
+
compiler.visit(call.parameters(0), true)
|
|
217
269
|
component_type.aload(compiler.method)
|
|
218
270
|
end
|
|
219
271
|
end
|
|
220
272
|
|
|
221
273
|
add_method('[]=',
|
|
222
|
-
[
|
|
274
|
+
[int_type, component_type],
|
|
223
275
|
component_type) do |compiler, call, expression|
|
|
224
|
-
call.target
|
|
225
|
-
convert_args(compiler, call.parameters, [
|
|
276
|
+
compiler.visit(call.target, true)
|
|
277
|
+
convert_args(compiler, call.parameters, [@type_system.type(nil, 'int'), component_type])
|
|
226
278
|
component_type.astore(compiler.method)
|
|
227
279
|
if expression
|
|
228
|
-
call.parameters
|
|
280
|
+
compiler.visit(call.parameters(1), true)
|
|
229
281
|
end
|
|
230
282
|
end
|
|
231
283
|
|
|
232
|
-
add_method('length', [],
|
|
233
|
-
call.target
|
|
284
|
+
add_method('length', [], int_type) do |compiler, call, expression|
|
|
285
|
+
compiler.visit(call.target, true)
|
|
234
286
|
compiler.method.arraylength
|
|
235
287
|
end
|
|
236
|
-
|
|
237
|
-
add_macro('each', Mirah::AST.block_type) do |transformer, call|
|
|
238
|
-
Mirah::AST::Loop.new(call.parent,
|
|
239
|
-
call.position, true, false) do |forloop|
|
|
240
|
-
index = transformer.tmp
|
|
241
|
-
array = transformer.tmp
|
|
242
|
-
|
|
243
|
-
init = transformer.eval("#{index} = 0;#{array} = nil")
|
|
244
|
-
array_assignment = init.children[-1]
|
|
245
|
-
array_assignment.value = call.target
|
|
246
|
-
call.target.parent = array_assignment
|
|
247
|
-
forloop.init << init
|
|
248
|
-
|
|
249
|
-
var = call.block.args.args[0]
|
|
250
|
-
if var
|
|
251
|
-
forloop.pre << transformer.eval(
|
|
252
|
-
"#{var.name} = #{array}[#{index}]", '', forloop, index, array)
|
|
253
|
-
end
|
|
254
|
-
forloop.post << transformer.eval("#{index} += 1")
|
|
255
|
-
call.block.body.parent = forloop if call.block.body
|
|
256
|
-
[
|
|
257
|
-
Mirah::AST::Condition.new(forloop, call.position) do |c|
|
|
258
|
-
[transformer.eval("#{index} < #{array}.length",
|
|
259
|
-
'', forloop, index, array)]
|
|
260
|
-
end,
|
|
261
|
-
call.block.body
|
|
262
|
-
]
|
|
263
|
-
end
|
|
264
|
-
end
|
|
265
288
|
end
|
|
266
289
|
end
|
|
267
290
|
|
|
268
291
|
class MetaType
|
|
269
292
|
def add_intrinsics
|
|
270
|
-
add_method('class', [],
|
|
293
|
+
add_method('class', [], @type_system.type(nil, 'java.lang.Class')) do |compiler, call, expression|
|
|
271
294
|
if expression
|
|
272
295
|
compiler.method.ldc_class(unmeta)
|
|
273
296
|
end
|
|
274
297
|
end
|
|
298
|
+
add_method('[]', [], unmeta.array_type.meta) do |compiler, call, expression|
|
|
299
|
+
compiler.method.ldc_class(unmeta.array_type.meta)
|
|
300
|
+
end
|
|
275
301
|
end
|
|
276
302
|
end
|
|
277
303
|
|
|
278
304
|
class ArrayMetaType
|
|
279
305
|
def add_intrinsics
|
|
280
306
|
super
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
307
|
+
load_extensions(@type_system.type(nil, 'org.mirah.builtins.ArrayMetaExtensions'))
|
|
308
|
+
# add_macro('cast', @type_system.type(nil, 'java.lang.Object')) do |transformer, call|
|
|
309
|
+
# call.cast = true
|
|
310
|
+
# call.resolve_if(nil) { unmeta }
|
|
311
|
+
# call
|
|
312
|
+
# end
|
|
286
313
|
end
|
|
287
314
|
end
|
|
288
315
|
|
|
289
316
|
class StringType < Type
|
|
290
317
|
def add_intrinsics
|
|
291
318
|
super
|
|
292
|
-
|
|
319
|
+
string_type = @type_system.type(nil, 'java.lang.String')
|
|
320
|
+
bool_type = @type_system.type(nil, 'boolean')
|
|
321
|
+
int_type = @type_system.type(nil, 'int')
|
|
322
|
+
long_type = @type_system.type(nil, 'long')
|
|
323
|
+
char_type = @type_system.type(nil, 'char')
|
|
324
|
+
float_type = @type_system.type(nil, 'float')
|
|
325
|
+
double_type = @type_system.type(nil, 'double')
|
|
326
|
+
add_method('+', [string_type], string_type) do |compiler, call, expression|
|
|
293
327
|
if expression
|
|
294
|
-
java_method('concat',
|
|
328
|
+
java_method('concat', string_type).call(compiler, call, expression)
|
|
295
329
|
end
|
|
296
330
|
end
|
|
297
|
-
add_method('+', [
|
|
331
|
+
add_method('+', [bool_type], string_type) do |compiler, call, expression|
|
|
298
332
|
if expression
|
|
299
|
-
call.target
|
|
300
|
-
call.parameters
|
|
301
|
-
compiler.method.invokestatic
|
|
302
|
-
compiler.method.invokevirtual
|
|
333
|
+
compiler.visit(call.target, true)
|
|
334
|
+
compiler.visit(call.parameters(0), true)
|
|
335
|
+
compiler.method.invokestatic string_type, "valueOf", [string_type, bool_type]
|
|
336
|
+
compiler.method.invokevirtual string_type, "concat", [string_type, string_type]
|
|
303
337
|
end
|
|
304
338
|
end
|
|
305
|
-
add_method('+', [
|
|
339
|
+
add_method('+', [char_type], string_type) do |compiler, call, expression|
|
|
306
340
|
if expression
|
|
307
|
-
call.target
|
|
308
|
-
call.parameters
|
|
309
|
-
compiler.method.invokestatic
|
|
310
|
-
compiler.method.invokevirtual
|
|
341
|
+
compiler.visit(call.target, true)
|
|
342
|
+
compiler.visit(call.parameters(0), true)
|
|
343
|
+
compiler.method.invokestatic string_type, "valueOf", [string_type, char_type]
|
|
344
|
+
compiler.method.invokevirtual string_type, "concat", [string_type, string_type]
|
|
311
345
|
end
|
|
312
346
|
end
|
|
313
|
-
add_method('+', [
|
|
347
|
+
add_method('+', [int_type], string_type) do |compiler, call, expression|
|
|
314
348
|
if expression
|
|
315
|
-
call.target
|
|
316
|
-
call.parameters
|
|
317
|
-
compiler.method.invokestatic
|
|
318
|
-
compiler.method.invokevirtual
|
|
349
|
+
compiler.visit(call.target, true)
|
|
350
|
+
compiler.visit(call.parameters(0), true)
|
|
351
|
+
compiler.method.invokestatic string_type, "valueOf", [string_type, int_type]
|
|
352
|
+
compiler.method.invokevirtual string_type, "concat", [string_type, string_type]
|
|
319
353
|
end
|
|
320
354
|
end
|
|
321
|
-
add_method('+', [
|
|
355
|
+
add_method('+', [long_type], string_type) do |compiler, call, expression|
|
|
322
356
|
if expression
|
|
323
|
-
call.target
|
|
324
|
-
call.parameters
|
|
325
|
-
compiler.method.invokestatic
|
|
326
|
-
compiler.method.invokevirtual
|
|
357
|
+
compiler.visit(call.target, true)
|
|
358
|
+
compiler.visit(call.parameters(0), true)
|
|
359
|
+
compiler.method.invokestatic string_type, "valueOf", [string_type, long_type]
|
|
360
|
+
compiler.method.invokevirtual string_type, "concat", [string_type, string_type]
|
|
327
361
|
end
|
|
328
362
|
end
|
|
329
|
-
add_method('+', [
|
|
363
|
+
add_method('+', [float_type], string_type) do |compiler, call, expression|
|
|
330
364
|
if expression
|
|
331
|
-
call.target
|
|
332
|
-
call.parameters
|
|
333
|
-
compiler.method.invokestatic
|
|
334
|
-
compiler.method.invokevirtual
|
|
365
|
+
compiler.visit(call.target, true)
|
|
366
|
+
compiler.visit(call.parameters(0), true)
|
|
367
|
+
compiler.method.invokestatic string_type, "valueOf", [string_type, float_type]
|
|
368
|
+
compiler.method.invokevirtual string_type, "concat", [string_type, string_type]
|
|
335
369
|
end
|
|
336
370
|
end
|
|
337
|
-
add_method('+', [
|
|
371
|
+
add_method('+', [double_type], string_type) do |compiler, call, expression|
|
|
338
372
|
if expression
|
|
339
|
-
call.target
|
|
340
|
-
call.parameters
|
|
341
|
-
compiler.method.invokestatic
|
|
342
|
-
compiler.method.invokevirtual
|
|
373
|
+
compiler.visit(call.target, true)
|
|
374
|
+
compiler.visit(call.parameters(0), true)
|
|
375
|
+
compiler.method.invokestatic string_type, "valueOf", [string_type, double_type]
|
|
376
|
+
compiler.method.invokevirtual string_type, "concat", [string_type, string_type]
|
|
343
377
|
end
|
|
344
378
|
end
|
|
345
|
-
add_method('[]', [
|
|
379
|
+
add_method('[]', [int_type], char_type) do |compiler, call, expression|
|
|
346
380
|
if expression
|
|
347
|
-
call.target
|
|
348
|
-
call.parameters
|
|
349
|
-
compiler.method.invokevirtual
|
|
381
|
+
compiler.visit(call.target, true)
|
|
382
|
+
compiler.visit(call.parameters(0), true)
|
|
383
|
+
compiler.method.invokevirtual string_type, "charAt", [char_type, int_type]
|
|
350
384
|
end
|
|
351
385
|
end
|
|
352
|
-
add_method('[]', [
|
|
386
|
+
add_method('[]', [int_type, int_type], string_type) do |compiler, call, expression|
|
|
353
387
|
if expression
|
|
354
|
-
call.target
|
|
355
|
-
call.parameters
|
|
388
|
+
compiler.visit(call.target, true)
|
|
389
|
+
compiler.visit(call.parameters(0), true)
|
|
356
390
|
compiler.method.dup
|
|
357
|
-
call.parameters[1]
|
|
391
|
+
compiler.visit(call.parameters[1], true)
|
|
358
392
|
compiler.method.iadd
|
|
359
|
-
compiler.method.invokevirtual
|
|
393
|
+
compiler.method.invokevirtual string_type, "substring", [string_type, int_type, int_type]
|
|
360
394
|
end
|
|
361
395
|
end
|
|
362
396
|
end
|
|
@@ -365,8 +399,9 @@ module Mirah::JVM::Types
|
|
|
365
399
|
class IterableType < Type
|
|
366
400
|
def add_intrinsics
|
|
367
401
|
super
|
|
402
|
+
return
|
|
368
403
|
add_enumerable_macros
|
|
369
|
-
add_macro('each',
|
|
404
|
+
add_macro('each', @type_system.block_type) do |transformer, call|
|
|
370
405
|
Mirah::AST::Loop.new(call.parent,
|
|
371
406
|
call.position, true, false) do |forloop|
|
|
372
407
|
it = transformer.tmp
|
|
@@ -400,4 +435,4 @@ module Mirah::JVM::Types
|
|
|
400
435
|
def add_intrinsics
|
|
401
436
|
end
|
|
402
437
|
end
|
|
403
|
-
end
|
|
438
|
+
end
|