duby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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