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
@@ -1,752 +0,0 @@
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::AST
17
- class TransformHelper
18
- java_import 'jmeta.Ast'
19
- def initialize(transformer)
20
- @mirah = transformer
21
- end
22
-
23
- def position(node)
24
- @mirah.position(node)
25
- end
26
-
27
- def transformer
28
- @mirah
29
- end
30
-
31
- def transform(node, parent)
32
- @mirah.transform(node, parent)
33
- end
34
-
35
- def transform_script(node, parent)
36
- Script.new(parent, position(node)) do |script|
37
- script.filename = transformer.filename
38
- [@mirah.transform(node.children[0], script)]
39
- end
40
- end
41
-
42
- def transform_fixnum(node, parent)
43
- Mirah::AST::fixnum(parent, position(node), node[1])
44
- end
45
-
46
- def transform_float(node, parent)
47
- Mirah::AST::float(parent, position(node), node[1])
48
- end
49
-
50
- def transform_true(node, parent)
51
- Boolean.new(parent, position(node), true)
52
- end
53
-
54
- def transform_false(node, parent)
55
- Boolean.new(parent, position(node), false)
56
- end
57
-
58
- def transform_nil(node, parent)
59
- Null.new(parent, position(node))
60
- end
61
-
62
- def transform_self(node, parent)
63
- Self.new(parent, position(node))
64
- end
65
-
66
- def transform_string(node, parent)
67
- String.new(parent, position(node), node[1])
68
- end
69
-
70
- def transform_symbol(node, parent)
71
- String.new(parent, position(node), node[1])
72
- end
73
-
74
- def transform_body(node, parent)
75
- Body.new(parent, position(node)) do |body|
76
- node.children.map {|child| @mirah.transform(child, body)}
77
- end
78
- end
79
-
80
- def transform_begin(node, parent)
81
- @mirah.transform(node[1], parent)
82
- end
83
-
84
- def transform_break(node, parent)
85
- Break.new(parent, position(node))
86
- end
87
-
88
- def transform_arguments(node, parent)
89
- Arguments.new(parent, position(node)) do |args_node|
90
- node.children.map do |child|
91
- if child.nil?
92
- nil
93
- elsif child.kind_of?(Ast)
94
- @mirah.transform(child, args_node)
95
- else
96
- child.map {|x| @mirah.transform(x, args_node)}
97
- end
98
- end
99
- end
100
- end
101
-
102
- def transform_required_argument(node, parent)
103
- name = node[1]
104
- name = transform(name, nil) unless name.kind_of?(::String)
105
- type = node[2]
106
- type_node = transform(type, parent) if type
107
- RequiredArgument.new(parent, position(node), name, type_node)
108
- end
109
-
110
- def transform_opt_arg(node, parent)
111
- name = node[1]
112
- name = transform(name, nil) unless name.kind_of?(::String)
113
- type = node[2]
114
- value = node[3]
115
- OptionalArgument.new(parent, position(node), name) do |optarg|
116
- [
117
- type ? transform(type, optarg) : nil,
118
- transform(value, optarg),
119
- ]
120
- end
121
- end
122
-
123
- def transform_rest_arg(node, parent)
124
- name = node[1]
125
- name = transform(name, nil) unless name.kind_of?(::String)
126
- type = node[2]
127
- RestArgument.new(parent, position(node), name) do |restarg|
128
- [type ? transform(type, restarg) : nil]
129
- end
130
- end
131
-
132
- def transform_block_arg(node, parent)
133
- name = node[1]
134
- name = transform(name, nil) unless name.kind_of?(::String)
135
- type = node[2]
136
- BlockArgument.new(parent, position(node), name) do |blkarg|
137
- [type ? transform(type, blkarg) : nil]
138
- end
139
- end
140
-
141
- def transform_opt_block_arg(node, parent)
142
- block_arg = transform_block_arg(node, parent)
143
- block_arg.optional = true
144
- return block_arg
145
- end
146
-
147
- # TODO UnnamedRestArg
148
-
149
- def transform_sclass(node, parent)
150
- ClassAppendSelf.new(parent, position(node)) do |class_append_self|
151
- raise "Singleton class not supported" unless node[1][0] == 'Self'
152
-
153
- [transformer.transform(node[2], class_append_self)]
154
- end
155
- end
156
-
157
- def transform_array(node, parent)
158
- Array.new(parent, position(node)) do |array|
159
- node.children.map {|child| transformer.transform(child, array)}
160
- end
161
- end
162
-
163
- def transform_attr_assign(node, parent)
164
- name = node[1]
165
- target = node[2]
166
- args = node[3] + [node[4]]
167
- position = position(node)
168
- case name
169
- when '[]='
170
- Call.new(parent, position, name) do |call|
171
- [
172
- transformer.transform(target, call),
173
- args.map {|arg| transformer.transform(arg, call)},
174
- nil
175
- ]
176
- end
177
- else
178
- new_name = name[0..-2] + '_set'
179
- Call.new(parent, position, new_name) do |call|
180
- [
181
- transformer.transform(target, call),
182
- args.map {|arg| transformer.transform(arg, call)},
183
- nil
184
- ]
185
- end
186
- end
187
- end
188
-
189
- def transform_class(node, parent)
190
- cpath = node[1]
191
- body_node = node[2]
192
- super_node = node[3]
193
- if cpath[0] == 'Constant'
194
- name = cpath[1]
195
- elsif cpath[0] == 'Unquote'
196
- name = cpath
197
- else
198
- raise "Unsupported class name #{cpath[0]}"
199
- end
200
- name = transform(name, nil) unless name.kind_of?(::String)
201
- ClassDefinition.new(parent, position(node),
202
- name,
203
- transformer.annotations) do |class_def|
204
- [
205
- super_node ? transform(super_node, class_def) : nil,
206
- body_node ? transform(body_node, class_def) : nil
207
- ]
208
- end
209
- end
210
-
211
- def transform_def(node, parent)
212
- name, args_node, type_node, body_node = node[1], node[2], node[3], node[4]
213
- name = transform(name, nil) unless name.kind_of?(::String)
214
- position = position(node)
215
- actual_name = name
216
- if name =~ /=$/ && name != '[]='
217
- actual_name = name[0..-2] + '_set'
218
- end
219
- if name == 'initialize'
220
- klass = ConstructorDefinition
221
- else
222
- klass = MethodDefinition
223
- end
224
- klass.new(parent,
225
- position,
226
- actual_name,
227
- transformer.annotations) do |defn|
228
- defn.signature = signature = {:return => nil}
229
- defn.return_type = transform(type_node, defn) if type_node
230
- [
231
- signature,
232
- args_node ? transformer.transform(args_node, defn) : nil,
233
- body_node ? transformer.transform(body_node, defn) : nil,
234
- ]
235
- end
236
- end
237
-
238
- def transform_def_static(node, parent)
239
- name, args_node, type_node, body_node = node[1], node[2], node[3], node[4]
240
- name = transform(name, nil) unless name.kind_of?(::String)
241
- position = position(node)
242
- actual_name = name
243
- if name =~ /=$/
244
- actual_name = name[0..-2] + '_set'
245
- end
246
- StaticMethodDefinition.new(parent,
247
- position,
248
- actual_name,
249
- transformer.annotations) do |defn|
250
- defn.signature = signature = {:return => nil}
251
- defn.return_type = transform(type_node, defn) if type_node
252
- [
253
- signature,
254
- args_node ? transformer.transform(args_node, defn) : nil,
255
- body_node ? transformer.transform(body_node, defn) : nil,
256
- ]
257
- end
258
- end
259
-
260
- def transform_fcall(node, parent)
261
- if node.respond_to?(:declaration?) && node.declaration?
262
- return Noop.new(parent, position(node))
263
- end
264
-
265
- name = node[1]
266
- name = transform(name, nil) unless name.kind_of?(::String)
267
- args = node[2]
268
- iter_node = node[3]
269
- fcall = FunctionalCall.new(parent, position(node), name) do |call|
270
- [
271
- args ? args.map {|arg| transformer.transform(arg, call)} : [],
272
- iter_node ? transformer.transform(iter_node, call) : nil
273
- ]
274
- end
275
- macro = Mirah::AST.macro(name)
276
- if macro
277
- transformer.expand(fcall, parent, &macro)
278
- else
279
- fcall
280
- end
281
- end
282
-
283
- def transform_call(node, parent)
284
- name = node[1]
285
- name = transform(name, nil) unless name.kind_of?(::String)
286
- target = node[2]
287
- args = node[3]
288
- iter_node = node[4]
289
- position = position(node)
290
-
291
- actual_name = name
292
- case actual_name
293
- when '[]'
294
- # could be array instantiation
295
- case target[0]
296
- when 'Identifier'
297
- case target[1]
298
- when 'boolean', 'byte', 'short', 'char', 'int', 'long', 'float', 'double'
299
- if args.nil? || args.size == 0
300
- constant = Constant.new(parent, position, target[1])
301
- constant.array = true
302
- return constant
303
- elsif args && args.size == 1
304
- return EmptyArray.new(parent, position) do |array|
305
- [transform(target, array), transform(args[0], array)]
306
- end
307
- end
308
- # TODO look for imported, lower case class names
309
- end
310
- when 'Constant'
311
- if args.nil? || args.size == 0
312
- constant = Constant.new(parent, position, target[1])
313
- constant.array = true
314
- return constant
315
- elsif args && args.size == 1
316
- return EmptyArray.new(parent, position) do |array|
317
- [transform(target, array), transform(args[0], array)]
318
- end
319
- end
320
- end
321
- when /=$/
322
- if name.size > 2 || name =~ /^\w/
323
- actual_name = name[0..-2] + '_set'
324
- end
325
- end
326
-
327
- Call.new(parent, position, actual_name) do |call|
328
- [
329
- transformer.transform(target, call),
330
- args ? args.map {|arg| transformer.transform(arg, call)} : [],
331
- iter_node ? transformer.transform(iter_node, call) : nil
332
- ]
333
- end
334
- end
335
-
336
- def transform_constant(node, parent)
337
- Constant.new(parent, position(node), node[1])
338
- end
339
-
340
- def transform_colon2const(node, parent)
341
- name = node[2]
342
- name = transform(name, nil) unless name.kind_of?(::String)
343
- target = node[1]
344
- Colon2.new(parent, position(node), name) do |colon2|
345
- [ transform(target, colon2) ]
346
- end
347
- end
348
-
349
- def transform_identifier(node, parent)
350
- name = node[1]
351
- position = position(node)
352
- if name == 'raise'
353
- Raise.new(parent, position) do
354
- []
355
- end
356
- elsif name == 'null'
357
- Null.new(parent, position)
358
- elsif ['public', 'private', 'protected'].include?(name)
359
- AccessLevel.new(parent, position, name)
360
- else
361
- macro = Mirah::AST.macro(name)
362
- fcall = FunctionalCall.new(parent, position, name) do |call|
363
- [
364
- [],
365
- nil
366
- ]
367
- end
368
- if macro
369
- transformer.expand(fcall, parent, &macro)
370
- else
371
- fcall
372
- end
373
- end
374
- end
375
-
376
- def transform_local_assign(node, parent)
377
- name = node[1]
378
- value_node = node[2]
379
- position = position(node)
380
- case value_node[0]
381
- when 'Symbol', 'Constant'
382
- LocalDeclaration.new(parent, position, name) {|local_decl| [transform(value_node, local_decl)]}
383
- else
384
- LocalAssignment.new(parent, position, name) {|local| [transform(value_node, local)]}
385
- end
386
- end
387
-
388
- def transform_local(node, parent)
389
- name = node[1]
390
- Local.new(parent, position(node), name)
391
- end
392
-
393
- def transform_iter(node, parent)
394
- args = node[1]
395
- body = node[2]
396
- Block.new(parent, position(node)) do |block|
397
- [
398
- args ? transformer.transform(args, block) : Arguments.new(block, position(node)),
399
- body ? transformer.transform(body, block) : nil,
400
- ]
401
- end
402
- end
403
-
404
- def transform_inst_var(node, parent)
405
- name = node[1]
406
- name = transform(name, nil) unless name.kind_of?(::String)
407
- Field.new(parent, position(node), name, transformer.annotations)
408
- end
409
-
410
- def transform_inst_var_assign(node, parent)
411
- name = node[1]
412
- name = transform(name, nil) unless name.kind_of?(::String)
413
- value_node = node[2]
414
- position = position(node)
415
- case value_node[0]
416
- when 'Symbol', 'Constant'
417
- FieldDeclaration.new(parent, position,
418
- name, transformer.annotations) do |field_decl|
419
- [transform(value_node, field_decl)]
420
- end
421
- else
422
- FieldAssignment.new(parent, position, name, transformer.annotations) {|field| [transformer.transform(value_node, field)]}
423
- end
424
- end
425
-
426
- def transform_class_var(node, parent)
427
- name = node[1]
428
- name = transform(name, nil) unless name.kind_of?(::String)
429
- Field.new(parent, position(node), name, transformer.annotations, true)
430
- end
431
-
432
- def transform_class_var_assign(node, parent)
433
- name = node[1]
434
- name = transform(name, nil) unless name.kind_of?(::String)
435
- value_node = node[2]
436
- position = position(node)
437
- case value_node[0]
438
- when 'Symbol', 'Constant'
439
- FieldDeclaration.new(parent, position,
440
- name, transformer.annotations, true) do |field_decl|
441
- [transform(value_node, field_decl)]
442
- end
443
- else
444
- FieldAssignment.new(parent, position, name, transformer.annotations, true) {|field| [transformer.transform(value_node, field)]}
445
- end
446
- end
447
-
448
- def transform_if(node, parent)
449
- condition = node[1]
450
- then_body = node[2]
451
- else_body = node[3]
452
- If.new(parent, position(node)) do |iff|
453
- [
454
- Condition.new(iff, position(condition)) {|cond| [transformer.transform(condition, cond)]},
455
- then_body ? transformer.transform(then_body, iff) : nil,
456
- else_body ? transformer.transform(else_body, iff) : nil
457
- ]
458
- end
459
- end
460
-
461
- def transform_zsuper(node, parent)
462
- Super.new(parent, position(node))
463
- end
464
-
465
- def transform_super(node, parent)
466
- args = node[1]
467
- iter = node[2]
468
- Super.new(parent, position(node)) do |s|
469
- [args ? args.map {|arg| transformer.transform(arg, s)} : []]
470
- end
471
- end
472
-
473
- def transform_return(node, parent)
474
- value_node = node[1] if node.size > 1
475
- Return.new(parent, position(node)) do |ret|
476
- [value_node ? transform(value_node, ret) : nil]
477
- end
478
- end
479
-
480
- def transform_dstring(node, parent)
481
- StringConcat.new(parent, position(node)) do |p|
482
- node.children.map{|n| transform(n, p)}
483
- end
484
- end
485
-
486
- def transform_ev_string(node, parent)
487
- ToString.new(parent, position(node)) do |p|
488
- [transform(node[1], p)]
489
- end
490
- end
491
-
492
- def transform_and(node, parent)
493
- first_node = node[1]
494
- second_node = node[2]
495
- If.new(parent, position(node)) do |iff|
496
- [
497
- Condition.new(iff, position(first_node)) {|cond| [transform(first_node, cond)]},
498
- transform(second_node, iff),
499
- nil
500
- ]
501
- end
502
- end
503
-
504
- def transform_or(node, parent)
505
- first_node = node[1]
506
- second_node = node[2]
507
- Body.new(parent, position(node)) do |block|
508
- temp = transformer.tmp
509
- [
510
- LocalAssignment.new(block, position(first_node), temp) do |l|
511
- [transform(first_node, l)]
512
- end,
513
- If.new(parent, position(node)) do |iff|
514
- [
515
- Condition.new(iff, position(first_node)) do |cond|
516
- [Local.new(cond, position(first_node), temp)]
517
- end,
518
- Local.new(iff, position(first_node), temp),
519
- transform(second_node, iff)
520
- ]
521
- end
522
- ]
523
- end
524
- end
525
-
526
- def transform_next(node, parent)
527
- Next.new(parent, position(node))
528
- end
529
-
530
- def transform_not(node, parent)
531
- # TODO it's probably better to keep a not node
532
- # and actually implement compiling it properly.
533
- # Bonus points for optimizing branches that use Not's.
534
- If.new(parent, position(node)) do |iff|
535
- [
536
- Condition.new(iff, position(node)) do |cond|
537
- [ transform(node[1], cond) ]
538
- end,
539
- Boolean.new(iff, position(node), false),
540
- Boolean.new(iff, position(node), true)
541
- ]
542
- end
543
- end
544
-
545
- def transform_redo(node, parent)
546
- Redo.new(parent, position(node))
547
- end
548
-
549
- def transform_regex(node, parent)
550
- contents = node[1]
551
- modifiers = node[2]
552
- if contents.size == 1 && contents[0][0] == 'String'
553
- value = contents[0][1]
554
- Regexp.new(parent, position(node), value)
555
- else
556
- raise "Unsupported regex #{node}"
557
- end
558
- end
559
-
560
- def transform_ensure(node, parent)
561
- Ensure.new(parent, position(node)) do |n|
562
- node.children.map {|c| transform(c, n)}
563
- end
564
- end
565
-
566
- def evaluate_at_start?(node)
567
- if node[0] =~ /Mod$/ && node[2] && node[2][0] == 'Begin'
568
- false
569
- else
570
- true
571
- end
572
- end
573
-
574
- def transform_while(node, parent)
575
- condition_node = node[1]
576
- body_node = node[2]
577
- Loop.new(parent, position(node), evaluate_at_start?(node), false) do |loop|
578
- [
579
- Condition.new(loop, position(condition_node)) {|cond| [transform(condition_node, cond)]},
580
- transform(body_node, loop)
581
- ]
582
- end
583
- end
584
- def transform_while_mod(node, parent)
585
- transform_while(node, parent)
586
- end
587
-
588
- def transform_until(node, parent)
589
- condition_node = node[1]
590
- body_node = node[2]
591
- Loop.new(parent, position(node), evaluate_at_start?(node), true) do |loop|
592
- [
593
- Condition.new(loop, position(condition_node)) {|cond| [transform(condition_node, cond)]},
594
- transform(body_node, loop)
595
- ]
596
- end
597
- end
598
- def transform_until_mod(node, parent)
599
- transform_until(node, parent)
600
- end
601
-
602
- def transform_for(node, parent)
603
- var_node = node[1]
604
- body_node = node[2]
605
- iter_node = node[3]
606
- Call.new(parent, position(node), 'each') do |each|
607
- [
608
- transformer.transform(iter_node, each),
609
- [],
610
- Block.new(each, position(body_node)) do |block|
611
- [
612
- Arguments.new(block, position(var_node)) do |args|
613
- [
614
- # TODO support for multiple assignment?
615
- [RequiredArgument.new(args,
616
- position(var_node),
617
- var_node[1])
618
- ]
619
- ]
620
- end,
621
- transformer.transform(body_node, block)
622
- ]
623
- end
624
- ]
625
- end
626
- end
627
-
628
- def transform_rescue(node, parent)
629
- body_node = node[1]
630
- clauses = node[2]
631
- Rescue.new(parent, position(node)) do |node|
632
- [
633
- transformer.transform(body_node, node),
634
- clauses.map {|clause| transformer.transform(clause, node)}
635
- ]
636
- end
637
- end
638
-
639
- def transform_rescue_clause(node, parent)
640
- exceptions = node[1]
641
- var_name = node[2]
642
- name = transform(var_name, nil) unless var_name.nil? || var_name.kind_of?(::String)
643
- body = node[3]
644
- RescueClause.new(parent, position(node)) do |clause|
645
- clause.name = var_name if var_name
646
- [
647
- if exceptions.size == 0
648
- [String.new(clause, position(node), 'java.lang.Exception')]
649
- else
650
- exceptions.map {|name| Constant.new(clause, position(node), name)}
651
- end,
652
- body ? transformer.transform(body, clause) : Null.new(clause, position(node))
653
- ]
654
- end
655
- end
656
-
657
- def transform_hash(node, parent)
658
- Call.new(parent, position(node), 'new_hash') do |call|
659
- [
660
- Builtin.new(call, position(node)),
661
- [
662
- Array.new(call, position(node)) do |array|
663
- values = []
664
- node.children.each do |assoc|
665
- assoc.children.each do |child|
666
- values << transform(child, array)
667
- end
668
- end
669
- values
670
- end
671
- ]
672
- ]
673
- end
674
- end
675
-
676
- def transform_op_assign(node, parent)
677
- target = node[1]
678
- attribute = node[2]
679
- op = node[3]
680
- value = node[4]
681
- temp = transformer.tmp
682
- tempval = transformer.tmp
683
- position = position(node)
684
- setter = "#{attribute}="
685
- getter = attribute
686
- Body.new(parent, position) do |body|
687
- [
688
- LocalAssignment.new(body, position, temp) {|l| transform(target, l)},
689
- LocalAssignment.new(body, position, tempval) do |l|
690
- Call.new(l, position, op) do |op_call|
691
- [
692
- Call.new(op_call, position, getter) do |get_call|
693
- [
694
- Local.new(get_call, position, temp),
695
- []
696
- ]
697
- end,
698
- [transform(value, op_call)],
699
- ]
700
- end
701
- end,
702
- Call.new(body, position, setter) do |set_call|
703
- [
704
- Local.new(set_call, position, temp),
705
- [ Local.new(set_call, position, tempval) ],
706
- ]
707
- end,
708
- Local.new(body, position, tempval),
709
- ]
710
- end
711
- end
712
-
713
- def transform_unquote(node, parent)
714
- Unquote.new(parent, position(node)) do |unquote|
715
- [transform(node[1], unquote)]
716
- end
717
- end
718
-
719
- def transform_unquote_assign(node, parent)
720
- name, value = node[1], node[2]
721
- UnquoteAssign.new(parent, position(node)) do |unquote|
722
- [transform(name, unquote), transform(value, unquote)]
723
- end
724
- end
725
-
726
- def transform_block_pass(node, parent)
727
- BlockPass.new(parent, position(node)) do |blockpass|
728
- [transform(node[1], blockpass)]
729
- end
730
- end
731
-
732
- def transform_annotation(node, parent)
733
- classname = node[1]
734
- values = if node[2]
735
- node[2].children
736
- else
737
- []
738
- end
739
- annotation = Annotation.new(parent, position(node)) do |anno|
740
- [String.new(anno, position(node), classname)]
741
- end
742
- values.each do |assoc|
743
- key = assoc[1]
744
- value = assoc[2]
745
- name = key[1]
746
- annotation[name] = transform(value, annotation)
747
- end
748
- transformer.add_annotation(annotation)
749
- return Noop.new(parent, position(node))
750
- end
751
- end
752
- end