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.
Files changed (171) hide show
  1. data/History.txt +372 -0
  2. data/README.txt +4 -5
  3. data/Rakefile +178 -55
  4. data/examples/appengine/Readme +3 -3
  5. data/examples/appengine/src/org/mirah/MirahApp.mirah +1 -1
  6. data/examples/appengine/src/org/mirah/list.dhtml +1 -1
  7. data/examples/bintrees.mirah +1 -1
  8. data/examples/edb.mirah +1 -1
  9. data/examples/fib.mirah +1 -1
  10. data/examples/interfaces.mirah +1 -1
  11. data/examples/macros/{string-each-char.mirah → string_each_char.mirah} +4 -5
  12. data/examples/maven/README.txt +1 -1
  13. data/examples/maven/src/main/mirah/hello_mirah.mirah +1 -1
  14. data/examples/plugins/appengine/Rakefile +1 -1
  15. data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/MetaModel.mirah +1 -1
  16. data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/Model.duby +1 -1
  17. data/examples/plugins/appengine/test/com/google/appengine/ext/duby/db/ModelTest.duby +1 -1
  18. data/examples/rosettacode/100-doors.mirah +6 -6
  19. data/examples/rosettacode/README.txt +3 -3
  20. data/examples/rosettacode/boolean-values.mirah +1 -1
  21. data/examples/rosettacode/comments.mirah +1 -1
  22. data/examples/rosettacode/count-occurrences-of-a-substring.mirah +1 -1
  23. data/examples/rosettacode/factorial.mirah +1 -1
  24. data/examples/rosettacode/fibonacci.mirah +1 -1
  25. data/examples/rosettacode/fizz-buzz.mirah +2 -2
  26. data/examples/rosettacode/flatten-a-list.mirah +4 -4
  27. data/examples/rosettacode/guess-the-number.mirah +2 -2
  28. data/examples/rosettacode/hamming-numbers.mirah +4 -4
  29. data/examples/rosettacode/is-string-numeric.mirah +22 -22
  30. data/examples/rosettacode/palindrome.mirah +2 -2
  31. data/examples/rosettacode/random-numbers.mirah +1 -1
  32. data/examples/rosettacode/repeat-a-string.mirah +1 -1
  33. data/examples/rosettacode/reverse-a-string.mirah +1 -1
  34. data/examples/rosettacode/rot-13.mirah +5 -5
  35. data/examples/rosettacode/secure-temporary-file.mirah +2 -2
  36. data/examples/rosettacode/sleep.mirah +1 -1
  37. data/examples/rosettacode/string-length.mirah +5 -5
  38. data/examples/swing.mirah +1 -1
  39. data/examples/test.edb +1 -1
  40. data/javalib/mirah-bootstrap.jar +0 -0
  41. data/javalib/mirah-builtins.jar +0 -0
  42. data/javalib/mirah-parser.jar +0 -0
  43. data/javalib/mirah-util.jar +0 -0
  44. data/lib/duby.rb +1 -1
  45. data/lib/mirah.rb +50 -28
  46. data/lib/mirah/ast.rb +15 -605
  47. data/lib/mirah/ast/scope.rb +98 -69
  48. data/lib/mirah/commands.rb +1 -1
  49. data/lib/mirah/commands/base.rb +7 -7
  50. data/lib/mirah/commands/compile.rb +3 -3
  51. data/lib/mirah/commands/parse.rb +7 -5
  52. data/lib/mirah/commands/run.rb +12 -19
  53. data/lib/mirah/compiler.rb +15 -23
  54. data/lib/mirah/errors.rb +16 -1
  55. data/lib/mirah/generator.rb +79 -39
  56. data/lib/mirah/jvm/compiler.rb +1 -19
  57. data/lib/mirah/jvm/compiler/base.rb +233 -90
  58. data/lib/mirah/jvm/compiler/jvm_bytecode.rb +675 -363
  59. data/lib/mirah/jvm/method_lookup.rb +134 -65
  60. data/lib/mirah/jvm/typer.rb +10 -5
  61. data/lib/mirah/jvm/types.rb +10 -2
  62. data/lib/mirah/jvm/types/array_type.rb +10 -12
  63. data/lib/mirah/{compiler/type.rb → jvm/types/ast_ext.rb} +12 -8
  64. data/lib/mirah/jvm/types/basic_types.rb +26 -33
  65. data/lib/mirah/jvm/types/bitescript_ext.rb +1 -1
  66. data/lib/mirah/jvm/types/block_type.rb +15 -0
  67. data/lib/mirah/jvm/types/boolean.rb +8 -4
  68. data/lib/mirah/jvm/types/dynamic_type.rb +12 -13
  69. data/lib/mirah/jvm/types/enumerable.rb +7 -7
  70. data/lib/mirah/jvm/types/extensions.rb +11 -6
  71. data/lib/mirah/jvm/types/factory.rb +624 -94
  72. data/lib/mirah/jvm/types/floats.rb +21 -15
  73. data/lib/mirah/jvm/types/generic_type.rb +72 -0
  74. data/lib/mirah/jvm/types/implicit_nil_type.rb +29 -0
  75. data/lib/mirah/jvm/types/integers.rb +26 -71
  76. data/lib/mirah/jvm/types/interface_definition.rb +3 -3
  77. data/lib/mirah/jvm/types/intrinsics.rb +203 -168
  78. data/lib/mirah/jvm/types/literals.rb +6 -6
  79. data/lib/mirah/jvm/types/meta_type.rb +13 -4
  80. data/lib/mirah/jvm/types/methods.rb +281 -93
  81. data/lib/mirah/jvm/types/null_type.rb +17 -5
  82. data/lib/mirah/jvm/types/number.rb +10 -7
  83. data/lib/mirah/jvm/types/primitive_type.rb +17 -6
  84. data/lib/mirah/jvm/types/source_mirror.rb +12 -7
  85. data/lib/mirah/jvm/types/type.rb +107 -23
  86. data/lib/mirah/jvm/types/type_definition.rb +25 -10
  87. data/lib/mirah/jvm/types/unreachable_type.rb +1 -1
  88. data/lib/mirah/jvm/types/void_type.rb +3 -3
  89. data/lib/mirah/parser.rb +154 -16
  90. data/lib/mirah/plugin/edb.rb +1 -1
  91. data/lib/mirah/transform.rb +1 -2
  92. data/lib/mirah/transform/ast_ext.rb +24 -43
  93. data/lib/mirah/transform/transformer.rb +29 -224
  94. data/lib/mirah/typer.rb +2 -16
  95. data/lib/mirah/util/argument_processor.rb +25 -10
  96. data/lib/mirah/util/class_loader.rb +1 -1
  97. data/lib/mirah/util/compilation_state.rb +16 -17
  98. data/lib/mirah/util/delegate.rb +2 -2
  99. data/lib/mirah/util/logging.rb +110 -0
  100. data/lib/mirah/util/process_errors.rb +69 -11
  101. data/lib/mirah/version.rb +1 -1
  102. data/test/core/commands_test.rb +6 -24
  103. data/test/core/env_test.rb +5 -5
  104. data/{lib/mirah/jvm/source_generator/typer.rb → test/core/generator_test.rb} +9 -9
  105. data/test/core/typer_test.rb +196 -158
  106. data/test/core/util/argument_processor_test.rb +10 -10
  107. data/test/core/util/class_loader_test.rb +6 -5
  108. data/test/fixtures/org/foo/LowerCaseInnerClass$inner.class +0 -0
  109. data/test/fixtures/org/foo/LowerCaseInnerClass.class +0 -0
  110. data/test/fixtures/org/foo/LowerCaseInnerClass.java +7 -0
  111. data/test/jvm/annotations_test.rb +5 -5
  112. data/test/jvm/blocks_test.rb +140 -88
  113. data/test/jvm/bytecode_test_helper.rb +112 -94
  114. data/test/jvm/cast_test.rb +162 -0
  115. data/test/jvm/constructors_test.rb +18 -8
  116. data/test/jvm/enumerable_test.rb +77 -44
  117. data/test/jvm/example_test.rb +53 -0
  118. data/test/jvm/factory_test.rb +7 -1
  119. data/test/jvm/generics_test.rb +57 -0
  120. data/test/jvm/hash_test.rb +106 -0
  121. data/test/jvm/import_test.rb +81 -0
  122. data/test/jvm/interface_test.rb +73 -0
  123. data/test/jvm/java_typer_test.rb +92 -66
  124. data/{lib/mirah/typer/base.rb → test/jvm/jvm_commands_test.rb} +6 -10
  125. data/test/jvm/jvm_compiler_test.rb +170 -604
  126. data/test/jvm/list_extensions_test.rb +23 -0
  127. data/test/jvm/macros_test.rb +197 -32
  128. data/test/jvm/main_method_test.rb +4 -4
  129. data/test/jvm/numeric_extensions_test.rb +13 -0
  130. data/test/jvm/rescue_test.rb +73 -16
  131. data/test/jvm/varargs_test.rb +65 -0
  132. data/test/test_helper.rb +1 -2
  133. metadata +234 -251
  134. data/examples/SortClosure$__xform_tmp_1.class +0 -0
  135. data/examples/SortClosure$__xform_tmp_2.class +0 -0
  136. data/examples/SortClosure.class +0 -0
  137. data/examples/macros/StringEachChar$Extension1.class +0 -0
  138. data/lib/mirah/ast/call.rb +0 -345
  139. data/lib/mirah/ast/class.rb +0 -359
  140. data/lib/mirah/ast/flow.rb +0 -381
  141. data/lib/mirah/ast/intrinsics.rb +0 -563
  142. data/lib/mirah/ast/literal.rb +0 -178
  143. data/lib/mirah/ast/local.rb +0 -112
  144. data/lib/mirah/ast/method.rb +0 -408
  145. data/lib/mirah/ast/structure.rb +0 -387
  146. data/lib/mirah/ast/type.rb +0 -146
  147. data/lib/mirah/commands/base.rb~ +0 -57
  148. data/lib/mirah/compiler/call.rb +0 -45
  149. data/lib/mirah/compiler/class.rb +0 -81
  150. data/lib/mirah/compiler/flow.rb +0 -109
  151. data/lib/mirah/compiler/literal.rb +0 -130
  152. data/lib/mirah/compiler/local.rb +0 -59
  153. data/lib/mirah/compiler/method.rb +0 -44
  154. data/lib/mirah/compiler/structure.rb +0 -65
  155. data/lib/mirah/jvm/compiler/java_source.rb +0 -787
  156. data/lib/mirah/jvm/method_lookup.rb~ +0 -247
  157. data/lib/mirah/jvm/source_generator/builder.rb +0 -468
  158. data/lib/mirah/jvm/source_generator/loops.rb +0 -131
  159. data/lib/mirah/jvm/source_generator/precompile.rb +0 -210
  160. data/lib/mirah/plugin/gwt.rb +0 -189
  161. data/lib/mirah/plugin/java.rb +0 -70
  162. data/lib/mirah/transform/error.rb +0 -13
  163. data/lib/mirah/transform/helper.rb +0 -765
  164. data/lib/mirah/typer/simple.rb +0 -384
  165. data/lib/mirah/version.rb~ +0 -18
  166. data/test/core/ast_test.rb +0 -382
  167. data/test/core/compilation_test.rb +0 -130
  168. data/test/core/macros_test.rb +0 -61
  169. data/test/jvm/javac_test_helper.rb +0 -89
  170. data/test/jvm/jvm_compiler_test.rb~ +0 -2181
  171. 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
