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