mirah 0.0.7-java → 0.0.8-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. data/History.txt +181 -0
  2. data/README.txt +6 -10
  3. data/Rakefile +86 -9
  4. data/bin/mirah +2 -0
  5. data/bin/mirahc +2 -0
  6. data/bin/mirahp +2 -0
  7. data/{bin/dubyp → examples/interfaces.mirah} +16 -9
  8. data/examples/macros/square.mirah +12 -0
  9. data/examples/macros/square_int.mirah +12 -0
  10. data/examples/macros/string-each-char.mirah +14 -0
  11. data/examples/maven/README.txt +2 -0
  12. data/examples/maven/pom.xml +23 -0
  13. data/examples/maven/src/main/mirah/hello_mirah.mirah +9 -0
  14. data/examples/rosettacode/100-doors.mirah +44 -0
  15. data/examples/rosettacode/99-bottles-of-beer.mirah +13 -0
  16. data/examples/rosettacode/README.txt +9 -0
  17. data/examples/rosettacode/boolean-values.mirah +29 -0
  18. data/examples/rosettacode/comments.mirah +2 -0
  19. data/examples/rosettacode/copy-a-string.mirah +10 -0
  20. data/examples/rosettacode/count-occurrences-of-a-substring.mirah +40 -0
  21. data/examples/rosettacode/create-a-file.mirah +6 -0
  22. data/examples/rosettacode/empty-string.mirah +9 -0
  23. data/examples/rosettacode/factorial.mirah +10 -0
  24. data/examples/rosettacode/fibonacci.mirah +21 -0
  25. data/examples/rosettacode/file-size.mirah +5 -0
  26. data/examples/rosettacode/fizz-buzz.mirah +21 -0
  27. data/examples/rosettacode/flatten-a-list.mirah +24 -0
  28. data/examples/rosettacode/guess-the-number.mirah +21 -0
  29. data/examples/rosettacode/is-string-numeric.mirah +127 -0
  30. data/examples/rosettacode/palindrome.mirah +14 -0
  31. data/examples/rosettacode/repeat-a-string.mirah +9 -0
  32. data/examples/rosettacode/reverse-a-string.mirah +6 -0
  33. data/examples/rosettacode/rot-13.mirah +20 -0
  34. data/examples/rosettacode/user-input.mirah +4 -0
  35. data/examples/sort_closure.mirah +1 -1
  36. data/javalib/dynalink-0.2.jar +0 -0
  37. data/javalib/mirah-bootstrap.jar +0 -0
  38. data/lib/mirah.rb +7 -16
  39. data/lib/mirah/ast.rb +22 -92
  40. data/lib/mirah/ast/call.rb +41 -9
  41. data/lib/mirah/ast/class.rb +34 -6
  42. data/lib/mirah/ast/flow.rb +17 -5
  43. data/lib/mirah/ast/intrinsics.rb +50 -8
  44. data/lib/mirah/ast/literal.rb +7 -0
  45. data/lib/mirah/ast/local.rb +9 -1
  46. data/lib/mirah/ast/method.rb +21 -8
  47. data/lib/mirah/ast/scope.rb +1 -1
  48. data/lib/mirah/ast/structure.rb +81 -15
  49. data/lib/mirah/ast/type.rb +4 -0
  50. data/{bin/dubyc → lib/mirah/commands.rb} +4 -11
  51. data/lib/mirah/commands/base.rb +54 -0
  52. data/lib/mirah/commands/compile.rb +39 -0
  53. data/{examples/wiki/Rakefile → lib/mirah/commands/parse.rb} +18 -17
  54. data/lib/mirah/commands/run.rb +73 -0
  55. data/lib/mirah/compiler.rb +37 -417
  56. data/lib/mirah/compiler/call.rb +45 -0
  57. data/lib/mirah/compiler/class.rb +81 -0
  58. data/lib/mirah/compiler/flow.rb +109 -0
  59. data/lib/mirah/compiler/literal.rb +130 -0
  60. data/lib/mirah/compiler/local.rb +59 -0
  61. data/lib/mirah/compiler/method.rb +44 -0
  62. data/lib/mirah/compiler/structure.rb +65 -0
  63. data/lib/mirah/compiler/type.rb +27 -0
  64. data/lib/mirah/env.rb +4 -6
  65. data/lib/mirah/generator.rb +61 -0
  66. data/lib/mirah/jvm/compiler.rb +8 -867
  67. data/lib/mirah/jvm/compiler/base.rb +270 -0
  68. data/lib/mirah/jvm/compiler/java_source.rb +779 -0
  69. data/lib/mirah/jvm/compiler/jvm_bytecode.rb +851 -0
  70. data/lib/mirah/jvm/method_lookup.rb +21 -2
  71. data/lib/mirah/jvm/source_generator/builder.rb +10 -13
  72. data/lib/mirah/jvm/source_generator/loops.rb +99 -93
  73. data/lib/mirah/jvm/source_generator/precompile.rb +3 -2
  74. data/lib/mirah/jvm/typer.rb +3 -3
  75. data/lib/mirah/jvm/types.rb +10 -426
  76. data/lib/mirah/jvm/types/array_type.rb +62 -0
  77. data/lib/mirah/jvm/types/basic_types.rb +1 -0
  78. data/lib/mirah/jvm/types/dynamic_type.rb +46 -0
  79. data/lib/mirah/jvm/types/factory.rb +23 -5
  80. data/lib/mirah/jvm/types/interface_definition.rb +20 -0
  81. data/lib/mirah/jvm/types/intrinsics.rb +15 -3
  82. data/lib/mirah/jvm/types/meta_type.rb +45 -0
  83. data/lib/mirah/jvm/types/methods.rb +12 -5
  84. data/lib/mirah/jvm/types/null_type.rb +27 -0
  85. data/lib/mirah/jvm/types/primitive_type.rb +38 -0
  86. data/lib/mirah/jvm/types/source_mirror.rb +266 -0
  87. data/lib/mirah/jvm/types/type.rb +173 -0
  88. data/lib/mirah/jvm/types/type_definition.rb +55 -0
  89. data/lib/mirah/jvm/types/unreachable_type.rb +27 -0
  90. data/lib/mirah/jvm/types/void_type.rb +19 -0
  91. data/lib/mirah/parser.rb +90 -0
  92. data/lib/mirah/plugin/gwt.rb +5 -5
  93. data/lib/mirah/plugin/java.rb +1 -1
  94. data/lib/mirah/transform.rb +4 -321
  95. data/lib/mirah/transform/ast_ext.rb +63 -0
  96. data/lib/mirah/transform/error.rb +13 -0
  97. data/lib/mirah/transform/helper.rb +761 -0
  98. data/lib/mirah/transform/transformer.rb +255 -0
  99. data/lib/mirah/typer.rb +2 -383
  100. data/{bin/duby → lib/mirah/typer/base.rb} +12 -10
  101. data/lib/mirah/typer/simple.rb +377 -0
  102. data/lib/mirah/util/argument_processor.rb +114 -0
  103. data/lib/mirah/util/class_loader.rb +37 -0
  104. data/lib/mirah/util/compilation_state.rb +51 -0
  105. data/lib/mirah/util/process_errors.rb +33 -0
  106. data/lib/mirah/version.rb +1 -1
  107. data/lib/mirah_task.rb +3 -2
  108. data/test/{test_ast.rb → core/test_ast.rb} +6 -0
  109. data/test/{test_compilation.rb → core/test_compilation.rb} +0 -0
  110. data/test/{test_env.rb → core/test_env.rb} +24 -25
  111. data/test/{test_macros.rb → core/test_macros.rb} +2 -4
  112. data/test/{test_typer.rb → core/test_typer.rb} +0 -3
  113. data/test/jvm/bytecode_test_helper.rb +181 -0
  114. data/test/{test_javac_compiler.rb → jvm/javac_test_helper.rb} +38 -22
  115. data/test/jvm/test_enumerable.rb +304 -0
  116. data/test/{test_java_typer.rb → jvm/test_java_typer.rb} +2 -4
  117. data/test/{test_jvm_compiler.rb → jvm/test_jvm_compiler.rb} +146 -443
  118. data/test/jvm/test_macros.rb +147 -0
  119. data/test/jvm/test_main_method.rb +15 -0
  120. data/test/{test_gwt.rb → plugins/test_gwt.rb} +0 -2
  121. metadata +103 -91
  122. data/bin/jrubyp +0 -52
  123. data/examples/wiki/src/org/mirah/wiki/MirahWiki.duby +0 -339
  124. data/examples/wiki/src/org/mirah/wiki/edit.eduby.html +0 -42
  125. data/examples/wiki/src/org/mirah/wiki/error.eduby.html +0 -2
  126. data/examples/wiki/src/org/mirah/wiki/layout.eduby.html +0 -69
  127. data/examples/wiki/src/org/mirah/wiki/parser.eduby.html +0 -7
  128. data/examples/wiki/src/org/mirah/wiki/view.eduby.html +0 -15
  129. data/examples/wiki/war/WEB-INF/classes/test/HeredocContext.class +0 -0
  130. data/examples/wiki/war/WEB-INF/classes/test/MirahParser.class +0 -0
  131. data/examples/wiki/war/WEB-INF/lib/appengine-api.jar +0 -0
  132. data/examples/wiki/war/WEB-INF/lib/dubydatastore.jar +0 -0
  133. data/examples/wiki/war/WEB-INF/lib/jmeta-runtime.jar +0 -0
  134. data/examples/wiki/war/WEB-INF/lib/pegdown-stubs.jar +0 -0
  135. data/examples/wiki/war/WEB-INF/pegdown.jar +0 -0
  136. data/examples/wiki/war/app.yaml +0 -21
  137. data/examples/wiki/war/public/favicon.ico +0 -0
  138. data/examples/wiki/war/public/images/appengine_duby.png +0 -0
  139. data/examples/wiki/war/public/images/back.gif +0 -0
  140. data/examples/wiki/war/public/images/dir.gif +0 -0
  141. data/examples/wiki/war/public/images/file.gif +0 -0
  142. data/examples/wiki/war/public/javascripts/prettify.js +0 -61
  143. data/examples/wiki/war/public/robots.txt +0 -0
  144. data/examples/wiki/war/public/stylesheets/main.css +0 -156
  145. data/examples/wiki/war/public/stylesheets/prettify.css +0 -1
  146. data/examples/wiki/war/public/stylesheets/sh_style.css +0 -66
  147. data/examples/wiki/war/public/stylesheets/source.css +0 -21
  148. data/examples/wiki/war/public/wmd/images/bg-fill.png +0 -0
  149. data/examples/wiki/war/public/wmd/images/bg.png +0 -0
  150. data/examples/wiki/war/public/wmd/images/blockquote.png +0 -0
  151. data/examples/wiki/war/public/wmd/images/bold.png +0 -0
  152. data/examples/wiki/war/public/wmd/images/code.png +0 -0
  153. data/examples/wiki/war/public/wmd/images/h1.png +0 -0
  154. data/examples/wiki/war/public/wmd/images/hr.png +0 -0
  155. data/examples/wiki/war/public/wmd/images/img.png +0 -0
  156. data/examples/wiki/war/public/wmd/images/italic.png +0 -0
  157. data/examples/wiki/war/public/wmd/images/link.png +0 -0
  158. data/examples/wiki/war/public/wmd/images/ol.png +0 -0
  159. data/examples/wiki/war/public/wmd/images/redo.png +0 -0
  160. data/examples/wiki/war/public/wmd/images/separator.png +0 -0
  161. data/examples/wiki/war/public/wmd/images/ul.png +0 -0
  162. data/examples/wiki/war/public/wmd/images/undo.png +0 -0
  163. data/examples/wiki/war/public/wmd/images/wmd-on.png +0 -0
  164. data/examples/wiki/war/public/wmd/images/wmd.png +0 -0
  165. data/examples/wiki/war/public/wmd/showdown.js +0 -421
  166. data/examples/wiki/war/public/wmd/wmd-base.js +0 -1799
  167. data/examples/wiki/war/public/wmd/wmd-plus.js +0 -311
  168. data/examples/wiki/war/public/wmd/wmd.js +0 -73
  169. data/examples/wiki/war/src/org/mirah/wiki/MirahWiki.duby +0 -339
  170. data/examples/wiki/war/src/org/mirah/wiki/edit.eduby.html +0 -42
  171. data/examples/wiki/war/src/org/mirah/wiki/error.eduby.html +0 -2
  172. data/examples/wiki/war/src/org/mirah/wiki/layout.eduby.html +0 -69
  173. data/examples/wiki/war/src/org/mirah/wiki/parser.eduby.html +0 -7
  174. data/examples/wiki/war/src/org/mirah/wiki/view.eduby.html +0 -15
  175. data/javalib/dynalink-0.1.jar +0 -0
  176. data/javalib/jsr292-mock.jar +0 -0
  177. data/lib/mirah/class_loader.rb +0 -35
  178. data/lib/mirah/compilation_state.rb +0 -28
  179. data/lib/mirah/impl.rb +0 -273
  180. data/lib/mirah/jvm/base.rb +0 -267
  181. data/lib/mirah/jvm/source_compiler.rb +0 -760
  182. data/lib/mirah/transform2.rb +0 -752