- Float
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 widen(builder, type)
52
- case type
53
- when Float
50
+
51
+ def compile_widen(builder, type)
52
+ case type.name
53
+ when 'float'
54
54
  # Do nothing
55
- when Double
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
- Double
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 widen(builder, type)
96
- if type != Double
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 widen(builder, type)
33
- case type
34
- when Byte, Short, Int
31
+
32
+ def compile_widen(builder, type)
33
+ case type.name
34
+ when 'byte', 'short', 'int'
35
35
  # do nothing
36
- when Long
36
+ when 'long'
37
37
  builder.i2l
38
- when Float
38
+ when 'float'
39
39
  builder.i2f
40
- when Double
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
- Int
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
- Long
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 widen(builder, type)
150
- case type
151
- when Long
102
+ def compile_widen(builder, type)
103
+ case type.name
104
+ when 'long'
152
105
  # do nothing
153
- when Float
106
+ when 'float'
154
107
  builder.l2f
155
- when Double
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 add_macro(name, *args, &block)
56
- type = Mirah::AST::InlineCode.new(&block)
57
- intrinsics[name][args] = Intrinsic.new(self, name, args, type) do
58
- raise "Macro should be expanded, no called!"
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
- def add_compiled_macro(klass, name, arg_types)
63
- add_macro(name, *arg_types) do |mirah, call|
64
- # Ick. We need to preserve the scope of the arguments to the macro.
65
- # However the only way to do that is to wrap them in a ScopedBody.
66
- # It'd be better if we didn't have to expose this wrapper node to
67
- # the user code.
68
- #
69
- if call.block && call.name != 'quote'
70
- call.block.body = wrap_with_scoped_body call, call.block.body
71
- end
72
-
73
- call.parameters = call.parameters.map do |arg|
74
- wrap_with_scoped_body call, arg
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::ScopedBody.new(call.parent, call.position)
81
- body << ast
82
-
83
- # if the macro was called on something, and that something
84
- # was not a class only containing macros, reassign self for
85
- # the body.
86
- if call.target && !call.target.is_a?(Mirah::AST::Builtin)
87
- body.static_scope.self_type = call.target.inferred_type!
88
- body.static_scope.self_node = call.target
89
- end
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(call.parent, call.position)
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 wrap_with_scoped_body call, node
99
- wrapper = Mirah::AST::ScopedBody.new(call.parent, call.position)
100
- wrapper.static_scope = call.scope.static_scope
101
- wrapper << node
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
- next if interface.error?
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
- factory = Mirah::AST.type_factory
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('duby.anno.Extensions')
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 |macro|
137
- macro_name = macro['name']
138
- class_name = macro['class']
139
- types = BiteScript::ASM::Type.get_argument_types(macro['signature'])
140
- args = types.map do |type|
141
- if type.class_name == 'duby.lang.compiler.Block'
142
- Mirah::AST::TypeReference::BlockType
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
- add_method('nil?', [], Boolean) do |compiler, call, expression|
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.compile(compiler, true)
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('==', [Object], Boolean) do |compiler, call, expression|
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.compile(compiler, true)
168
- call.parameters[0].compile(compiler, true)
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('!=', [Object], Boolean) do |compiler, call, expression|
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.compile(compiler, true)
179
- call.parameters[0].compile(compiler, true)
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
- add_macro('kind_of?', ClassType) do |transformer, call|
187
- klass, object = call.parameters[0], call.target
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[0].inferred_type!
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
- add_enumerable_macros
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
- '[]', [Int], component_type) do |compiler, call, expression|
265
+ '[]', [int_type], component_type) do |compiler, call, expression|
214
266
  if expression
