mirah 0.0.7-java → 0.0.8-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 (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,37 @@
1
+ # This is a custom classloader impl to allow loading classes with
2
+ # interdependencies by having findClass retrieve classes as needed from the
3
+ # collection of all classes generated by the target script.
4
+ module Mirah
5
+ module Util
6
+ class ClassLoader < java::security::SecureClassLoader
7
+ def initialize(parent, class_map)
8
+ super(parent)
9
+ @class_map = class_map
10
+ end
11
+
12
+ def findClass(name)
13
+ if @class_map[name]
14
+ bytes = @class_map[name].to_java_bytes
15
+ defineClass(name, bytes, 0, bytes.length)
16
+ else
17
+ raise java.lang.ClassNotFoundException.new(name)
18
+ end
19
+ end
20
+
21
+ def loadClass(name, resolve)
22
+ cls = findLoadedClass(name)
23
+ if cls == nil
24
+ if @class_map[name]
25
+ cls = findClass(name)
26
+ else
27
+ cls = super(name, false)
28
+ end
29
+ end
30
+
31
+ resolveClass(cls) if resolve
32
+
33
+ cls
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,51 @@
1
+ # Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
2
+ # All contributing project authors may be found in the NOTICE file.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'bitescript'
17
+
18
+ module Mirah
19
+ module Util
20
+ class CompilationState
21
+ def initialize
22
+ @save_extensions = true
23
+ end
24
+
25
+ attr_accessor :verbose, :destination
26
+ attr_accessor :version_printed
27
+ attr_accessor :help_printed
28
+ attr_accessor :save_extensions
29
+ attr_accessor :running
30
+ alias running? running
31
+ attr_accessor :compiler_class
32
+ attr_accessor :args
33
+ attr_accessor :command
34
+
35
+ def set_jvm_version(ver_str)
36
+ case ver_str
37
+ when '1.4'
38
+ BiteScript.bytecode_version = BiteScript::JAVA1_4
39
+ when '1.5'
40
+ BiteScript.bytecode_version = BiteScript::JAVA1_5
41
+ when '1.6'
42
+ BiteScript.bytecode_version = BiteScript::JAVA1_6
43
+ when '1.7'
44
+ BiteScript.bytecode_version = BiteScript::JAVA1_7
45
+ else
46
+ $stderr.puts "invalid bytecode version specified: #{ver_str}"
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,33 @@
1
+ # Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
2
+ # All contributing project authors may be found in the NOTICE file.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ module Mirah
17
+ module Util
18
+ module ProcessErrors
19
+ def process_errors(errors)
20
+ errors.each do |ex|
21
+ puts ex
22
+ if ex.node
23
+ Mirah.print_error(ex.message, ex.position)
24
+ else
25
+ puts ex.message
26
+ end
27
+ puts ex.backtrace if @verbose
28
+ end
29
+ throw :exit unless errors.empty?
30
+ end
31
+ end
32
+ end
33
+ end
@@ -14,5 +14,5 @@
14
14
  # limitations under the License.
15
15
 
16
16
  module Mirah
17
- VERSION = "0.0.7"
17
+ VERSION = "0.0.8"
18
18
  end
@@ -14,6 +14,7 @@
14
14
  # limitations under the License.
15
15
 
16
16
  require 'mirah'
17
+
17
18
  module Mirah
18
19
  class PathArray < Array
19
20
  def <<(value)
@@ -98,12 +99,12 @@ def mirahc(*files)
98
99
  end
99
100
  source_dir = options.fetch(:dir, Mirah.source_path)
100
101
  dest = File.expand_path(options.fetch(:dest, Mirah.dest_path))
101
- files = files.map {|f| f.sub(/^#{source_dir}\//, '')}
102
+ files = files.map {|f| File.expand_path(f).sub(/^#{source_dir}\//, '')}
102
103
  flags = options.fetch(:options, Mirah.compiler_options)
103
104
  args = ['-d', dest, *flags] + files
104
105
  chdir(source_dir) do
105
106
  puts "mirahc #{args.join ' '}"
106
- Mirah.compile(*args)
107
+ Mirah.compile(*args) || exit(1)
107
108
  Mirah.reset
108
109
  end
109
110
  end
@@ -371,4 +371,10 @@ class TestAst < Test::Unit::TestCase
371
371
  assert(AST::Fixnum === new_ast)
372
372
  assert_equal(1, new_ast.literal)
373
373
  end
374
+
375
+ def test_incorrect_syntax_raises_syntax_error
376
+ assert_raises SyntaxError do
377
+ AST.parse("puts( 'aoue'")
378
+ end
379
+ end
374
380
  end
@@ -19,39 +19,38 @@ require 'mirah'
19
19
  class TestEnv < Test::Unit::TestCase
20
20
  include Mirah
21
21
 
22
- def test_path_seperator
23
- # Check that env var PATH_SEPERATOR is used
24
- RbConfig::CONFIG['PATH_SEPARATOR'] = '*'
25
- assert_equal('*', Mirah::Env.path_seperator)
26
-
27
- # Check that : (colon) is returned if no PATH_SEPERATOR env var set
28
- RbConfig::CONFIG['PATH_SEPARATOR'] = ''
29
- assert_equal(':', Mirah::Env.path_seperator)
22
+ def test_use_file_path_separator
23
+ assert_equal(File::PATH_SEPARATOR, Mirah::Env.path_separator)
30
24
  end
31
25
 
32
- def test_encode_paths
33
- RbConfig::CONFIG['PATH_SEPARATOR'] = ':'
34
-
35
- assert_equal('a:b:c', Mirah::Env.encode_paths(['a','b','c']))
26
+ def test_encode_paths_joins_paths_with_path_separator
27
+ abc = %w[a b c]
28
+ assert_equal(abc.join(Mirah::Env.path_separator), Mirah::Env.encode_paths(abc))
29
+ end
30
+
31
+ def test_encode_paths_with_single_element
36
32
  assert_equal('a', Mirah::Env.encode_paths(['a']))
37
- assert_equal('', Mirah::Env.encode_paths([]))
38
-
39
- RbConfig::CONFIG['PATH_SEPARATOR'] = ';'
40
-
41
- assert_equal('a;b;c', Mirah::Env.encode_paths(['a','b','c']))
42
33
  end
43
34
 
44
- def test_decode_paths
45
- RbConfig::CONFIG['PATH_SEPARATOR'] = ':'
35
+ def test_encode_paths_with_empty_list
36
+ assert_equal('', Mirah::Env.encode_paths([]))
37
+ end
46
38
 
39
+ def test_decode_paths_appends_to_second_arg
40
+ paths_to_append = %w[a b c d]
41
+ encoded_paths = paths_to_append.join Mirah::Env.path_separator
47
42
  path_array = ['1','2']
48
- assert_equal(['1','2','a','b','c','d'], Mirah::Env.decode_paths('a:b:c:d', path_array))
43
+
44
+ assert_equal(['1','2','a','b','c','d'], Mirah::Env.decode_paths(encoded_paths, path_array))
49
45
  assert_equal(['1','2','a','b','c','d'], path_array)
50
-
51
- assert_equal(['a','b','c','d'], Mirah::Env.decode_paths('a:b:c:d'))
46
+ end
47
+
48
+ def test_decode_paths_with_empty_list
49
+ assert_equal([], Mirah::Env.decode_paths(''))
50
+ end
51
+
52
+ def test_decode_paths_with_single_element
52
53
  assert_equal(['a'], Mirah::Env.decode_paths('a'))
53
-
54
- RbConfig::CONFIG['PATH_SEPARATOR'] = ';'
55
- assert_equal(['a','b','c','d'], Mirah::Env.decode_paths('a;b;c;d'))
56
54
  end
55
+
57
56
  end
@@ -1,7 +1,5 @@
1
1
  # TODO refactor this and test_jvm_compiler to use mirah.rb
2
2
 
3
- $:.unshift File.join(File.dirname(__FILE__),'..','lib')
4
-
5
3
  require 'test/unit'
6
4
  require 'mirah'
7
5
 
@@ -11,12 +9,12 @@ class TestMacros < Test::Unit::TestCase
11
9
  def parse(code)
12
10
  Mirah::AST.type_factory = Mirah::JVM::Types::TypeFactory.new
13
11
  name = "script" + System.nano_time.to_s
14
- state = Mirah::CompilationState.new
12
+ state = Mirah::Util::CompilationState.new
15
13
  state.save_extensions = false
16
14
  transformer = Mirah::Transform::Transformer.new(state)
17
15
  Java::MirahImpl::Builtin.initialize_builtins(transformer)
18
16
  ast = Mirah::AST.parse(code, name, true, transformer)
19
- typer = Mirah::Typer::JVM.new(transformer)
17
+ typer = Mirah::JVM::Typer.new(transformer)
20
18
  ast.infer(typer, true)
21
19
  typer.resolve(true)
22
20
  ast
@@ -14,9 +14,6 @@
14
14
  # limitations under the License.
15
15
 
16
16
  require 'test/unit'
17
-
18
- $:.unshift File.join(File.dirname(__FILE__),'..','lib')
19
-
20
17
  require 'mirah'
21
18
 
22
19
  class TestTyper < Test::Unit::TestCase
@@ -0,0 +1,181 @@
1
+ # Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
2
+ # All contributing project authors may be found in the NOTICE file.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ require 'bundler/setup'
16
+ require 'test/unit'
17
+ require 'mirah'
18
+ require 'jruby'
19
+ require 'stringio'
20
+ require 'fileutils'
21
+
22
+ unless Mirah::AST.macro "__gloop__"
23
+ Mirah::AST.defmacro "__gloop__" do |transformer, fcall, parent|
24
+ Mirah::AST::Loop.new(parent, parent.position, true, false) do |loop|
25
+ init, condition, check_first, pre, post = fcall.parameters
26
+ loop.check_first = check_first.literal
27
+
28
+ nil_t = Mirah::AST::Null
29
+ loop.init = init
30
+ loop.pre = pre
31
+ loop.post = post
32
+
33
+ body = fcall.block.body
34
+ body.parent = loop
35
+ [
36
+ Mirah::AST::Condition.new(loop, parent.position) do |c|
37
+ condition.parent = c
38
+ [condition]
39
+ end,
40
+ body
41
+ ]
42
+ end
43
+ end
44
+ end
45
+
46
+
47
+
48
+ module JVMCompiler
49
+ import java.lang.System
50
+ import java.io.PrintStream
51
+ include Mirah
52
+
53
+ def create_transformer
54
+ state = Mirah::Util::CompilationState.new
55
+ state.save_extensions = false
56
+
57
+ transformer = Mirah::Transform::Transformer.new(state)
58
+ Java::MirahImpl::Builtin.initialize_builtins(transformer)
59
+ transformer
60
+ end
61
+
62
+ def reset_type_factory
63
+ AST.type_factory = Mirah::JVM::Types::TypeFactory.new
64
+ end
65
+
66
+ def clear_tmp_files
67
+ File.unlink(*@tmp_classes)
68
+ @tmp_classes.clear
69
+ end
70
+
71
+ def create_compiler
72
+ JVM::Compiler::JVMBytecode.new
73
+ end
74
+
75
+ def parse name, code, transformer
76
+ AST.parse(code, name, true, transformer)
77
+ end
78
+
79
+ def infer_and_resolve_types ast, transformer
80
+ typer = JVM::Typer.new(transformer)
81
+
82
+ ast.infer(typer, true)
83
+
84
+ typer.resolve(true)
85
+ end
86
+
87
+ def parse_and_resolve_types name, code
88
+ transformer = create_transformer
89
+
90
+ ast = parse name, code, transformer
91
+
92
+ infer_and_resolve_types ast, transformer
93
+
94
+ ast
95
+ end
96
+
97
+
98
+ def generate_classes compiler
99
+ classes = {}
100
+
101
+ compiler.generate do |filename, builder|
102
+ bytes = builder.generate
103
+ FileUtils.mkdir_p(File.dirname(filename))
104
+ open("#{filename}", "wb") do |f|
105
+ f << bytes
106
+ end
107
+ classes[filename[0..-7]] = bytes
108
+ end
109
+
110
+ loader = Mirah::Util::ClassLoader.new(JRuby.runtime.jruby_class_loader, classes)
111
+ classes.keys.map do |name|
112
+ cls = loader.load_class(name.tr('/', '.'))
113
+ proxy = JavaUtilities.get_proxy_class(cls.name)
114
+ @tmp_classes << "#{name}.class"
115
+ proxy
116
+ end
117
+
118
+ end
119
+
120
+ def compile_ast ast
121
+ compiler = create_compiler
122
+ compiler.compile(ast)
123
+ compiler
124
+ end
125
+
126
+ def compile(code, name = "script" + System.nano_time.to_s)
127
+ clear_tmp_files
128
+ reset_type_factory
129
+
130
+ ast = parse_and_resolve_types name, code
131
+
132
+ compiler = compile_ast ast
133
+
134
+ generate_classes compiler
135
+ end
136
+ end
137
+
138
+
139
+ module CommonAssertions
140
+ import java.lang.System
141
+ import java.io.PrintStream
142
+
143
+ def assert_include(value, array, message=nil)
144
+ message = build_message message, '<?> does not include <?>', array, value
145
+ assert_block message do
146
+ array.include? value
147
+ end
148
+ end
149
+
150
+ def capture_output
151
+ saved_output = System.out
152
+ output = StringIO.new
153
+ System.setOut(PrintStream.new(output.to_outputstream))
154
+ begin
155
+ yield
156
+ output.rewind
157
+ output.read
158
+ ensure
159
+ System.setOut(saved_output)
160
+ end
161
+ end
162
+
163
+ def assert_output(expected, &block)
164
+ assert_equal(expected, capture_output(&block))
165
+ end
166
+
167
+ end
168
+
169
+ class Test::Unit::TestCase
170
+ include JVMCompiler
171
+ include CommonAssertions
172
+
173
+ def setup
174
+ @tmp_classes = []
175
+ end
176
+
177
+ def teardown
178
+ reset_type_factory
179
+ clear_tmp_files
180
+ end
181
+ end