@@ -0,0 +1,14 @@
1
+
2
+ def reverse(s:string)
3
+ StringBuilder.new(s).reverse.toString()
4
+ end
5
+
6
+ def palindrome?(s:string)
7
+ s.equals(reverse(s))
8
+ end
9
+
10
+ puts palindrome?("anna") # ==> true
11
+ puts palindrome?("Erik") # ==> false
12
+ puts palindrome?("palindroom-moordnilap") # ==> true
13
+ puts nil # ==> null
14
+
@@ -0,0 +1,9 @@
1
+ x = ""
2
+
3
+ 5.times do
4
+ x = x + "ha"
5
+ end
6
+
7
+ puts x # ==> "hahahahaha"
8
+
9
+
@@ -0,0 +1,6 @@
1
+
2
+ def reverse(s:string)
3
+ StringBuilder.new(s).reverse
4
+ end
5
+
6
+ puts reverse('reversed')
@@ -0,0 +1,20 @@
1
+
2
+
3
+ def rot13 (value:string)
4
+ result = ""
5
+ d = ' '.toCharArray[0]
6
+ value.toCharArray.each do |c|
7
+ testChar = Character.toLowerCase(c)
8
+ if testChar <= 'm'.toCharArray[0] && testChar >= 'a'.toCharArray[0] then
9
+ d = char(c + 13)
10
+ end
11
+ if testChar <= 'z'.toCharArray[0] && testChar >= 'n'.toCharArray[0] then
12
+ d = char(c - 13)
13
+ end
14
+ result += d
15
+ end
16
+ result
17
+ end
18
+
19
+
20
+ puts rot13("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
@@ -0,0 +1,4 @@
1
+
2
+ s = System.console.readLine()
3
+
4
+ puts s
@@ -18,5 +18,5 @@ import java.util.ArrayList
18
18
 
19
19
  list = ArrayList.new [9,5,2,6,8,5,0,3,6,1,8,3,6,4,7,5,0,8,5,6,7,2,3]
20
20
  puts "unsorted: #{list}"
21
- Collections.sort(list) {|a,b| Integer(a).compareTo(b)}
21
+ Collections.sort(list) {|a,b| Integer(a).compareTo(Integer(b))}
22
22
  puts "sorted: #{list}"
Binary file
Binary file
@@ -22,31 +22,26 @@ require 'mirah/typer'
22
22
  require 'mirah/compiler'
23
23
  require 'mirah/env'
24
24
  require 'mirah/errors'
25
- require 'mirah/class_loader'
26
- begin
27
- require 'bitescript'
28
- rescue LoadError
29
- $: << File.dirname(__FILE__) + '/../../bitescript/lib'
30
- require 'bitescript'
31
- end
25
+ require 'bitescript'
26
+
32
27
  require 'mirah/jvm/compiler'
33
28
  require 'mirah/jvm/typer'
34
29
  Dir[File.dirname(__FILE__) + "/mirah/plugin/*"].each {|file| require "#{file}" if file =~ /\.rb$/}
35
- require 'mirah/impl'
36
- require 'mirah/compilation_state'
37
30
  require 'jruby'
38
31
 
32
+ require 'mirah/commands'
33
+
39
34
  module Mirah
40
35
  def self.run(*args)
41
- Impl.new.run(*args)
36
+ Mirah::Commands::Run.new(args).execute
42
37
  end
43
38
 
44
39
  def self.compile(*args)
45
- Impl.new.compile(*args)
40
+ Mirah::Commands::Compile.new(args).execute
46
41
  end
47
42
 
48
43
  def self.parse(*args)
49
- Impl.new.parse(*args)
44
+ Mirah::Commands::Parse.new(args).execute
50
45
  end
51
46
 
52
47
  def self.plugins
@@ -89,7 +84,3 @@ module Mirah
89
84
  end
90
85
  end
91
86
  end
92
-
93
- if __FILE__ == $0
94
- Mirah.run(ARGV[0], *ARGV[1..-1])
95
- end
@@ -37,6 +37,10 @@ module Mirah
37
37
  attr_accessor :newline
38
38
  attr_accessor :inferred_type
39
39
 
40
+ # defines children of a node by name,
41
+ # respecting call order.
42
+ #
43
+ # @param [Symbol] name the name of the child node
40
44
  def self.child(name)
41
45
  @children ||= []
42
46
  index = @children.size
@@ -60,6 +64,13 @@ module Mirah
60
64
  java.util.ArrayList.new(@children)
61
65
  end
62
66
 
67
+ #
68
+ # @param [Mirah::AST::Node] parent the parent node
69
+ # @param [JMetaPosition] position the location in the source code of the node
70
+ # @param [Array] children the list of child nodes
71
+ # @yield [self] yields the node being initialized, expects the list of children as the result.
72
+ # takes priority over the `children` argument.
73
+ #
63
74
  def initialize(parent, position, children = [])
64
75
  JRuby.reference(self.class).setRubyClassAllocator(JRuby.reference(self.class).reified_class)
65
76
  unless parent.nil? || Mirah::AST::Node === parent
@@ -271,6 +282,10 @@ module Mirah
271
282
  end
272
283
  inferred_type
273
284
  end
285
+
286
+ def top_level?
287
+ false
288
+ end
274
289
  end
275
290
 
276
291
 
@@ -356,99 +371,9 @@ module Mirah
356
371
  end
357
372
  end
358
373
 
359
- class Constant < Node
360
- include Named
361
- include Scoped
362
- attr_accessor :array
363
-
364
- def initialize(parent, position, name)
365
- self.name = name
366
- super(parent, position, [])
367
- end
368
-
369
- def infer(typer, expression)
370
- @inferred_type ||= begin
371
- # TODO lookup constant, inline if we're supposed to.
372
- typer.type_reference(scope, name, @array, true)
373
- end
374
- end
375
-
376
- def type_reference(typer)
377
- typer.type_reference(scope, @name, @array)
378
- end
379
- end
380
-
381
- class Self < Node
382
- include Scoped
383
- def infer(typer, expression)
384
- @inferred_type ||= scope.static_scope.self_type
385
- end
386
- end
387
-
388
- class Annotation < Node
389
- attr_reader :values
390
- attr_accessor :runtime
391
- alias runtime? runtime
392
-
393
- child :name_node
394
-
395
- def initialize(parent, position, name=nil, &block)
396
- super(parent, position, &block)
397
- if name
398
- @name = if name.respond_to?(:class_name)
399
- name.class_name
400
- else
401
- name.name
402
- end
403
- end
404
- @values = {}
405
- end
406
-
407
- def name
408
- @name
409
- end
410
-
411
- def type
412
- BiteScript::ASM::Type.getObjectType(@name.tr('.', '/'))
413
- end
414
-
415
- def []=(name, value)
416
- @values[name] = value
417
- end
418
-
419
- def [](name)
420
- @values[name]
421
- end
422
-
423
- def infer(typer, expression)
424
- @inferred ||= begin
425
- @name = name_node.type_reference(typer).name if name_node
426
- @values.each do |name, value|
427
- if Node === value
428
- @values[name] = annotation_value(value, typer)
429
- end
430
- end
431
- true
432
- end
433
- end
434
-
435
- def annotation_value(node, typer)
436
- case node
437
- when String
438
- java.lang.String.new(node.literal)
439
- when Array
440
- node.children.map {|node| annotation_value(node, typer)}
441
- else
442
- # TODO Support other types
443
- ref = value.type_refence(typer)
444
- desc = BiteScript::Signature.class_id(ref)
445
- BiteScript::ASM::Type.getType(desc)
446
- end
447
- end
448
- end
449
-
450
374
  class NodeProxy < DelegateClass(Node)
451
375
  include Java::DubyLangCompiler::Node
376
+ include Java::DubyLangCompiler.Call
452
377
  def __inline__(node)
453
378
  node.parent = parent
454
379
  __setobj__(node)
@@ -646,7 +571,12 @@ module Mirah
646
571
  end
647
572
 
648
573
  def self.unreachable_type
649
- TypeReference::UnreachableType
574
+ factory = type_factory
575
+ if factory
576
+ factory.unreachable_type
577
+ else
578
+ TypeReference::UnreachableType
579
+ end
650
580
  end
651
581
 
652
582
  def self.block_type
@@ -50,11 +50,12 @@ module Mirah::AST
50
50
  def validate_parameters
51
51
  parameters.each_with_index do |child, i|
52
52
  if UnquotedValue === child
53
- child = child.node
54
- child.parent = self
55
- parameters[i] = child
53
+ children = child.nodes
54
+ children.each {|c| c.parent = self}
55
+ parameters[i] = children
56
56
  end
57
57
  end
58
+ parameters.flatten!
58
59
  end
59
60
 
60
61
  def infer(typer, expression)
@@ -169,6 +170,21 @@ module Mirah::AST
169
170
  parameter_types << Mirah::AST.block_type if block
170
171
 
171
172
  unless should_defer
173
+ class_name, array = self.type_name(true)
174
+ if class_name && parameters.size == 1 && typer.known_type(scope, class_name)
175
+ # Support casts to fully-qualified names and inner classes.
176
+ begin
177
+ type = inferred_type = typer.type_reference(scope, class_name, array)
178
+ @inferred_type = type unless (type && type.error?)
179
+ if @inferred_type
180
+ # cast operation
181
+ resolved!
182
+ self.cast = true
183
+ return @inferred_type
184
+ end
185
+ rescue
186
+ end
187
+ end
172
188
  @inferred_type = typer.method_type(receiver_type, name,
173
189
  parameter_types)
174
190
  if @inferred_type.kind_of? InlineCode
@@ -203,6 +219,14 @@ module Mirah::AST
203
219
  end
204
220
 
205
221
  def type_reference(typer)
222
+ class_name, array = type_name
223
+ typer.type_reference(scope, class_name, array)
224
+ end
225
+
226
+ def type_name(force=false)
227
+ if !force && parameters && !parameters.empty?
228
+ return nil
229
+ end
206
230
  if name == "[]"
207
231
  # array type, top should be a constant; find the rest
208
232
  array = true
@@ -216,19 +240,27 @@ module Mirah::AST
216
240
  while !receiver.eql?(old_receiver)
217
241
  old_receiver = receiver
218
242
  case receiver
219
- when Constant, FunctionalCall, Local, Annotation
243
+ when Constant, Local, Annotation
220
244
  elements.unshift(receiver.name)
245
+ when FunctionalCall
246
+ if receiver.parameters.nil? || receiver.parameters.empty?
247
+ elements.unshift(receiver.name)
248
+ else
249
+ return nil, nil
250
+ end
221
251
  when Call
222
- elements.unshift(receiver.name)
223
- receiver = receiver.target
252
+ if receiver.parameters.nil? || receiver.parameters.empty?
253
+ elements.unshift(receiver.name)
254
+ receiver = receiver.target
255
+ else
256
+ return nil, nil
257
+ end
224
258
  when String
225
259
  elements.unshift(receiver.literal)
226
260
  end
227
261
  end
228
262
 
229
- # join and load
230
- class_name = elements.join(".")
231
- typer.type_reference(scope, class_name, array)
263
+ return elements.join("."), array
232
264
  end
233
265
  end
234
266
 
@@ -54,13 +54,13 @@ module Mirah::AST
54
54
  node
55
55
  end
56
56
 
57
- def define_method(position, name, type, *args)
58
- append_node(_define_method(MethodDefinition, position, name, type, args))
57
+ def define_method(position, name, type, *args, &block)
58
+ append_node(_define_method(MethodDefinition, position, name, type, args, &block))
59
59
  end
60
60
 
61
- def define_static_method(position, name, type, *args)
61
+ def define_static_method(position, name, type, *args, &block)
62
62
  append_node(
63
- _define_method(StaticMethodDefinition, position, name, type, args))
63
+ _define_method(StaticMethodDefinition, position, name, type, args, &block))
64
64
  end