215
- call.target.compile(compiler, true)
216
- call.parameters[0].compile(compiler, true)
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
- [Int, component_type],
274
+ [int_type, component_type],
223
275
  component_type) do |compiler, call, expression|
224
- call.target.compile(compiler, true)
225
- convert_args(compiler, call.parameters, [Int, component_type])
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[1].compile(compiler, true)
280
+ compiler.visit(call.parameters(1), true)
229
281
  end
230
282
  end
231
283
 
232
- add_method('length', [], Int) do |compiler, call, expression|
233
- call.target.compile(compiler, true)
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', [], ClassType) do |compiler, call, expression|
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
- add_macro('cast', Object) do |transformer, call|
282
- call.cast = true
283
- call.resolve_if(nil) { unmeta }
284
- call
285
- end
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
- add_method('+', [String], String) do |compiler, call, expression|
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', String).call(compiler, call, expression)
328
+ java_method('concat', string_type).call(compiler, call, expression)
295
329
  end
296
330
  end
297
- add_method('+', [Boolean], String) do |compiler, call, expression|
331
+ add_method('+', [bool_type], string_type) do |compiler, call, expression|
298
332
  if expression
299
- call.target.compile(compiler, true)
300
- call.parameters[0].compile(compiler, true)
301
- compiler.method.invokestatic String, "valueOf", [String, Boolean]
302
- compiler.method.invokevirtual String, "concat", [String, String]
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('+', [Char], String) do |compiler, call, expression|
339
+ add_method('+', [char_type], string_type) do |compiler, call, expression|
306
340
  if expression
