mirah 0.0.12-java → 0.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. data/History.txt +372 -0
  2. data/README.txt +4 -5
  3. data/Rakefile +178 -55
  4. data/examples/appengine/Readme +3 -3
  5. data/examples/appengine/src/org/mirah/MirahApp.mirah +1 -1
  6. data/examples/appengine/src/org/mirah/list.dhtml +1 -1
  7. data/examples/bintrees.mirah +1 -1
  8. data/examples/edb.mirah +1 -1
  9. data/examples/fib.mirah +1 -1
  10. data/examples/interfaces.mirah +1 -1
  11. data/examples/macros/{string-each-char.mirah → string_each_char.mirah} +4 -5
  12. data/examples/maven/README.txt +1 -1
  13. data/examples/maven/src/main/mirah/hello_mirah.mirah +1 -1
  14. data/examples/plugins/appengine/Rakefile +1 -1
  15. data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/MetaModel.mirah +1 -1
  16. data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/Model.duby +1 -1
  17. data/examples/plugins/appengine/test/com/google/appengine/ext/duby/db/ModelTest.duby +1 -1
  18. data/examples/rosettacode/100-doors.mirah +6 -6
  19. data/examples/rosettacode/README.txt +3 -3
  20. data/examples/rosettacode/boolean-values.mirah +1 -1
  21. data/examples/rosettacode/comments.mirah +1 -1
  22. data/examples/rosettacode/count-occurrences-of-a-substring.mirah +1 -1
  23. data/examples/rosettacode/factorial.mirah +1 -1
  24. data/examples/rosettacode/fibonacci.mirah +1 -1
  25. data/examples/rosettacode/fizz-buzz.mirah +2 -2
  26. data/examples/rosettacode/flatten-a-list.mirah +4 -4
  27. data/examples/rosettacode/guess-the-number.mirah +2 -2
  28. data/examples/rosettacode/hamming-numbers.mirah +4 -4
  29. data/examples/rosettacode/is-string-numeric.mirah +22 -22
  30. data/examples/rosettacode/palindrome.mirah +2 -2
  31. data/examples/rosettacode/random-numbers.mirah +1 -1
  32. data/examples/rosettacode/repeat-a-string.mirah +1 -1
  33. data/examples/rosettacode/reverse-a-string.mirah +1 -1
  34. data/examples/rosettacode/rot-13.mirah +5 -5
  35. data/examples/rosettacode/secure-temporary-file.mirah +2 -2
  36. data/examples/rosettacode/sleep.mirah +1 -1
  37. data/examples/rosettacode/string-length.mirah +5 -5
  38. data/examples/swing.mirah +1 -1
  39. data/examples/test.edb +1 -1
  40. data/javalib/mirah-bootstrap.jar +0 -0
  41. data/javalib/mirah-builtins.jar +0 -0
  42. data/javalib/mirah-parser.jar +0 -0
  43. data/javalib/mirah-util.jar +0 -0
  44. data/lib/duby.rb +1 -1
  45. data/lib/mirah.rb +50 -28
  46. data/lib/mirah/ast.rb +15 -605
  47. data/lib/mirah/ast/scope.rb +98 -69
  48. data/lib/mirah/commands.rb +1 -1
  49. data/lib/mirah/commands/base.rb +7 -7
  50. data/lib/mirah/commands/compile.rb +3 -3
  51. data/lib/mirah/commands/parse.rb +7 -5
  52. data/lib/mirah/commands/run.rb +12 -19
  53. data/lib/mirah/compiler.rb +15 -23
  54. data/lib/mirah/errors.rb +16 -1
  55. data/lib/mirah/generator.rb +79 -39
  56. data/lib/mirah/jvm/compiler.rb +1 -19
  57. data/lib/mirah/jvm/compiler/base.rb +233 -90
  58. data/lib/mirah/jvm/compiler/jvm_bytecode.rb +675 -363
  59. data/lib/mirah/jvm/method_lookup.rb +134 -65
  60. data/lib/mirah/jvm/typer.rb +10 -5
  61. data/lib/mirah/jvm/types.rb +10 -2
  62. data/lib/mirah/jvm/types/array_type.rb +10 -12
  63. data/lib/mirah/{compiler/type.rb → jvm/types/ast_ext.rb} +12 -8
  64. data/lib/mirah/jvm/types/basic_types.rb +26 -33
  65. data/lib/mirah/jvm/types/bitescript_ext.rb +1 -1
  66. data/lib/mirah/jvm/types/block_type.rb +15 -0
  67. data/lib/mirah/jvm/types/boolean.rb +8 -4
  68. data/lib/mirah/jvm/types/dynamic_type.rb +12 -13
  69. data/lib/mirah/jvm/types/enumerable.rb +7 -7
  70. data/lib/mirah/jvm/types/extensions.rb +11 -6
  71. data/lib/mirah/jvm/types/factory.rb +624 -94
  72. data/lib/mirah/jvm/types/floats.rb +21 -15
  73. data/lib/mirah/jvm/types/generic_type.rb +72 -0
  74. data/lib/mirah/jvm/types/implicit_nil_type.rb +29 -0
  75. data/lib/mirah/jvm/types/integers.rb +26 -71
  76. data/lib/mirah/jvm/types/interface_definition.rb +3 -3
  77. data/lib/mirah/jvm/types/intrinsics.rb +203 -168
  78. data/lib/mirah/jvm/types/literals.rb +6 -6
  79. data/lib/mirah/jvm/types/meta_type.rb +13 -4
  80. data/lib/mirah/jvm/types/methods.rb +281 -93
  81. data/lib/mirah/jvm/types/null_type.rb +17 -5
  82. data/lib/mirah/jvm/types/number.rb +10 -7
  83. data/lib/mirah/jvm/types/primitive_type.rb +17 -6
  84. data/lib/mirah/jvm/types/source_mirror.rb +12 -7
  85. data/lib/mirah/jvm/types/type.rb +107 -23
  86. data/lib/mirah/jvm/types/type_definition.rb +25 -10
  87. data/lib/mirah/jvm/types/unreachable_type.rb +1 -1
  88. data/lib/mirah/jvm/types/void_type.rb +3 -3
  89. data/lib/mirah/parser.rb +154 -16
  90. data/lib/mirah/plugin/edb.rb +1 -1
  91. data/lib/mirah/transform.rb +1 -2
  92. data/lib/mirah/transform/ast_ext.rb +24 -43
  93. data/lib/mirah/transform/transformer.rb +29 -224
  94. data/lib/mirah/typer.rb +2 -16
  95. data/lib/mirah/util/argument_processor.rb +25 -10
  96. data/lib/mirah/util/class_loader.rb +1 -1
  97. data/lib/mirah/util/compilation_state.rb +16 -17
  98. data/lib/mirah/util/delegate.rb +2 -2
  99. data/lib/mirah/util/logging.rb +110 -0
  100. data/lib/mirah/util/process_errors.rb +69 -11
  101. data/lib/mirah/version.rb +1 -1
  102. data/test/core/commands_test.rb +6 -24
  103. data/test/core/env_test.rb +5 -5
  104. data/{lib/mirah/jvm/source_generator/typer.rb → test/core/generator_test.rb} +9 -9
  105. data/test/core/typer_test.rb +196 -158
  106. data/test/core/util/argument_processor_test.rb +10 -10
  107. data/test/core/util/class_loader_test.rb +6 -5
  108. data/test/fixtures/org/foo/LowerCaseInnerClass$inner.class +0 -0
  109. data/test/fixtures/org/foo/LowerCaseInnerClass.class +0 -0
  110. data/test/fixtures/org/foo/LowerCaseInnerClass.java +7 -0
  111. data/test/jvm/annotations_test.rb +5 -5
  112. data/test/jvm/blocks_test.rb +140 -88
  113. data/test/jvm/bytecode_test_helper.rb +112 -94
  114. data/test/jvm/cast_test.rb +162 -0
  115. data/test/jvm/constructors_test.rb +18 -8
  116. data/test/jvm/enumerable_test.rb +77 -44
  117. data/test/jvm/example_test.rb +53 -0
  118. data/test/jvm/factory_test.rb +7 -1
  119. data/test/jvm/generics_test.rb +57 -0
  120. data/test/jvm/hash_test.rb +106 -0
  121. data/test/jvm/import_test.rb +81 -0
  122. data/test/jvm/interface_test.rb +73 -0
  123. data/test/jvm/java_typer_test.rb +92 -66
  124. data/{lib/mirah/typer/base.rb → test/jvm/jvm_commands_test.rb} +6 -10
  125. data/test/jvm/jvm_compiler_test.rb +170 -604
  126. data/test/jvm/list_extensions_test.rb +23 -0
  127. data/test/jvm/macros_test.rb +197 -32
  128. data/test/jvm/main_method_test.rb +4 -4
  129. data/test/jvm/numeric_extensions_test.rb +13 -0
  130. data/test/jvm/rescue_test.rb +73 -16
  131. data/test/jvm/varargs_test.rb +65 -0
  132. data/test/test_helper.rb +1 -2
  133. metadata +234 -251
  134. data/examples/SortClosure$__xform_tmp_1.class +0 -0
  135. data/examples/SortClosure$__xform_tmp_2.class +0 -0
  136. data/examples/SortClosure.class +0 -0
  137. data/examples/macros/StringEachChar$Extension1.class +0 -0
  138. data/lib/mirah/ast/call.rb +0 -345
  139. data/lib/mirah/ast/class.rb +0 -359
  140. data/lib/mirah/ast/flow.rb +0 -381
  141. data/lib/mirah/ast/intrinsics.rb +0 -563
  142. data/lib/mirah/ast/literal.rb +0 -178
  143. data/lib/mirah/ast/local.rb +0 -112
  144. data/lib/mirah/ast/method.rb +0 -408
  145. data/lib/mirah/ast/structure.rb +0 -387
  146. data/lib/mirah/ast/type.rb +0 -146
  147. data/lib/mirah/commands/base.rb~ +0 -57
  148. data/lib/mirah/compiler/call.rb +0 -45
  149. data/lib/mirah/compiler/class.rb +0 -81
  150. data/lib/mirah/compiler/flow.rb +0 -109
  151. data/lib/mirah/compiler/literal.rb +0 -130
  152. data/lib/mirah/compiler/local.rb +0 -59
  153. data/lib/mirah/compiler/method.rb +0 -44
  154. data/lib/mirah/compiler/structure.rb +0 -65
  155. data/lib/mirah/jvm/compiler/java_source.rb +0 -787
  156. data/lib/mirah/jvm/method_lookup.rb~ +0 -247
  157. data/lib/mirah/jvm/source_generator/builder.rb +0 -468
  158. data/lib/mirah/jvm/source_generator/loops.rb +0 -131
  159. data/lib/mirah/jvm/source_generator/precompile.rb +0 -210
  160. data/lib/mirah/plugin/gwt.rb +0 -189
  161. data/lib/mirah/plugin/java.rb +0 -70
  162. data/lib/mirah/transform/error.rb +0 -13
  163. data/lib/mirah/transform/helper.rb +0 -765
  164. data/lib/mirah/typer/simple.rb +0 -384
  165. data/lib/mirah/version.rb~ +0 -18
  166. data/test/core/ast_test.rb +0 -382
  167. data/test/core/compilation_test.rb +0 -130
  168. data/test/core/macros_test.rb +0 -61
  169. data/test/jvm/javac_test_helper.rb +0 -89
  170. data/test/jvm/jvm_compiler_test.rb~ +0 -2181
  171. data/test/plugins/gwt_test.rb +0 -69