65
65
 
66
66
  def define_constructor(position, *args, &block)
@@ -122,6 +122,10 @@ module Mirah::AST
122
122
  end
123
123
  end
124
124
  end
125
+
126
+ def top_level?
127
+ true
128
+ end
125
129
  end
126
130
 
127
131
  defmacro('implements') do |transformer, fcall, parent|
@@ -159,6 +163,10 @@ module Mirah::AST
159
163
  def superclass_node
160
164
  nil
161
165
  end
166
+
167
+ def top_level?
168
+ true
169
+ end
162
170
  end
163
171
 
164
172
  class ClosureDefinition < ClassDefinition
@@ -307,8 +315,6 @@ module Mirah::AST
307
315
  the_scope.self_type = the_scope.self_type.include(typeref)
308
316
  end
309
317
  end
310
-
311
- def compile(compiler, expression); end
312
318
  end
313
319
 
314
320
  defmacro("include") do |transformer, fcall, parent|
@@ -320,4 +326,26 @@ module Mirah::AST
320
326
  end
321
327
  end
322
328
  end
329
+
330
+ class Constant < Node
331
+ include Named
332
+ include Scoped
333
+ attr_accessor :array
334
+
335
+ def initialize(parent, position, name)
336
+ self.name = name
337
+ super(parent, position, [])
338
+ end
339
+
340
+ def infer(typer, expression)
341
+ @inferred_type ||= begin
342
+ # TODO lookup constant, inline if we're supposed to.
343
+ typer.type_reference(scope, name, @array, true)
344
+ end
345
+ end
346
+
347
+ def type_reference(typer)
348
+ typer.type_reference(scope, @name, @array)
349
+ end
350
+ end
323
351
  end
