duby 0.0.1

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 (69) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +68 -0
  3. data/README.txt +31 -0
  4. data/Rakefile +37 -0
  5. data/bin/duby +9 -0
  6. data/bin/dubyc +9 -0
  7. data/bin/dubyp +9 -0
  8. data/examples/appengine/src/com/google/appengine/ext/duby/db/Model.duby +132 -0
  9. data/examples/appengine/src/com/ribrdb/DubyApp.duby +28 -0
  10. data/examples/bench_fractal.duby +57 -0
  11. data/examples/construction.duby +8 -0
  12. data/examples/edb.duby +3 -0
  13. data/examples/fib.duby +24 -0
  14. data/examples/fields.duby +22 -0
  15. data/examples/java_thing.duby +13 -0
  16. data/examples/simple_class.duby +12 -0
  17. data/examples/swing.duby +20 -0
  18. data/examples/tak.duby +15 -0
  19. data/javalib/JRubyParser.jar +0 -0
  20. data/lib/duby.rb +170 -0
  21. data/lib/duby/ast.rb +340 -0
  22. data/lib/duby/ast/call.rb +73 -0
  23. data/lib/duby/ast/class.rb +145 -0
  24. data/lib/duby/ast/flow.rb +328 -0
  25. data/lib/duby/ast/intrinsics.rb +46 -0
  26. data/lib/duby/ast/literal.rb +93 -0
  27. data/lib/duby/ast/local.rb +77 -0
  28. data/lib/duby/ast/method.rb +187 -0
  29. data/lib/duby/ast/structure.rb +44 -0
  30. data/lib/duby/ast/type.rb +93 -0
  31. data/lib/duby/c/compiler.rb +134 -0
  32. data/lib/duby/compiler.rb +261 -0
  33. data/lib/duby/jvm/compiler.rb +684 -0
  34. data/lib/duby/jvm/method_lookup.rb +185 -0
  35. data/lib/duby/jvm/source_compiler.rb +516 -0
  36. data/lib/duby/jvm/source_generator/builder.rb +368 -0
  37. data/lib/duby/jvm/source_generator/loops.rb +132 -0
  38. data/lib/duby/jvm/source_generator/precompile.rb +154 -0
  39. data/lib/duby/jvm/source_generator/typer.rb +11 -0
  40. data/lib/duby/jvm/typer.rb +118 -0
  41. data/lib/duby/jvm/types.rb +326 -0
  42. data/lib/duby/jvm/types/basic_types.rb +18 -0
  43. data/lib/duby/jvm/types/boolean.rb +11 -0
  44. data/lib/duby/jvm/types/factory.rb +151 -0
  45. data/lib/duby/jvm/types/floats.rb +70 -0
  46. data/lib/duby/jvm/types/integers.rb +110 -0
  47. data/lib/duby/jvm/types/intrinsics.rb +157 -0
  48. data/lib/duby/jvm/types/literals.rb +82 -0
  49. data/lib/duby/jvm/types/methods.rb +344 -0
  50. data/lib/duby/jvm/types/number.rb +92 -0
  51. data/lib/duby/nbcompiler.rb +29 -0
  52. data/lib/duby/old/compiler_old.rb +845 -0
  53. data/lib/duby/old/declaration.rb +72 -0
  54. data/lib/duby/old/mapper.rb +72 -0
  55. data/lib/duby/old/signature.rb +52 -0
  56. data/lib/duby/old/typer_old.rb +163 -0
  57. data/lib/duby/plugin/edb.rb +25 -0
  58. data/lib/duby/plugin/java.rb +42 -0
  59. data/lib/duby/plugin/math.rb +84 -0
  60. data/lib/duby/transform.rb +908 -0
  61. data/lib/duby/typer.rb +359 -0
  62. data/test/test_ast.rb +391 -0
  63. data/test/test_compilation.rb +98 -0
  64. data/test/test_java_typer.rb +199 -0
  65. data/test/test_javac_compiler.rb +57 -0
  66. data/test/test_jvm_compiler.rb +1459 -0
  67. data/test/test_math_plugin.rb +87 -0
  68. data/test/test_typer.rb +246 -0
  69. metadata +155 -0
