mirah 0.1.0.pre-java → 0.1.1-java
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +736 -0
- data/README.md +71 -0
- data/Rakefile +227 -73
- data/examples/Fib.class +0 -0
- data/examples/macros/{string-each-char.mirah → string_each_char.mirah} +2 -3
- data/examples/simple_class.mirah +3 -3
- data/examples/{dynamic.mirah → simple_class.mirah~} +7 -12
- data/javalib/mirah-bootstrap.jar +0 -0
- data/javalib/mirah-builtins.jar +0 -0
- data/javalib/mirah-compiler.jar +0 -0
- data/javalib/mirah-parser.jar +0 -0
- data/javalib/mirah-util.jar +0 -0
- data/lib/mirah.rb +8 -1
- data/lib/mirah/ast.rb +1 -1
- data/lib/mirah/ast/scope.rb +16 -0
- data/lib/mirah/commands/base.rb +1 -3
- data/lib/mirah/compiler.rb +17 -3
- data/lib/mirah/errors.rb +10 -10
- data/lib/mirah/generator.rb +21 -9
- data/lib/mirah/jvm/compiler.rb +17 -0
- data/lib/mirah/jvm/compiler/base.rb +24 -5
- data/lib/mirah/jvm/compiler/jvm_bytecode.rb +83 -20
- data/lib/mirah/jvm/method_lookup.rb +43 -22
- data/lib/mirah/jvm/types.rb +1 -2
- data/lib/mirah/jvm/types/array_type.rb +1 -6
- data/lib/mirah/jvm/types/ast_ext.rb +31 -0
- data/lib/mirah/jvm/types/basic_types.rb +1 -2
- data/lib/mirah/jvm/types/boolean.rb +11 -10
- data/lib/mirah/jvm/types/extensions.rb +14 -5
- data/lib/mirah/jvm/types/factory.rb +128 -43
- data/lib/mirah/jvm/types/floats.rb +8 -10
- data/lib/mirah/jvm/types/integers.rb +16 -9
- data/lib/mirah/jvm/types/intrinsics.rb +17 -69
- data/lib/mirah/jvm/types/meta_type.rb +5 -0
- data/lib/mirah/jvm/types/methods.rb +317 -151
- data/lib/mirah/jvm/types/methods.rb~ +973 -0
- data/lib/mirah/jvm/types/number.rb +29 -6
- data/lib/mirah/jvm/types/primitive_type.rb +35 -7
- data/lib/mirah/jvm/types/source_mirror.rb +11 -6
- data/lib/mirah/jvm/types/type.rb +52 -0
- data/lib/mirah/jvm/types/type_definition.rb +8 -2
- data/lib/mirah/transform/ast_ext.rb +9 -31
- data/lib/mirah/transform/transformer.rb +1 -1
- data/lib/mirah/typer.rb +2 -1
- data/lib/mirah/util/argument_processor.rb +10 -14
- data/lib/mirah/util/argument_processor.rb~ +146 -0
- data/lib/mirah/util/compilation_state.rb +15 -9
- data/lib/mirah/util/process_errors.rb +8 -2
- data/lib/mirah/version.rb +2 -2
- data/lib/mirah_task.rb +0 -7
- data/test/core/typer_test.rb +21 -13
- data/test/core/util/argument_processor_test.rb +19 -19
- data/test/core/util/class_loader_test.rb +19 -4
- data/test/core/util/compilation_state_test.rb +38 -0
- 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/blocks_test.rb +50 -29
- data/test/jvm/bytecode_test_helper.rb +71 -57
- data/test/jvm/cast_test.rb +162 -0
- data/test/jvm/constructors_test.rb +48 -0
- data/test/jvm/enumerable_test.rb +136 -7
- data/test/jvm/example_test.rb +39 -0
- data/test/jvm/factory_test.rb +6 -0
- data/test/jvm/generics_test.rb +0 -5
- data/test/jvm/import_test.rb +81 -0
- data/test/jvm/interface_test.rb +113 -0
- data/test/jvm/java_typer_test.rb +57 -11
- data/test/jvm/jvm_commands_test.rb +24 -0
- data/test/jvm/jvm_compiler_test.rb +186 -370
- data/test/jvm/macros_test.rb +67 -6
- data/test/jvm/main_method_test.rb +1 -1
- data/test/jvm/mirror_compilation_test_helper.rb +24 -0
- data/test/jvm/new_backend_test_helper.rb +25 -0
- data/test/jvm/rescue_test.rb +153 -18
- data/test/jvm/string_test.rb +41 -0
- data/test/jvm/varargs_test.rb +65 -0
- data/test/mirrors/base_type_test.rb +96 -0
- data/test/mirrors/bytecode_mirror_test.rb +86 -0
- data/test/mirrors/generics_test.rb +776 -0
- data/test/mirrors/member_test.rb +69 -0
- data/test/mirrors/method_lookup_test.rb +574 -0
- data/test/mirrors/mirrors_test.rb +562 -0
- data/test/mirrors/simple_async_mirror_loader_test.rb +110 -0
- data/test/mirrors/simple_mirror_loader_test.rb +104 -0
- data/test/test_helper.rb +2 -1
- metadata +244 -217
- data/README.txt +0 -59
- data/javalib/dynalink-0.2.jar +0 -0
- data/lib/mirah/jvm/typer.rb +0 -177
- data/lib/mirah/jvm/types/dynamic_type.rb +0 -45
- data/lib/mirah/jvm/types/unreachable_type.rb +0 -27
data/examples/Fib.class
ADDED
Binary file
|
@@ -14,10 +14,9 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
16
|
|
17
|
-
macro def eachChar(value,
|
18
|
-
|
17
|
+
macro def eachChar(value, block:Block)
|
19
18
|
quote {
|
20
|
-
`value`.toCharArray.each do
|
19
|
+
`value`.toCharArray.each do |`block.arguments` |
|
21
20
|
`block.body`
|
22
21
|
end
|
23
22
|
}
|
data/examples/simple_class.mirah
CHANGED
@@ -13,15 +13,15 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
class
|
16
|
+
class SimpleClass
|
17
17
|
def initialize
|
18
18
|
puts 'constructor'
|
19
19
|
@hello = 'Hello, '
|
20
20
|
end
|
21
21
|
|
22
|
-
def hello(a:
|
22
|
+
def hello(a:String)
|
23
23
|
puts @hello; puts a
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
|
27
|
+
SimpleClass.new.hello('Mirah')
|
@@ -13,20 +13,15 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
class SizeThing
|
22
|
-
def initialize(size:int)
|
23
|
-
@size = size
|
16
|
+
class Foo
|
17
|
+
def initialize
|
18
|
+
puts 'constructor'
|
19
|
+
@hello = 'Hello, '
|
24
20
|
end
|
25
21
|
|
26
|
-
def
|
27
|
-
@
|
22
|
+
def hello(a:string)
|
23
|
+
puts @hello; puts a
|
28
24
|
end
|
29
25
|
end
|
30
26
|
|
31
|
-
|
32
|
-
foo(SizeThing.new(12))
|
27
|
+
Foo.new.hello('Mirah')
|
data/javalib/mirah-bootstrap.jar
CHANGED
Binary file
|
data/javalib/mirah-builtins.jar
CHANGED
Binary file
|
Binary file
|
data/javalib/mirah-parser.jar
CHANGED
Binary file
|
Binary file
|
data/lib/mirah.rb
CHANGED
@@ -17,6 +17,13 @@ require 'fileutils'
|
|
17
17
|
require 'rbconfig'
|
18
18
|
require 'bitescript'
|
19
19
|
|
20
|
+
$CLASSPATH << File.dirname(__FILE__) + '/../javalib/mirah-builtins.jar'
|
21
|
+
$CLASSPATH << File.dirname(__FILE__) + '/../javalib/mirah-parser.jar'
|
22
|
+
$CLASSPATH << File.dirname(__FILE__) + '/../javalib/mirah-bootstrap.jar'
|
23
|
+
$CLASSPATH << File.dirname(__FILE__) + '/../javalib/mirah-util.jar'
|
24
|
+
$CLASSPATH << File.dirname(__FILE__) + '/../javalib/mirah-compiler.jar'
|
25
|
+
$CLASSPATH << File.dirname(__FILE__) + '/../javalib/mirah-mirrors.jar'
|
26
|
+
|
20
27
|
require 'mirah/version'
|
21
28
|
require 'mirah/transform'
|
22
29
|
require 'mirah/ast'
|
@@ -78,7 +85,7 @@ module Mirah
|
|
78
85
|
end_col -= adjustment
|
79
86
|
|
80
87
|
result = ""
|
81
|
-
position.source.contents.
|
88
|
+
position.source.contents.each_line.with_index do |line, lineno|
|
82
89
|
break if lineno > end_line
|
83
90
|
next if lineno < start_line
|
84
91
|
|
data/lib/mirah/ast.rb
CHANGED
@@ -34,10 +34,10 @@ module Mirah
|
|
34
34
|
java_import 'mirah.lang.ast.NodeList'
|
35
35
|
java_import 'mirah.lang.ast.Noop'
|
36
36
|
java_import 'mirah.lang.ast.OptionalArgument'
|
37
|
+
java_import 'mirah.lang.ast.Position'
|
37
38
|
java_import 'mirah.lang.ast.SimpleString'
|
38
39
|
java_import 'mirah.lang.ast.TypeName'
|
39
40
|
java_import 'mirah.lang.ast.TypeRef'
|
40
41
|
|
41
|
-
|
42
42
|
end
|
43
43
|
end
|
data/lib/mirah/ast/scope.rb
CHANGED
@@ -19,6 +19,7 @@ module Mirah
|
|
19
19
|
java_import 'java.util.LinkedHashMap'
|
20
20
|
java_import 'org.mirah.typer.Scope'
|
21
21
|
java_import 'org.mirah.typer.AssignableTypeFuture'
|
22
|
+
java_import 'org.mirah.typer.BaseTypeFuture'
|
22
23
|
java_import 'org.mirah.typer.LocalFuture'
|
23
24
|
java_import 'org.mirah.typer.ErrorType'
|
24
25
|
include Scope
|
@@ -85,6 +86,10 @@ module Mirah
|
|
85
86
|
def locals
|
86
87
|
@vars.keys
|
87
88
|
end
|
89
|
+
|
90
|
+
def capturedLocals
|
91
|
+
locals.select {|name| self.captured?(name)}
|
92
|
+
end
|
88
93
|
|
89
94
|
def temp(name="tmp")
|
90
95
|
"$#{name}$#{@temps[name] += 1}"
|
@@ -117,6 +122,10 @@ module Mirah
|
|
117
122
|
end
|
118
123
|
end
|
119
124
|
|
125
|
+
def isCaptured(name)
|
126
|
+
self.captured?(name)
|
127
|
+
end
|
128
|
+
|
120
129
|
def children
|
121
130
|
@children.keys
|
122
131
|
end
|
@@ -214,6 +223,13 @@ module Mirah
|
|
214
223
|
@cached_packages ||= fetch_packages([])
|
215
224
|
end
|
216
225
|
|
226
|
+
def staticImport(type)
|
227
|
+
future = BaseTypeFuture.new(self_type.position)
|
228
|
+
extended = self_type.resolve.include(type.resolve)
|
229
|
+
future.resolved(extended)
|
230
|
+
self.self_type = future
|
231
|
+
end
|
232
|
+
|
217
233
|
def import(full_name, short_name)
|
218
234
|
return if full_name == short_name
|
219
235
|
if short_name == '*'
|
data/lib/mirah/commands/base.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
|
1
|
+
# Copyright (c) 2010-2013 The Mirah project authors. All Rights Reserved.
|
2
2
|
# All contributing project authors may be found in the NOTICE file.
|
3
3
|
#
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -13,7 +13,6 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
#require 'mirah/jvm/types'
|
17
16
|
require 'mirah/util/compilation_state'
|
18
17
|
require 'mirah/util/argument_processor'
|
19
18
|
require 'mirah/errors'
|
@@ -23,7 +22,6 @@ module Mirah
|
|
23
22
|
class Base
|
24
23
|
include Mirah::Logging::Logged
|
25
24
|
def initialize(args)
|
26
|
-
#Mirah::AST.type_factory = Mirah::JVM::Types::TypeFactory.new
|
27
25
|
@state = Mirah::Util::CompilationState.new
|
28
26
|
@state.command = command_name
|
29
27
|
@args = args
|
data/lib/mirah/compiler.rb
CHANGED
@@ -16,7 +16,8 @@
|
|
16
16
|
module Mirah
|
17
17
|
module Compiler
|
18
18
|
class ASTCompiler
|
19
|
-
def initialize(compiler_class, logging)
|
19
|
+
def initialize(config, compiler_class, logging)
|
20
|
+
@config = config
|
20
21
|
@compiler_class = compiler_class
|
21
22
|
@logging = logging
|
22
23
|
end
|
@@ -29,16 +30,29 @@ module Mirah
|
|
29
30
|
nodes.each do |ast|
|
30
31
|
puts " #{ast.position.source.name}" if logging
|
31
32
|
compile_ast(ast, scoper, typer) do |filename, builder|
|
32
|
-
|
33
|
+
if builder.respond_to?(:class_name)
|
34
|
+
class_name = builder.class_name
|
35
|
+
bytes = builder.generate
|
36
|
+
else
|
37
|
+
class_name = filename
|
38
|
+
bytes = String.from_java_bytes(builder)
|
39
|
+
filename = class_name.tr('.', '/') + ".class"
|
40
|
+
end
|
41
|
+
results << CompilerResult.new(filename, class_name, bytes)
|
33
42
|
end
|
34
43
|
end
|
35
44
|
results
|
36
45
|
end
|
37
46
|
|
38
47
|
def compile_ast(ast, scoper, typer, &block)
|
39
|
-
@compiler = compiler_class.new(scoper, typer)
|
48
|
+
@compiler = compiler_class.new(@config, scoper, typer)
|
40
49
|
compiler.visit(ast, nil)
|
41
50
|
compiler.generate(&block)
|
51
|
+
rescue java.lang.UnsupportedOperationException => ex
|
52
|
+
raise MirahError.new(ex.message)
|
53
|
+
rescue java.lang.Throwable => ex
|
54
|
+
ex.cause.printStackTrace if ex.cause
|
55
|
+
raise ex
|
42
56
|
end
|
43
57
|
end
|
44
58
|
|
data/lib/mirah/errors.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
|
1
|
+
# Copyright (c) 2010-2013 The Mirah project authors. All Rights Reserved.
|
2
2
|
# All contributing project authors may be found in the NOTICE file.
|
3
3
|
#
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -34,23 +34,24 @@ module Mirah
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def node=(node)
|
37
|
-
@position = node
|
38
|
-
@node
|
37
|
+
@position = node.position if node
|
38
|
+
@node = node
|
39
39
|
end
|
40
40
|
|
41
41
|
def self.wrap(ex, node)
|
42
|
-
|
42
|
+
case ex
|
43
|
+
when NodeError
|
43
44
|
ex.node ||= node
|
44
|
-
|
45
|
-
|
45
|
+
ex
|
46
|
+
when MirahError
|
46
47
|
ex.position ||= node.position
|
47
|
-
|
48
|
+
ex
|
48
49
|
else
|
49
50
|
new_ex = new(ex.message, node)
|
50
|
-
new_ex.cause
|
51
|
+
new_ex.cause = ex
|
51
52
|
new_ex.position ||= ex.position if ex.respond_to?(:position)
|
52
53
|
new_ex.set_backtrace(ex.backtrace)
|
53
|
-
|
54
|
+
new_ex
|
54
55
|
end
|
55
56
|
end
|
56
57
|
|
@@ -66,7 +67,6 @@ module Mirah
|
|
66
67
|
class SyntaxError < NodeError
|
67
68
|
end
|
68
69
|
|
69
|
-
|
70
70
|
class InferenceError < NodeError
|
71
71
|
end
|
72
72
|
|
data/lib/mirah/generator.rb
CHANGED
@@ -25,18 +25,30 @@ module Mirah
|
|
25
25
|
|
26
26
|
def initialize(state, compiler_class, logging, verbose)
|
27
27
|
@state = state
|
28
|
-
@scoper = SimpleScoper.new {|scoper, node| Mirah::AST::StaticScope.new(node, scoper)}
|
29
28
|
|
30
29
|
# TODO untie this from the jvm backend (nh)
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
if state.type_system
|
31
|
+
# Using new type system
|
32
|
+
@scoper = SimpleScoper.new do |scoper, node|
|
33
|
+
scope = Java::OrgMirahJvmMirrors::JVMScope.new(scoper)
|
34
|
+
scope.context_set(node)
|
35
|
+
scope
|
36
|
+
end
|
37
|
+
type_system = state.type_system
|
38
|
+
else
|
39
|
+
@scoper = SimpleScoper.new {|scoper, node| Mirah::AST::StaticScope.new(node, scoper)}
|
40
|
+
type_system = Mirah::JVM::Types::TypeFactory.new
|
41
|
+
type_system.classpath = state.classpath if state.classpath
|
42
|
+
type_system.bootclasspath = state.bootclasspath
|
43
|
+
end
|
34
44
|
|
35
|
-
@typer = Mirah::Typer::Typer.new(type_system, @scoper, self)
|
45
|
+
@typer = Mirah::Typer::Typer.new(type_system, @scoper, self, nil)
|
36
46
|
@parser = Mirah::Parser.new(state, @typer, logging)
|
37
|
-
@compiler = Mirah::Compiler::ASTCompiler.new(compiler_class, logging)
|
38
|
-
@
|
39
|
-
type_system.maybe_initialize_builtins
|
47
|
+
@compiler = Mirah::Compiler::ASTCompiler.new(state, compiler_class, logging)
|
48
|
+
@extension_compiler = Mirah::Compiler::ASTCompiler.new(state, compiler_class, logging)
|
49
|
+
if type_system.respond_to?(:maybe_initialize_builtins)
|
50
|
+
type_system.maybe_initialize_builtins(@typer.macro_compiler)
|
51
|
+
end
|
40
52
|
@logging = logging
|
41
53
|
@verbose = verbose
|
42
54
|
end
|
@@ -93,7 +105,7 @@ module Mirah
|
|
93
105
|
def compileAndLoadExtension(ast)
|
94
106
|
log_types([ast])
|
95
107
|
process_inference_errors(@typer, [ast])
|
96
|
-
results = @
|
108
|
+
results = @extension_compiler.compile_asts([ast], @scoper, @typer)
|
97
109
|
class_map = {}
|
98
110
|
first_class_name = nil
|
99
111
|
results.each do |result|
|
data/lib/mirah/jvm/compiler.rb
CHANGED
@@ -19,6 +19,7 @@ require 'mirah/jvm/method_lookup'
|
|
19
19
|
require 'mirah/jvm/types'
|
20
20
|
require 'bitescript'
|
21
21
|
require 'mirah/jvm/compiler/jvm_bytecode'
|
22
|
+
require 'mirah/transform/ast_ext'
|
22
23
|
|
23
24
|
module Mirah
|
24
25
|
module AST
|
@@ -31,3 +32,19 @@ module Mirah
|
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
35
|
+
|
36
|
+
module Mirah
|
37
|
+
module JVM
|
38
|
+
module Compiler
|
39
|
+
begin
|
40
|
+
class Backend < Java::OrgMirahJvmCompiler::Backend
|
41
|
+
def initialize(config, scoper, typer)
|
42
|
+
super(typer)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
rescue NameError
|
46
|
+
puts "Unable to load new Backend"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -32,16 +32,25 @@ module Mirah
|
|
32
32
|
"org.mirah.ruby.JVM.Compiler.Base"
|
33
33
|
end
|
34
34
|
|
35
|
-
def initialize(scoper, typer)
|
35
|
+
def initialize(config, scoper, typer)
|
36
36
|
super()
|
37
|
+
@config = config
|
37
38
|
@jump_scope = []
|
38
39
|
@bindings = Hash.new {|h, type| h[type] = type.define(@file)}
|
39
40
|
@captured_locals = Hash.new {|h, binding| h[binding] = {}}
|
40
41
|
@self_scope = nil
|
41
|
-
@scoper = scoper
|
42
|
+
@scoper = typer.scoper
|
42
43
|
@typer = typer
|
43
44
|
end
|
44
45
|
|
46
|
+
def target_jvm_version
|
47
|
+
@config.target_jvm_version
|
48
|
+
end
|
49
|
+
|
50
|
+
def supports_invokedynamic?
|
51
|
+
@config.supports_invokedynamic?
|
52
|
+
end
|
53
|
+
|
45
54
|
def defaultNode(node, expression)
|
46
55
|
raise ArgumentError, "Can't compile node #{node}"
|
47
56
|
end
|
@@ -192,9 +201,12 @@ module Mirah
|
|
192
201
|
|
193
202
|
# arg_types must be an Array
|
194
203
|
def create_method_builder(name, node, static, exceptions, return_type, arg_types)
|
204
|
+
return_type = nil if return_type.name == ':unreachable'
|
195
205
|
visibility = :public # TODO
|
196
|
-
|
197
|
-
|
206
|
+
flags = BiteScript::ASM::Opcodes::ACC_PUBLIC
|
207
|
+
flags |= BiteScript::ASM::Opcodes::ACC_STATIC if static
|
208
|
+
flags |= BiteScript::ASM::Opcodes::ACC_ABSTRACT if node.annotated_abstract?
|
209
|
+
@class.method(flags, name.to_s, [return_type, *arg_types], exceptions)
|
198
210
|
end
|
199
211
|
|
200
212
|
def base_define_method(node)
|
@@ -205,7 +217,7 @@ module Mirah
|
|
205
217
|
name = "<clinit>"
|
206
218
|
end
|
207
219
|
arg_types = args.map { |arg| inferred_type(arg) }
|
208
|
-
return_type = inferred_type(node)
|
220
|
+
return_type = inferred_type(node).return_type
|
209
221
|
exceptions = [] # TODO
|
210
222
|
|
211
223
|
with :static => is_static, :current_scope => introduced_scope(node) do
|
@@ -341,6 +353,13 @@ module Mirah
|
|
341
353
|
inferred_type(node).literal(method, node.value)
|
342
354
|
end
|
343
355
|
end
|
356
|
+
|
357
|
+
def visitCharLiteral(node, expression)
|
358
|
+
if expression
|
359
|
+
inferred_type(node).literal(method, node.value)
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
344
363
|
alias visitFloat visitFixnum
|
345
364
|
|
346
365
|
def visitSelf(node, expression)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'mirah/jvm/types/ast_ext'
|
2
|
+
|
1
3
|
module Mirah
|
2
4
|
module JVM
|
3
5
|
module Compiler
|
@@ -40,7 +42,7 @@ module Mirah
|
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
43
|
-
def initialize(scoper, typer)
|
45
|
+
def initialize(config, scoper, typer)
|
44
46
|
super
|
45
47
|
@jump_scope = []
|
46
48
|
end
|
@@ -52,8 +54,8 @@ module Mirah
|
|
52
54
|
def file_builder(filename)
|
53
55
|
builder = BiteScript::FileBuilder.new(filename)
|
54
56
|
builder.to_widen do |_a, _b|
|
55
|
-
a = @typer.type_system.get_type(_a)
|
56
|
-
b = @typer.type_system.get_type(_b)
|
57
|
+
a = @typer.type_system.get_type(_a.tr('/', '.'))
|
58
|
+
b = @typer.type_system.get_type(_b.tr('/', '.'))
|
57
59
|
a_ancestors = []
|
58
60
|
while a
|
59
61
|
a_ancestors << a.name
|
@@ -65,7 +67,13 @@ module Mirah
|
|
65
67
|
b = b.superclass
|
66
68
|
end
|
67
69
|
intersection = (a_ancestors & b_ancestors)
|
68
|
-
intersection
|
70
|
+
if intersection.size == 0
|
71
|
+
puts "#{_a} => #{a}, #{_b} => #{b}"
|
72
|
+
puts "#{a_ancestors.inspect} & #{b_ancestors.inspect} = []"
|
73
|
+
'java/lang/Object'
|
74
|
+
else
|
75
|
+
intersection[0].gsub('.', '/')
|
76
|
+
end
|
69
77
|
end
|
70
78
|
@typer.type_system.define_types(builder)
|
71
79
|
builder
|
@@ -139,12 +147,12 @@ module Mirah
|
|
139
147
|
def visitMethodDefinition(node, expression)
|
140
148
|
push_jump_scope(node) do
|
141
149
|
base_define_method(node) do |method, arg_types|
|
142
|
-
return if @class.interface?
|
150
|
+
return if @class.interface? || node.annotated_abstract?
|
143
151
|
is_static = self.static || node.kind_of?(StaticMethodDefinition)
|
144
152
|
|
145
153
|
log "Starting new #{is_static ? 'static ' : ''}method #{node.name.identifier}(#{arg_types})"
|
146
154
|
args = visit(node.arguments, true)
|
147
|
-
method_body(method, args, node, inferred_type(node))
|
155
|
+
method_body(method, args, node, inferred_type(node).returnType)
|
148
156
|
log "Method #{node.name.identifier}(#{arg_types}) complete!"
|
149
157
|
end
|
150
158
|
end
|
@@ -233,17 +241,26 @@ module Mirah
|
|
233
241
|
|
234
242
|
prepare_binding(node) do
|
235
243
|
expression = return_type.name != 'void'
|
236
|
-
|
244
|
+
if body
|
245
|
+
if expression
|
246
|
+
body_type = inferred_type(body)
|
247
|
+
unless return_type.assignableFrom(body_type)
|
248
|
+
error("Invalid return type #{body_type.name}, expected #{return_type.name}", body)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
visit(body, expression)
|
252
|
+
convert_value inferred_type(body), return_type if expression
|
253
|
+
end
|
237
254
|
end
|
238
255
|
|
239
|
-
return_type.return(@method)
|
256
|
+
return_type.return(@method) unless return_type.name == ':unreachable'
|
240
257
|
|
241
258
|
@method.stop
|
242
259
|
end
|
243
260
|
end
|
244
261
|
|
245
262
|
def visitClosureDefinition(class_def, expression)
|
246
|
-
compiler = ClosureCompiler.new(@file, @type, self, @scoper, @typer)
|
263
|
+
compiler = ClosureCompiler.new(@config, @file, @type, self, @scoper, @typer)
|
247
264
|
compiler.visitClassDefinition(class_def, expression)
|
248
265
|
end
|
249
266
|
|
@@ -440,6 +457,18 @@ module Mirah
|
|
440
457
|
end
|
441
458
|
end
|
442
459
|
|
460
|
+
def visitVarargsArray type, parameters
|
461
|
+
@method.push_int parameters.size
|
462
|
+
@method.anewarray type.component_type
|
463
|
+
parameters.each.with_index do |value, i|
|
464
|
+
@method.dup
|
465
|
+
@method.push_int i
|
466
|
+
visit(value, true)
|
467
|
+
convert_value inferred_type(value), type.component_type
|
468
|
+
@method.aastore
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
443
472
|
def visitFunctionalCall(fcall, expression)
|
444
473
|
scope = get_scope(fcall)
|
445
474
|
type = get_scope(fcall).self_type.resolve
|
@@ -562,6 +591,7 @@ module Mirah
|
|
562
591
|
|
563
592
|
def annotate(builder, annotations)
|
564
593
|
annotations.each do |annotation|
|
594
|
+
next if annotation.type.typeref.name.start_with?('org.mirah.jvm.')
|
565
595
|
type = inferred_type(annotation)
|
566
596
|
mirror = type.jvm_type
|
567
597
|
if mirror.respond_to?(:getDeclaredAnnotation)
|
@@ -730,19 +760,29 @@ module Mirah
|
|
730
760
|
declare_local(scope, name, type)
|
731
761
|
|
732
762
|
visit(local.value, true)
|
763
|
+
convert_value inferred_type(local.value), type
|
733
764
|
|
734
765
|
# if expression, dup the value we're assigning
|
735
|
-
|
766
|
+
if expression
|
767
|
+
dup_value type
|
768
|
+
end
|
769
|
+
|
736
770
|
set_position(local.position)
|
737
771
|
type.store(@method, @method.local(scoped_local_name(name, scope), type))
|
738
772
|
end
|
739
773
|
|
740
774
|
def captured_local_assign(node, expression)
|
741
|
-
scope, name
|
775
|
+
scope, name = containing_scope(node), node.name.identifier
|
776
|
+
type = get_scope(node).local_type(name).resolve
|
742
777
|
captured_local_declare(scope, name, type)
|
743
778
|
binding_reference
|
744
779
|
visit(node.value, true)
|
745
|
-
|
780
|
+
convert_value(inferred_type(node.value), type)
|
781
|
+
|
782
|
+
# if expression, dup the value we're assigning
|
783
|
+
if expression
|
784
|
+
dup_x2_value type
|
785
|
+
end
|
746
786
|
set_position(node.position)
|
747
787
|
@method.putfield(scope.binding_type, name, type)
|
748
788
|
end
|
@@ -906,9 +946,6 @@ module Mirah
|
|
906
946
|
@method.invokeinterface java::util::List, "add", [@method.boolean, @method.object]
|
907
947
|
@method.pop
|
908
948
|
end
|
909
|
-
|
910
|
-
# make it unmodifiable
|
911
|
-
@method.invokestatic java::util::Collections, "unmodifiableList", [java::util::List, java::util::List]
|
912
949
|
else
|
913
950
|
# elements, as non-expressions
|
914
951
|
# TODO: ensure they're all reference types!
|
@@ -997,7 +1034,7 @@ module Mirah
|
|
997
1034
|
|
998
1035
|
def set_position(position)
|
999
1036
|
# TODO support positions from multiple files
|
1000
|
-
@method.line(position.start_line
|
1037
|
+
@method.line(position.start_line) if @method && position
|
1001
1038
|
end
|
1002
1039
|
|
1003
1040
|
def print(print_node)
|
@@ -1034,10 +1071,14 @@ module Mirah
|
|
1034
1071
|
start = @method.label.set!
|
1035
1072
|
body_end = @method.label
|
1036
1073
|
done = @method.label
|
1037
|
-
|
1074
|
+
no_else_clauses = rescue_node.else_clause.size == 0
|
1075
|
+
|
1076
|
+
visit(rescue_node.body, expression && no_else_clauses)
|
1038
1077
|
body_end.set!
|
1039
|
-
|
1078
|
+
|
1079
|
+
visit(rescue_node.else_clause, expression) unless no_else_clauses
|
1040
1080
|
return if start.label.offset == body_end.label.offset
|
1081
|
+
|
1041
1082
|
@method.goto(done)
|
1042
1083
|
rescue_node.clauses.each do |clause|
|
1043
1084
|
target = @method.label.set!
|
@@ -1092,9 +1133,31 @@ module Mirah
|
|
1092
1133
|
end
|
1093
1134
|
end
|
1094
1135
|
|
1136
|
+
private
|
1137
|
+
|
1138
|
+
def convert_value in_type, out_type
|
1139
|
+
in_type.compile_widen(@method, out_type) if in_type.name != ':unreachable' && in_type.primitive?
|
1140
|
+
end
|
1141
|
+
|
1142
|
+
def dup_value type
|
1143
|
+
if type.primitive? && type.wide?
|
1144
|
+
@method.dup2
|
1145
|
+
else
|
1146
|
+
@method.dup
|
1147
|
+
end
|
1148
|
+
end
|
1149
|
+
|
1150
|
+
def dup_x2_value type
|
1151
|
+
if type.primitive? && type.wide?
|
1152
|
+
@method.dup2_x2
|
1153
|
+
else
|
1154
|
+
@method.dup_x2
|
1155
|
+
end
|
1156
|
+
end
|
1157
|
+
|
1095
1158
|
class ClosureCompiler < JVMBytecode
|
1096
|
-
def initialize(file, type, parent, scoper, typer)
|
1097
|
-
super(scoper, typer)
|
1159
|
+
def initialize(config, file, type, parent, scoper, typer)
|
1160
|
+
super(config, scoper, typer)
|
1098
1161
|
@file = file
|
1099
1162
|
@type = type
|
1100
1163
|
@jump_scope = []
|