@@ -235,7 +235,7 @@ module Mirah
235
235
  typer.defer(self)
236
236
  return
237
237
  end
238
- if throwable.assignable_from?(arg_type) && !arg_type.meta?
238
+ if throwable.compatible?(arg_type) && !arg_type.meta?
239
239
  resolved!
240
240
  return @inferred_type
241
241
  end
@@ -245,7 +245,7 @@ module Mirah
245
245
  if arg_types.any? {|c| c.nil?}
246
246
  typer.defer(self)
247
247
  else
248
- if arg_types[0] && throwable.assignable_from?(arg_types[0])
248
+ if arg_types[0] && throwable.compatible?(arg_types[0])
249
249
  klass = children.shift
250
250
  else
251
251
  klass = Constant.new(self, position, 'RuntimeException')
@@ -315,20 +315,32 @@ module Mirah
315
315
  class Rescue < Node
316
316
  child :body
317
317
  child :clauses
318
+ child :else_node
319
+
318
320
  def initialize(parent, position, &block)
319
321
  super(parent, position, &block)
320
- @body, @clauses = children
321
322
  end
322
323
 
323
324
  def infer(typer, expression)
324
325
  unless resolved?
325
- types = [typer.infer(body, true )] + clauses.map {|c| typer.infer(c, true)}
326
+ types = []
327
+ body_type = typer.infer(body, else_node.nil?) if body
328
+ else_type = typer.infer(else_node, true) if else_node
329
+ if else_node
330
+ types << else_type
331
+ elsif body
332
+ types << body_type
333
+ end
334
+ types += clauses.map {|c| typer.infer(c, true)}
326
335
  if types.any? {|t| t.nil?}
327
336
  typer.defer(self)
328
337
  else
329
338
  # TODO check types for compatibility (maybe only if an expression)
330
339
  resolved!
331
- @inferred_type = types[0]
340
+ types.each do |type|
341
+ @inferred_type ||= type unless type.unreachable?
342
+ end
343
+ @inferred_type ||= types[0]
332
344
  end
333
345
  end
334
346
  @inferred_type