@@ -0,0 +1,73 @@
1
+ module Duby::AST
2
+ class FunctionalCall < Node
3
+ include Named
4
+ attr_accessor :parameters, :block, :cast
5
+ alias cast? cast
6
+
7
+ def initialize(parent, line_number, name, &kids)
8
+ super(parent, line_number, &kids)
9
+ @parameters, @block = children
10
+ @name = name
11
+ @cast = false
12
+ end
13
+
14
+ def infer(typer)
15
+ @self_type ||= typer.self_type
16
+
17
+ unless @inferred_type
18
+ receiver_type = @self_type
19
+ should_defer = false
20
+
21
+ parameter_types = parameters.map do |param|
22
+ typer.infer(param) || should_defer = true
23
+ end
24
+
25
+ unless should_defer
26
+ if parameters.size == 1 && typer.known_types[name]
27
+ # cast operation
28
+ resolved!
29
+ self.cast = true
30
+ @inferred_type = typer.known_types[name]
31
+ else
32
+ @inferred_type = typer.method_type(receiver_type, name,
33
+ parameter_types)
34
+ end
35
+ end
36
+
37
+ @inferred_type ? resolved! : typer.defer(self)
38
+ end
39
+
40
+ @inferred_type
41
+ end
42
+ end
43
+
44
+ class Call < Node
45
+ include Named
46
+ attr_accessor :target, :parameters, :block
47
+
48
+ def initialize(parent, line_number, name, &kids)
49
+ super(parent, line_number, children, &kids)
50
+ @target, @parameters, @block = children
51
+ @name = name
52
+ end
53
+
54
+ def infer(typer)
55
+ unless @inferred_type
56
+ receiver_type = typer.infer(target)
57
+ should_defer = false
58
+ parameter_types = parameters.map do |param|
59
+ typer.infer(param) || should_defer = true
60
+ end
61
+
62
+ unless should_defer
63
+ @inferred_type = typer.method_type(receiver_type, name,
64
+ parameter_types)
65
+ end
66
+
67
+ @inferred_type ? resolved! : typer.defer(self)
68
+ end
69
+
70
+ @inferred_type
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,145 @@
1
+ module Duby::AST
2
+ class ClassDefinition < Node
3
+ include Named
4
+ include Scope
5
+ attr_accessor :superclass, :body, :interfaces
6
+
7
+ def initialize(parent, line_number, name, &block)
8
+ @interfaces = []
9
+ @name = name
10
+ if Duby::AST.type_factory.respond_to? :declare_type
11
+ Duby::AST.type_factory.declare_type(self)
12
+ end
13
+ super(parent, line_number, &block)
14
+ @superclass, @body = children
15
+ end
16
+
17
+ def infer(typer)
18
+ unless resolved?
19
+ @inferred_type ||= typer.define_type(name, superclass, @interfaces) do
20
+ if body
21
+ typer.infer(body)
22
+ else
23
+ typer.no_type
24
+ end
25
+ end
26
+ @inferred_type ? resolved! : typer.defer(self)
27
+ end
28
+
29
+ @inferred_type
30
+ end
31
+
32
+ def implements(*types)
33
+ raise ArgumentError if types.any? {|x| x.nil?}
34
+ @interfaces.concat types
35
+ end
36
+ end
37
+
38
+ defmacro('implements') do |transformer, fcall, parent|
39
+ interfaces = fcall.args_node.child_nodes.map do |interface|
40
+ interface.type_reference(parent)
41
+ end
42
+ parent.parent.implements(*interfaces)
43
+ Noop.new(parent, fcall.position)
44
+ end
45
+
46
+ class InterfaceDeclaration < ClassDefinition
47
+ attr_accessor :superclass, :body, :interfaces
48
+
49
+ def initialize(parent, line_number, name)
50
+ super(parent, line_number, name) {|p| }
51
+ @interfaces = []
52
+ @name = name
53
+ @children = yield(self)
54
+ @interfaces, @body = children
55
+ end
56
+ end
57
+
58
+ defmacro('interface') do |transformer, fcall, parent|
59
+ raise "Interface name required" unless fcall.args_node
60
+ interfaces = fcall.args_node.child_nodes.to_a
61
+ interface_name = interfaces.shift
62
+ if (JRubyAst::CallNode === interface_name &&
63
+ interface_name.args_node.size == 1)
64
+ interfaces.unshift(interface_name.args_node.get(0))
65
+ interface_name = interface_name.receiver_node
66
+ end
67
+ raise 'Interface body required' unless fcall.iter_node
68
+ InterfaceDeclaration.new(parent, fcall.position,
69
+ interface_name.name) do |interface|
70
+ [interfaces.map {|p| p.type_reference(interface)},
71
+ if fcall.iter_node.body_node
72
+ transformer.transform(fcall.iter_node.body_node, interface)
73
+ end
74
+ ]
75
+ end
76
+ end
77
+
78
+ class FieldDeclaration < Node
79
+ include Named
80
+ include ClassScoped
81
+ include Typed
82
+
83
+ def initialize(parent, line_number, name, &block)
84
+ super(parent, line_number, &block)
85
+ @name = name
86
+ @type = children[0]
87
+ end
88
+
89
+ def infer(typer)
90
+ unless resolved?
91
+ resolved!
92
+ @inferred_type = typer.known_types[type]
93
+ if @inferred_type
94
+ resolved!
95
+ typer.learn_field_type(scope, name, @inferred_type)
96
+ else
97
+ typer.defer(self)
98
+ end
99
+ end
100
+ @inferred_type
101
+ end
102
+ end
103
+
104
+ class FieldAssignment < Node
105
+ include Named
106
+ include Valued
107
+ include ClassScoped
108
+
109
+ def initialize(parent, line_number, name, &block)
110
+ super(parent, line_number, &block)
111
+ @value = children[0]
112
+ @name = name
113
+ end
114
+
115
+ def infer(typer)
116
+ unless resolved?
117
+ @inferred_type = typer.learn_field_type(scope, name, typer.infer(value))
118
+
119
+ @inferred_type ? resolved! : typer.defer(self)
120
+ end
121
+
122
+ @inferred_type
123
+ end
124
+ end
125
+
126
+ class Field < Node
127
+ include Named
128
+ include ClassScoped
129
+
130
+ def initialize(parent, line_number, name, &block)
131
+ super(parent, line_number, &block)
132
+ @name = name
133
+ end
134
+
135
+ def infer(typer)
136
+ unless resolved?
137
+ @inferred_type = typer.field_type(scope, name)
138
+
139
+ @inferred_type ? resolved! : typer.defer(self)
140
+ end
141
+
142
+ @inferred_type
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,328 @@
1
+ module Duby
2
+ module AST
3
+ class Condition < Node
4
+ attr_accessor :predicate
5
+
6
+ def initialize(parent, line_number, &block)
7
+ super(parent, line_number, &block)
8
+ @predicate = children[0]
9
+ end
10
+
11
+ def infer(typer)
12
+ unless resolved?
13
+ @inferred_type = typer.infer(predicate)
14
+ if @inferred_type && !@inferred_type.primitive?
15
+ call = Call.new(parent, position, '!=') do |call|
16
+ @predicate.parent = call
17
+ [@predicate, [Null.new(call, position)]]
18
+ end
19
+ @predicate = children[0] = call
20
+ @inferred_type = typer.infer(predicate)
21
+ end
22
+
23
+ @inferred_type ? resolved! : typer.defer(self)
24
+ end
25
+
26
+ @inferred_type
27
+ end
28
+ end
29
+
30
+ class If < Node
31
+ attr_accessor :condition, :body, :else
32
+
33
+ def initialize(parent, line_number, &block)
34
+ super(parent, line_number, &block)
35
+ @condition, @body, @else = children
36
+ end
37
+
38
+ def infer(typer)
39
+ unless resolved?
40
+ condition_type = typer.infer(condition)
41
+ unless condition_type
42
+ typer.defer(condition)
43
+ end
44
+
45
+ # condition type is unrelated to body types, so we proceed with bodies
46
+ then_type = typer.infer(body) if body
47
+
48
+ if !then_type
49
+ # attempt to determine else branch
50
+ if self.else
51
+ else_type = typer.infer(self.else)
52
+
53
+ if !else_type
54
+ # we have neither type, defer until later
55
+ typer.defer(self)
56
+ else
57
+ # we have else but not then, defer only then and use else type for now
58
+ @inferred_type = else_type
59
+ typer.defer(self)
60
+ end
61
+ else
62
+ # no then type could be inferred and no else body, defer for now
63
+ typer.defer(self)
64
+ end
65
+ else
66
+ if self.else
67
+ else_type = typer.infer(self.else)
68
+
69
+ if !else_type
70
+ # we determined a then type, so we use that and defer the else body
71
+ @inferred_type = then_type
72
+ typer.defer(self)
73
+ else
74
+ # both then and else inferred, ensure they're compatible
75
+ if then_type.compatible?(else_type)
76
+ # types are compatible...if condition is resolved, we're done
77
+ @inferred_type = then_type.narrow(else_type)
78
+ resolved! if condition_type
79
+ else
80
+ raise Typer::InferenceError.new("if statement with incompatible result types")
81
+ end
82
+ end
83
+ else
84
+ # only then and type inferred, we're 100% resolved
85
+ @inferred_type = then_type
86
+ resolved! if condition_type
87
+ end
88
+ end
89
+ end
90
+
91
+ @inferred_type
92
+ end
93
+ end
94
+
95
+ class Loop < Node
96
+ attr_accessor :redo
97
+
98
+ def infer(typer)
99
+ unless resolved?
100
+ child_types = children.map {|c| typer.infer(c)}
101
+ if child_types.any? {|t| t.nil?}
102
+ typer.defer(self)
103
+ else
104
+ resolved!
105
+ @inferred_type = typer.null_type
106
+ end
107
+ end
108
+
109
+ @inferred_type
110
+ end
111
+ end
112
+
113
+ class WhileLoop < Loop
114
+ attr_accessor :condition, :body, :check_first, :negative
115
+
116
+ def initialize(parent, line_number, check_first, negative, &block)
117
+ super(parent, line_number, &block)
118
+ @condition, @body = children
119
+ @check_first = check_first
120
+ @negative = negative
121
+ end
122
+
123
+ def check_first?; @check_first; end
124
+ def negative?; @negative; end
125
+ def has_redo?; @redo; end
126
+
127
+ def to_s
128
+ "WhileLoop(check_first = #{check_first?}, negative = #{negative?})"
129
+ end
130
+ end
131
+
132
+ class ForLoop < Loop
133
+ attr_reader :name, :body, :iter
134
+
135
+ def initialize(parent, position, &block)
136
+ super(parent, position, &block)
137
+ var = children.shift
138
+ @body, @iter = children
139
+ @scope = var.scope
140
+ @name = var.name
141
+ end
142
+
143
+ def infer(typer)
144
+ super
145
+ iter_type = @iter.inferred_type
146
+ if iter_type
147
+ if !iter_type.iterable?
148
+ raise "#{iter_type} is not iterable."
149
+ end
150
+ typer.learn_local_type(@scope, name, iter_type.component_type)
151
+ end
152
+ @inferred_type
153
+ end
154
+ end
155
+
156
+ class Not < Node
157
+ def initialize(parent, line_number, &block)
158
+ super(parent, line_number, &block)
159
+ end
160
+ end
161
+
162
+ class JumpNode < Node
163
+ attr_accessor :ensures
164
+
165
+ def initialize(parent, line_number, ensures, &block)
166
+ super(parent, line_number, &block)
167
+ @ensures = ensures
168
+ end
169
+ end
170
+
171
+ class Return < JumpNode
172
+ include Valued
173
+
174
+ def initialize(parent, line_number, ensures, &block)
175
+ super(parent, line_number, ensures, &block)
176
+ @value = children[0]
177
+ end
178
+
179
+ def infer(typer)
180
+ unless resolved?
181
+ @inferred_type = typer.infer(value)
182
+
183
+ (@inferred_type && value.resolved?) ? resolved! : typer.defer(self)
184
+ end
185
+
186
+ @inferred_type
187
+ end
188
+ end
189
+
190
+ class Break < JumpNode;
191
+ def infer(typer)
192
+ unless resolved?
193
+ resolved!
194
+ @inferred_type = typer.null_type
195
+ end
196
+ end
197
+ end
198
+
199
+ class Next < Break; end
200
+
201
+ class Redo < Break; end
202
+
203
+ class Raise < Node
204
+ include Valued
205
+
206
+ def initialize(parent, line_number, &block)
207
+ super(parent, line_number, &block)
208
+ end
209
+
210
+ def infer(typer)
211
+ unless resolved?
212
+ @inferred_type = AST.unreachable_type
213
+ throwable = AST.type('java.lang.Throwable')
214
+ if children.size == 1
215
+ arg_type = typer.infer(children[0])
216
+ unless arg_type
217
+ typer.defer(self)
218
+ return
219
+ end
220
+ if throwable.assignable_from?(arg_type) && !arg_type.meta?
221
+ @exception = children[0]
222
+ resolved!
223
+ return @inferred_type
224
+ end
225
+ end
226
+
227
+ arg_types = children.map {|c| typer.infer(c)}
228
+ if arg_types.any? {|c| c.nil?}
229
+ typer.defer(self)
230
+ else
231
+ if arg_types[0] && throwable.assignable_from?(arg_types[0])
232
+ klass = children.shift
233
+ else
234
+ klass = Constant.new(self, position, 'RuntimeException')
235
+ end
236
+ @exception = Call.new(self, position, 'new') do
237
+ [klass, children, nil]
238
+ end
239
+ resolved!
240
+ @children = [@exception]
241
+ typer.infer(@exception)
242
+ end
243
+ end
244
+ @inferred_type
245
+ end
246
+ end
247
+
248
+ defmacro('raise') do |transformer, fcall, parent|
249
+ Raise.new(parent, fcall.position) do |raise_node|
250
+ if fcall.args_node
251
+ fcall.args_node.child_nodes.map do |arg|
252
+ transformer.transform(arg, raise_node)
253
+ end
254
+ end
255
+ end
256
+ end
257
+
258
+ class RescueClause < Node
259
+ include Scoped
260
+ attr_accessor :types, :body, :name, :type
261
+
262
+ def initialize(parent, position, &block)
263
+ super(parent, position, &block)
264
+ @types, @body = children
265
+ end
266
+
267
+ def infer(typer)
268
+ unless resolved?
269
+ if name
270
+ orig_type = typer.local_type(scope, name)
271
+ # TODO find the common parent Throwable
272
+ @type = types.size == 1 ? types[0] : AST.type('java.lang.Throwable')
273
+ typer.learn_local_type(scope, name, @type)
274
+ end
275
+ @inferred_type = typer.infer(body)
276
+
277
+ (@inferred_type && body.resolved?) ? resolved! : typer.defer(self)
278
+ typer.local_type_hash(scope)[name] = orig_type if name
279
+ end
280
+
281
+ @inferred_type
282
+ end
283
+ end
284
+
285
+ class Rescue < Node
286
+ attr_accessor :body, :clauses
287
+ def initialize(parent, position, &block)
288
+ super(parent, position, &block)
289
+ @body, @clauses = children
290
+ end
291
+
292
+ def infer(typer)
293
+ unless resolved?
294
+ types = [typer.infer(body)] + clauses.map {|c| typer.infer(c)}
295
+ if types.any? {|t| t.nil?}
296
+ typer.defer(self)
297
+ else
298
+ # TODO check types for compatibility (maybe only if an expression)
299
+ resolved!
300
+ @inferred_type = types[0]
301
+ end
302
+ end
303
+ @inferred_type
304
+ end
305
+ end
306
+
307
+ class Ensure < Node
308
+ attr_reader :body, :clause
309
+ attr_accessor :state # Used by the some compilers.
310
+
311
+ def initialize(parent, position, &block)
312
+ super(parent, position, &block)
313
+ @body, @clause = children
314
+ end
315
+
316
+ def infer(typer)
317
+ resolve_if(typer) do
318
+ typer.infer(clause)
319
+ typer.infer(body)
320
+ end
321
+ end
322
+
323
+ def ensures
324
+ [self]
325
+ end
326
+ end
327
+ end
328
+ end