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,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