@@ -1,384 +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
- require 'mirah/ast'
17
- require 'mirah/transform'
18
-
19
- module Mirah
20
- module Typer
21
- class Simple < Base
22
- attr_accessor :known_types, :errors, :last_chance
23
-
24
- def initialize(self_type)
25
- @known_types = {}
26
-
27
- @known_types["self"] = type_reference(nil, self_type)
28
- @known_types["fixnum"] = type_reference(nil, "fixnum")
29
- @known_types["float"] = type_reference(nil, "float")
30
- @known_types["string"] = type_reference(nil, "string")
31
- @known_types["boolean"] = type_reference(nil, "boolean")
32
- @errors = []
33
- end
34
-
35
- def name
36
- "Simple"
37
- end
38
-
39
- def set_filename(scope, name); end
40
-
41
- def self_type
42
- known_types["self"]
43
- end
44
-
45
- def default_type
46
- nil
47
- end
48
-
49
- def fixnum_type(value=0)
50
- known_types["fixnum"]
51
- end
52
-
53
- def float_type(value=0)
54
- known_types["float"]
55
- end
56
-
57
- def string_type
58
- known_types["string"]
59
- end
60
-
61
- def boolean_type
62
- known_types["boolean"]
63
- end
64
-
65
- def null_type
66
- AST::TypeReference::NullType
67
- end
68
-
69
- def no_type
70
- AST::TypeReference::NoType
71
- end
72
-
73
- # to be overridden
74
- def array_type
75
- AST::TypeReference::NullType
76
- end
77
-
78
- # to be overridden
79
- def hash_type
80
- AST::TypeReference::NullType
81
- end
82
-
83
- def known_type(scope, name)
84
- @known_types[name]
85
- end
86
-
87
- def define_type(scope, name, superclass, interfaces)
88
- log "New type defined: '#{name}' < '#{superclass}'"
89
- result = type_definition(scope, name, superclass, interfaces)
90
-
91
- # TODO Get rid of known_types["self"]
92
- old_self, known_types["self"] = known_types["self"], result
93
- yield
94
- known_types["self"] = old_self
95
-
96
- result
97
- end
98
-
99
- def learn_local_type(scope, name, type)
100
- return if type.null? && !@last_chance
101
- type = scope.learn_local_type(name, known_types[type] || type)
102
- log "Learned local type under #{scope} : #{name} = #{type}" if type
103
- type
104
- end
105
-
106
- def local_type(scope, name)
107
- type = scope.local_type(name)
108
- log "Retrieved local type in #{scope} : #{name} = #{type}" if type
109
- type
110
- end
111
-
112
- def local_types
113
- @local_types ||= {}
114
- end
115
-
116
- def local_type_hash(scope)
117
- local_types[scope] ||= {}
118
- end
119
-
120
- def field_types
121
- @field_types ||= {}
122
- end
123
-
124
- def field_type_hash(cls)
125
- field_types[cls] ||= {}
126
- end
127
-
128
- def static_field_types
129
- @static_field_types ||= {}
130
- end
131
-
132
- def static_field_type_hash(cls)
133
- static_field_types[cls] ||= {}
134
- end
135
-
136
- def infer_signature(method_def)
137
- end
138
-
139
- def learn_field_type(cls, name, type)
140
- log "Learned field type under #{cls} : #{name} = #{type}" if type
141
-
142
- # TODO check for compatibility?
143
- field_type_hash(cls)[name] ||= known_types[type] || type
144
-
145
- type
146
- end
147
-
148
- def field_type(cls, name)
149
- field_type_hash(cls)[name]
150
- end
151
-
152
- def learn_static_field_type(cls, name, type)
153
- log "Learned field type under #{cls} : #{name} = #{type}" if type
154
-
155
- # TODO check for compatibility?
156
- static_field_type_hash(cls)[name] ||= known_types[type] || type
157
-
158
- type
159
- end
160
-
161
- def static_field_type(cls, name)
162
- static_field_type_hash(cls)[name]
163
- end
164
-
165
- def learn_method_type(target_type, name, parameter_types, type, exceptions)
166
- log "Learned method #{name} (#{parameter_types}) on #{target_type} = #{type}" if type
167
-
168
- get_method_type_hash(target_type, name, parameter_types)[:type] = known_types[type] || type
169
-
170
- # if it's any args are imported types, also add a mapping for the expanded name
171
- imported_types = parameter_types.map {|param| known_types[param] || param}
172
- get_method_type_hash(target_type, name, imported_types)[:type] = type
173
- end
174
-
175
- def method_type(target_type, name, parameter_types)
176
- if (target_type && target_type.error?) ||
177
- parameter_types.any? {|t| t && t.error?}
178
- return AST.error_type
179
- end
180
- constructor = (name == 'new' && target_type && target_type.meta?)
181
-
182
- if constructor
183
- # constructor handled different from other methods
184
- simple_type = get_method_type_hash(target_type.unmeta, 'initialize', parameter_types)[:type]
185
- else
186
- simple_type = get_method_type_hash(target_type, name, parameter_types)[:type]
187
- end
188
-
189
-
190
- if !simple_type
191
- log "Method type for \"#{name}\" #{parameter_types} on #{target_type} not found."
192
-
193
- # allow plugins a go if we're in the inference phase
194
- simple_type = plugins do |plugin|
195
- plugin.method_type(self, target_type, name, parameter_types)
196
- end
197
- end
198
-
199
- return nil unless simple_type
200
-
201
- if constructor
202
- log "Method type for \"#{name}\" #{parameter_types} on #{target_type} = #{target_type}"
203
- target_type.unmeta
204
- else
205
- log "Method type for \"#{name}\" #{parameter_types} on #{target_type} = #{simple_type}"
206
- simple_type
207
- end
208
- end
209
-
210
- def plugins
211
- if cycling?
212
- Mirah.typer_plugins.each do |plugin|
213
- log "Invoking plugin: #{plugin}"
214
-
215
- result = yield plugin
216
- return result if result
217
- end
218
- end
219
-
220
- nil
221
- end
222
-
223
- def cycling?
224
- @cycling
225
- end
226
-
227
- def cycling=(c)
228
- @cycling = c
229
- end
230
-
231
- def cycle(count)
232
- @cycling = true
233
- count.times do |i|
234
- begin
235
- log "[Cycle #{i}]: Started... (#{@deferred_nodes.size} nodes to resolve)"
236
- yield i
237
- ensure
238
- log "[Cycle #{i}]: Complete!"
239
- end
240
- end
241
- ensure
242
- @cycling = false
243
- end
244
-
245
- def method_types
246
- @method_types ||= {}
247
- end
248
-
249
- def get_method_type_hash(target_type, name, parameter_types)
250
- method_types[target_type] ||= {}
251
- method_types[target_type][name] ||= {}
252
- method_types[target_type][name][parameter_types.size] ||= {}
253
-
254
- current = method_types[target_type][name][parameter_types.size]
255
-
256
- parameter_types.each {|type| current[type] ||= {}; current = current[type]}
257
-
258
- current
259
- end
260
-
261
- def type_reference(scope, name, array=false, meta=false)
262
- AST::TypeReference.new(name, array, meta)
263
- end
264
-
265
- def type_definition(scope, name, superclass, interfaces)
266
- AST::TypeDefinition.new(name, AST::TypeReference.new(superclass), interfaces)
267
- end
268
-
269
- def deferred_nodes
270
- @deferred_nodes ||= {}
271
- end
272
-
273
- def infer(node, expression=true)
274
- begin
275
- node.infer(self, expression)
276
- rescue InferenceError => ex
277
- ex.node ||= node
278
- error(node, ex)
279
- rescue Exception => ex
280
- raise Mirah::InternalCompilerError.wrap(ex, node)
281
- end
282
- end
283
-
284
- def error(node, error_or_msg=nil, backtrace=nil)
285
- if error_or_msg.kind_of? InferenceError
286
- error = error_or_msg
287
- elsif error_or_msg
288
- error = InferenceError.new(error_or_msg, node)
289
- error.set_backtrace(backtrace) if backtrace
290
- else
291
- error = InferenceError.new("Unable to infer type.", node)
292
- end
293
- @errors << error
294
- node.resolve_if(self) do
295
- AST.error_type
296
- end
297
- end
298
-
299
- def defer(node, error_message=nil)
300
- if @error_next
301
- log "Marking #{node} as an error"
302
- @error_next = false
303
- error(node, error_message)
304
- else
305
- raise "Can't defer nil" if node.nil?
306
- return if deferred_nodes.include? node
307
- log "Deferring inference for #{node}"
308
-
309
- deferred_nodes[node] = self_type
310
- end
311
- end
312
-
313
- def resolve(raise = false)
314
- count = deferred_nodes.size + 1
315
-
316
- log "Entering type inference cycle"
317
-
318
- retried = false
319
- cycle(count) do |i|
320
- old_deferred = @deferred_nodes
321
- @deferred_nodes = {}
322
- old_deferred.each do |node, saved_type|
323
- known_types["self"] = saved_type
324
- type = infer(node)
325
-
326
- log "[Cycle #{i}]: Inferred type for #{node}: #{type || 'FAILED'}"
327
-
328
- if type == default_type
329
- @deferred_nodes[node] = saved_type
330
- end
331
- end
332
-
333
- if @deferred_nodes.empty?
334
- log "[Cycle #{i}]: Resolved all types, exiting"
335
- break
336
- elsif old_deferred == @deferred_nodes
337
- if @error_next || retried
338
- log "[Cycle #{i}]: Made no progress, bailing out"
339
- break
340
- elsif @last_chance
341
- break unless @errors.empty?
342
- # Retry this iteration, and mark the first deferred
343
- # type as an error.
344
- retried = true
345
- @error_next = true
346
- redo
347
- else
348
- # This is a hack for default constructor support. The right fix
349
- # is probably to check the AST for constructors. Instead we
350
- # tell the plugins that we're near the end of inference so they
351
- # can assume no new constructors are being added. You could
352
- # easily write some circular constructors that would compile
353
- # with this technique but fail to run.
354
- @last_chance = true
355
- redo
356
- end
357
- elsif @errors.size > 15
358
- log "Too many errors, giving up"
359
- break
360
- end
361
- retried = false
362
- end
363
-
364
- # done with n sweeps, if any remain mark them as errors
365
- error_nodes = @errors.map {|e| e.node}
366
- if error_nodes.empty?
367
- (deferred_nodes.keys - error_nodes).each do |deferred_node|
368
- break if @errors.size > 15
369
- error_nodes << deferred_node
370
- error(deferred_node)
371
- end
372
- end
373
- if raise && !error_nodes.empty?
374
- msg = "Could not infer typing for nodes:"
375
- error_nodes.map do |e|
376
- msg << "\n "
377
- msg << "#{e.inspect} at line #{e.line_number} (child of #{e.parent})"
378
- end
379
- raise InferenceError.new(msg)
380
- end
381
- end
382
- end
383
- end
384
- end
@@ -1,18 +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
17
- VERSION = "0.0.9"
18
- end
@@ -1,382 +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
- require 'test_helper'
16
-
17
- class AstTest < Test::Unit::TestCase
18
- include Mirah
19
-
20
- def test_args
21
- new_ast = AST.parse("def foo(a, *c, &d); end").body[0]
22
- arguments = new_ast.arguments
23
-
24
- assert_not_nil(arguments)
25
- inspected = "Arguments\n RequiredArgument(a)\n RestArgument(c)\n BlockArgument(d)"
26
- assert_equal(inspected, arguments.inspect)
27
-
28
- assert(AST::Arguments === arguments)
29
- children = arguments.children
30
- assert_not_nil(children)
31
- assert_equal(5, children.size)
32
- assert(Array === children[0])
33
- assert(AST::RequiredArgument === children[0][0])
34
- assert_equal("a", children[0][0].name)
35
- assert_equal(arguments, children[0][0].parent)
36
- assert(AST::RestArgument === children[2])
37
- assert_equal("c", children[2].name)
38
- assert_equal(arguments, children[2].parent)
39
- assert(AST::BlockArgument === children[4])
40
- assert_equal("d", children[4].name)
41
- assert_equal(arguments, children[4].parent)
42
- end
43
-
44
- def test_locals
45
- new_ast = AST.parse("a = 1; a").body
46
-
47
- assert_not_nil(new_ast)
48
- assert(AST::Body === new_ast)
49
- inspected = "Body\n LocalAssignment(name = a, scope = Script, captured = false)\n Fixnum(1)\n FunctionalCall(a)"
50
- assert_equal(inspected, new_ast.inspect)
51
-
52
- asgn = new_ast[0]
53
- var = new_ast[1]
54
-
55
- assert(AST::LocalAssignment === asgn)
56
- assert_equal("a", asgn.name)
57
- assert(AST::Fixnum === asgn.value)
58
- assert(AST::FunctionalCall === var)
59
- assert_equal("a", var.name)
60
- end
61
-
62
- def test_fields
63
- new_ast = AST.parse("@a = 1; @a").body
64
-
65
- assert_not_nil(new_ast)
66
- assert(AST::Body === new_ast)
67
- inspected = "Body\n FieldAssignment(a)\n Fixnum(1)\n Field(a)"
68
- assert_equal(inspected, new_ast.inspect)
69
-
70
- asgn = new_ast[0]
71
- var = new_ast[1]
72
-
73
- assert(AST::FieldAssignment === asgn)
74
- assert_equal("a", asgn.name)
75
- assert(AST::Fixnum === asgn.value)
76
- assert(AST::Field === var)
77
- assert_equal("a", var.name)
78
- end
79
-
80
- def test_array
81
- new_ast = AST.parse("[a = 1, 1]").body[0]
82
-
83
- assert_not_nil(new_ast)
84
- assert(AST::Array === new_ast)
85
- assert_equal("Array\n LocalAssignment(name = a, scope = Script, captured = false)\n Fixnum(1)\n Fixnum(1)", new_ast.inspect)
86
-
87
- assert(AST::LocalAssignment === new_ast[0])
88
- assert(AST::Fixnum === new_ast[1])
89
- end
90
-
91
- def test_call
92
- new_ast = AST.parse("1.foo(1)").body[0]
93
-
94
- assert_not_nil(new_ast)
95
- assert(AST::Call === new_ast)
96
- assert_equal("Call(foo)\n Fixnum(1)\n Fixnum(1)", new_ast.inspect)
97
-
98
- assert_equal("foo", new_ast.name)
99
- assert(AST::Fixnum === new_ast.target)
100
- assert_not_nil(new_ast.parameters)
101
- assert_equal(1, new_ast.parameters.size)
102
- assert(AST::Fixnum === new_ast.parameters[0])
103
- end
104
-
105
- def test_fcall
106
- new_ast = AST.parse("foo(1)").body[0]
107
-
108
- assert_not_nil(new_ast)
109
- assert(AST::FunctionalCall === new_ast)
110
- assert_equal("FunctionalCall(foo)\n Fixnum(1)", new_ast.inspect)
111
-
112
- assert_equal("foo", new_ast.name)
113
- assert_not_nil(new_ast.parameters)
114
- assert_equal(1, new_ast.parameters.size)
115
- assert(AST::Fixnum === new_ast.parameters[0])
116
- end
117
-
118
- def test_if
119
- new_ast = AST.parse("if 1; 2; elsif 3; 4; else; 5; end").body[0]
120
-
121
- assert_not_nil(new_ast)
122
- assert(AST::If === new_ast)
123
- assert_equal("If\n Condition\n Fixnum(1)\n Fixnum(2)\n If\n Condition\n Fixnum(3)\n Fixnum(4)\n Fixnum(5)", new_ast.inspect)
124
-
125
- assert(AST::Condition === new_ast.condition)
126
- assert(AST::Fixnum === new_ast.condition.predicate)
127
- assert(AST::Fixnum === new_ast.body)
128
- assert(AST::If === new_ast.else)
129
- assert(AST::Condition === new_ast.else.condition)
130
- assert(AST::Fixnum === new_ast.else.condition.predicate)
131
- assert(AST::Fixnum === new_ast.else.body)
132
- assert(AST::Fixnum === new_ast.else.else)
133
- end
134
-
135
- def test_begin
136
- new_ast = AST.parse("begin; 1; 2; end").body
137
-
138
- assert_not_nil(new_ast)
139
- assert_equal("Body\n Fixnum(1)\n Fixnum(2)", new_ast.inspect)
140
- assert(AST::Body === new_ast)
141
- assert(AST::Fixnum === new_ast[0])
142
-
143
- new_ast = AST.parse("begin; 1; end").body[0]
144
- assert(AST::Fixnum === new_ast)
145
- end
146
-
147
- def test_block
148
- new_ast = AST.parse("1; 2").body
149
-
150
- assert_not_nil(new_ast)
151
- assert_equal("Body\n Fixnum(1)\n Fixnum(2)", new_ast.inspect)
152
- assert(AST::Body === new_ast)
153
- assert(AST::Fixnum === new_ast[0])
154
-
155
- new_ast = AST.parse("1").body[0]
156
- assert(AST::Fixnum === new_ast)
157
- end
158
-
159
- def test_fixnum
160
- new_ast = AST.parse("1").body[0]
161
-
162
- assert_not_nil(new_ast)
163
- assert_equal("Fixnum(1)", new_ast.inspect)
164
- assert(AST::Fixnum === new_ast)
165
- assert_equal(1, new_ast.literal)
166
- end
167
-
168
- def test_float
169
- new_ast = AST.parse("1.0").body[0]
170
-
171
- assert_not_nil(new_ast)
172
- assert_equal("Float(1.0)", new_ast.inspect)
173
- assert(AST::Float === new_ast)
174
- assert_equal(1.0, new_ast.literal)
175
- end
176
-
177
- def test_class
178
- new_ast = AST.parse("class Foo < Bar; 1; 2; end").body[0]
179
-
180
- assert_not_nil(new_ast)
181
- assert_equal("ClassDefinition(Foo)\n Constant(Bar)\n Body\n Body\n Fixnum(1)\n Fixnum(2)", new_ast.inspect)
182
- assert(AST::ClassDefinition === new_ast)
183
- assert_equal("Foo", new_ast.name)
184
-
185
- assert(AST::Body === new_ast.body)
186
- assert(AST::Fixnum === new_ast.body[0][0])
187
-
188
- new_ast = AST.parse("class Foo < Bar; def foo; end; end").body[0]
189
-
190
- assert_not_nil(new_ast)
191
- assert_equal("ClassDefinition(Foo)\n Constant(Bar)\n Body\n MethodDefinition(foo)\n {:return=>nil}\n Arguments\n Null(nil)", new_ast.inspect)
192
- assert_equal(new_ast, new_ast.body.parent)
193
- end
194
-
195
- def test_defn
196
- new_ast = AST.parse("def foo(a, b); 1; end").body[0]
197
-
198
- assert_not_nil(new_ast)
199
- assert_equal("MethodDefinition(foo)\n {:return=>nil}\n Arguments\n RequiredArgument(a)\n RequiredArgument(b)\n Fixnum(1)", new_ast.inspect)
200
- assert(AST::MethodDefinition === new_ast)
201
- assert_equal("foo", new_ast.name)
202
- assert_not_nil(new_ast.signature)
203
- assert_equal(1, new_ast.signature.size)
204
- assert(nil === new_ast.signature[:return])
205
- assert(AST::Arguments === new_ast.arguments)
206
- assert(AST::Fixnum === new_ast.body)
207
-
208
- new_ast = AST.parse("def foo; end").body[0]
209
-
210
- assert_not_nil(new_ast)
211
- assert_equal("MethodDefinition(foo)\n {:return=>nil}\n Arguments\n Null(nil)", new_ast.inspect)
212
- assert_not_nil(new_ast.arguments)
213
- assert_equal([], new_ast.arguments.args)
214
- assert_equal(nil, new_ast.arguments.opt_args)
215
- assert_equal(nil, new_ast.arguments.rest_arg)
216
- assert_equal(nil, new_ast.arguments.block_arg)
217
-
218
- new_ast = AST.parse("def foo(a, b):int; 1; end").body[0]
219
- assert_equal("FunctionalCall(int)", new_ast.return_type.to_s)
220
- end
221
-
222
- def test_defs
223
- new_ast = AST.parse("def self.foo(a, b); 1; end").body[0]
224
-
225
- assert_not_nil(new_ast)
226
- inspected = "StaticMethodDefinition(foo)\n {:return=>nil}\n Arguments\n RequiredArgument(a)\n RequiredArgument(b)\n Fixnum(1)"
227
- assert_equal(inspected, new_ast.inspect)
228
- assert(AST::StaticMethodDefinition === new_ast)
229
- assert_equal("foo", new_ast.name)
230
- assert_not_nil(new_ast.signature)
231
- assert_equal(1, new_ast.signature.size)
232
- assert(nil === new_ast.signature[:return])
233
- assert(AST::Arguments === new_ast.arguments)
234
- assert(AST::Fixnum === new_ast.body)
235
-
236
- new_ast = AST.parse("def self.foo; end").body[0]
237
-
238
- assert_not_nil(new_ast)
239
- assert_equal("StaticMethodDefinition(foo)\n {:return=>nil}\n Arguments\n Null(nil)", new_ast.inspect)
240
- assert_not_nil(new_ast.arguments)
241
- assert_equal([], new_ast.arguments.args)
242
- assert_equal(nil, new_ast.arguments.opt_args)
243
- assert_equal(nil, new_ast.arguments.rest_arg)
244
- assert_equal(nil, new_ast.arguments.block_arg)
245
- end
246
-
247
- def test_return
248
- new_ast = AST.parse("return 1").body[0]
249
-
250
- assert_not_nil(new_ast)
251
- inspected = "Return\n Fixnum(1)"
252
- assert_equal(inspected, new_ast.inspect)
253
- assert(AST::Return === new_ast)
254
- assert(AST::Fixnum === new_ast.value)
255
- end
256
-
257
- def test_vcall
258
- new_ast = AST.parse("foo").body[0]
259
-
260
- assert_not_nil(new_ast)
261
- assert(AST::FunctionalCall === new_ast)
262
- assert_equal("FunctionalCall(foo)", new_ast.inspect)
263
-
264
- assert_equal("foo", new_ast.name)
265
- assert_not_nil(new_ast.parameters)
266
- assert_equal(0, new_ast.parameters.size)
267
- end
268
-
269
- def test_while
270
- new_ast = AST.parse("while 1; 2; end").body[0]
271
-
272
- assert_not_nil(new_ast)
273
- assert(AST::Loop === new_ast)
274
- assert_equal("Loop(check_first = true, negative = false)\n Body\n Condition\n Fixnum(1)\n Body\n Fixnum(2)\n Body", new_ast.inspect)
275
- assert(new_ast.check_first?)
276
- assert(!new_ast.negative?)
277
- assert(AST::Condition === new_ast.condition)
278
- assert(AST::Fixnum === new_ast.condition.predicate)
279
- assert(AST::Fixnum === new_ast.body)
280
-
281
- new_ast = AST.parse("begin; 2; end while 1").body[0]
282
-
283
- assert_not_nil(new_ast)
284
- assert(AST::Loop === new_ast)
285
- assert_equal("Loop(check_first = false, negative = false)\n Body\n Condition\n Fixnum(1)\n Body\n Fixnum(2)\n Body", new_ast.inspect)
286
- assert(!new_ast.check_first?)
287
- assert(!new_ast.negative?)
288
- assert(AST::Condition === new_ast.condition)
289
- assert(AST::Fixnum === new_ast.condition.predicate)
290
- assert(AST::Fixnum === new_ast.body)
291
- end
292
-
293
- def test_until
294
- new_ast = AST.parse("until 1; 2; end").body[0]
295
-
296
- assert_not_nil(new_ast)
297
- assert(AST::Loop === new_ast)
298
- assert_equal("Loop(check_first = true, negative = true)\n Body\n Condition\n Fixnum(1)\n Body\n Fixnum(2)\n Body", new_ast.inspect)
299
- assert(new_ast.check_first?)
300
- assert(new_ast.negative?)
301
- assert(AST::Condition === new_ast.condition)
302
- assert(AST::Fixnum === new_ast.condition.predicate)
303
- assert(AST::Fixnum === new_ast.body)
304
-
305
- new_ast = AST.parse("begin; 2; end until 1").body[0]
306
-
307
- assert_not_nil(new_ast)
308
- assert(AST::Loop === new_ast)
309
- assert_equal("Loop(check_first = false, negative = true)\n Body\n Condition\n Fixnum(1)\n Body\n Fixnum(2)\n Body", new_ast.inspect)
310
- assert(!new_ast.check_first?)
311
- assert(new_ast.negative?)
312
- assert(AST::Condition === new_ast.condition)
313
- assert(AST::Fixnum === new_ast.condition.predicate)
314
- assert(AST::Fixnum === new_ast.body)
315
- end
316
-
317
- def test_string
318
- new_ast = AST.parse("'foo'").body[0]
319
-
320
- assert_not_nil(new_ast)
321
- assert(AST::String === new_ast)
322
- assert_equal("String(\"foo\")", new_ast.inspect)
323
- assert_equal("foo", new_ast.literal)
324
- end
325
-
326
- def test_root
327
- new_ast = AST.parse("1").body[0]
328
-
329
- assert_not_nil(new_ast)
330
- assert(AST::Fixnum === new_ast)
331
- end
332
-
333
- def test_boolean
334
- new_ast1 = AST.parse("true").body[0]
335
- new_ast2 = AST.parse("false").body[0]
336
-
337
- assert_not_nil(new_ast1)
338
- assert_not_nil(new_ast2)
339
- assert(AST::Boolean === new_ast1)
340
- assert(AST::Boolean === new_ast2)
341
- assert(new_ast1.literal)
342
- assert(!new_ast2.literal)
343
- end
344
-
345
- def test_return
346
- new_ast = AST.parse("return 1").body[0]
347
-
348
- assert_not_nil(new_ast)
349
- assert(AST::Return === new_ast)
350
- assert(AST::Fixnum === new_ast.value)
351
- assert(1, new_ast.value.literal)
352
- end
353
-
354
- def test_empty_array
355
- new_ast = AST.parse("int[5]").body[0]
356
-
357
- assert_not_nil(new_ast)
358
- assert(AST::EmptyArray === new_ast)
359
- assert_equal(5, new_ast.size.literal)
360
-
361
- assert_equal("int", new_ast.type_node.name)
362
- end
363
-
364
- def test_block_comment
365
- new_ast = AST.parse("/* foo\nbar*/1").body[0]
366
-
367
- assert_not_nil(new_ast)
368
- assert_equal("Fixnum(1)", new_ast.inspect)
369
- assert(AST::Fixnum === new_ast)
370
- assert_equal(1, new_ast.literal)
371
- end
372
-
373
- def test_incorrect_syntax_raises_syntax_error
374
- assert_raises SyntaxError do
375
- AST.parse("puts( 'aoue'")
376
- end
377
- end
378
-
379
- def test_parsing_empty_string_raises_no_error
380
- AST.parse("")
381
- end
382
- end