307
- call.target.compile(compiler, true)
308
- call.parameters[0].compile(compiler, true)
309
- compiler.method.invokestatic String, "valueOf", [String, Char]
310
- compiler.method.invokevirtual String, "concat", [String, String]
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('+', [Int], String) do |compiler, call, expression|
347
+ add_method('+', [int_type], string_type) do |compiler, call, expression|
314
348
  if expression
315
- call.target.compile(compiler, true)
316
- call.parameters[0].compile(compiler, true)
317
- compiler.method.invokestatic String, "valueOf", [String, Int]
318
- compiler.method.invokevirtual String, "concat", [String, String]
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('+', [Long], String) do |compiler, call, expression|
355
+ add_method('+', [long_type], string_type) do |compiler, call, expression|
322
356
  if expression
323
- call.target.compile(compiler, true)
324
- call.parameters[0].compile(compiler, true)
325
- compiler.method.invokestatic String, "valueOf", [String, Long]
326
- compiler.method.invokevirtual String, "concat", [String, String]
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('+', [Float], String) do |compiler, call, expression|
363
+ add_method('+', [float_type], string_type) do |compiler, call, expression|
330
364
  if expression
331
- call.target.compile(compiler, true)
332
- call.parameters[0].compile(compiler, true)
333
- compiler.method.invokestatic String, "valueOf", [String, Float]
334
- compiler.method.invokevirtual String, "concat", [String, String]
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('+', [Double], String) do |compiler, call, expression|
371
+ add_method('+', [double_type], string_type) do |compiler, call, expression|
338
372
  if expression
339
- call.target.compile(compiler, true)
340
- call.parameters[0].compile(compiler, true)
341
- compiler.method.invokestatic String, "valueOf", [String, Double]
342
- compiler.method.invokevirtual String, "concat", [String, String]
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('[]', [Int], Char) do |compiler, call, expression|
379
+ add_method('[]', [int_type], char_type) do |compiler, call, expression|
346
380
  if expression
347
- call.target.compile(compiler, true)
348
- call.parameters[0].compile(compiler, true)
349
- compiler.method.invokevirtual String, "charAt", [Char, Int]
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('[]', [Int, Int], String) do |compiler, call, expression|
386
+ add_method('[]', [int_type, int_type], string_type) do |compiler, call, expression|
353
387
  if expression
354
- call.target.compile(compiler, true)
355
- call.parameters[0].compile(compiler, true)
388
+ compiler.visit(call.target, true)
389
+ compiler.visit(call.parameters(0), true)
356
390
  compiler.method.dup
357
- call.parameters[1].compile(compiler, true)
391
+ compiler.visit(call.parameters[1], true)
358
392
  compiler.method.iadd
359
- compiler.method.invokevirtual String, "substring", [String, Int, Int]
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', Mirah::AST.block_type) do |transformer, call|
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