mirah 0.0.12-java → 0.1.0-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 (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