mirah 0.1.0.pre-java → 0.1.1-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 +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 = []
|