duby 0.0.2-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 (77) hide show
  1. data/History.txt +8 -0
  2. data/README.txt +39 -0
  3. data/Rakefile +13 -0
  4. data/bin/duby +9 -0
  5. data/bin/dubyc +9 -0
  6. data/bin/dubyp +9 -0
  7. data/examples/README +16 -0
  8. data/examples/appengine/Rakefile +72 -0
  9. data/examples/appengine/Readme +27 -0
  10. data/examples/appengine/config.ru +7 -0
  11. data/examples/appengine/lib/duby/plugin/datastore.rb +171 -0
  12. data/examples/appengine/src/com/google/appengine/ext/duby/db/Model.duby +132 -0
  13. data/examples/appengine/src/com/ribrdb/DubyApp.duby +28 -0
  14. data/examples/appengine/src/com/ribrdb/list.dhtml +15 -0
  15. data/examples/construction.duby +8 -0
  16. data/examples/edb.duby +3 -0
  17. data/examples/fib.duby +24 -0
  18. data/examples/fields.duby +22 -0
  19. data/examples/fractal.duby +57 -0
  20. data/examples/java_thing.duby +13 -0
  21. data/examples/simple_class.duby +12 -0
  22. data/examples/swing.duby +20 -0
  23. data/examples/tak.duby +15 -0
  24. data/examples/test.edb +9 -0
  25. data/javalib/JRubyParser.jar +0 -0
  26. data/lib/duby.rb +168 -0
  27. data/lib/duby/ast.rb +386 -0
  28. data/lib/duby/ast/call.rb +145 -0
  29. data/lib/duby/ast/class.rb +154 -0
  30. data/lib/duby/ast/flow.rb +332 -0
  31. data/lib/duby/ast/intrinsics.rb +56 -0
  32. data/lib/duby/ast/literal.rb +97 -0
  33. data/lib/duby/ast/local.rb +92 -0
  34. data/lib/duby/ast/method.rb +244 -0
  35. data/lib/duby/ast/structure.rb +62 -0
  36. data/lib/duby/ast/type.rb +93 -0
  37. data/lib/duby/c/compiler.rb +134 -0
  38. data/lib/duby/compiler.rb +282 -0
  39. data/lib/duby/jvm/compiler.rb +766 -0
  40. data/lib/duby/jvm/method_lookup.rb +193 -0
  41. data/lib/duby/jvm/source_compiler.rb +605 -0
  42. data/lib/duby/jvm/source_generator/builder.rb +387 -0
  43. data/lib/duby/jvm/source_generator/loops.rb +110 -0
  44. data/lib/duby/jvm/source_generator/precompile.rb +170 -0
  45. data/lib/duby/jvm/source_generator/typer.rb +11 -0
  46. data/lib/duby/jvm/typer.rb +131 -0
  47. data/lib/duby/jvm/types.rb +331 -0
  48. data/lib/duby/jvm/types/basic_types.rb +19 -0
  49. data/lib/duby/jvm/types/boolean.rb +11 -0
  50. data/lib/duby/jvm/types/enumerable.rb +63 -0
  51. data/lib/duby/jvm/types/factory.rb +155 -0
  52. data/lib/duby/jvm/types/floats.rb +70 -0
  53. data/lib/duby/jvm/types/integers.rb +110 -0
  54. data/lib/duby/jvm/types/intrinsics.rb +230 -0
  55. data/lib/duby/jvm/types/literals.rb +82 -0
  56. data/lib/duby/jvm/types/methods.rb +381 -0
  57. data/lib/duby/jvm/types/number.rb +92 -0
  58. data/lib/duby/nbcompiler.rb +29 -0
  59. data/lib/duby/old/compiler_old.rb +845 -0
  60. data/lib/duby/old/declaration.rb +72 -0
  61. data/lib/duby/old/mapper.rb +72 -0
  62. data/lib/duby/old/signature.rb +52 -0
  63. data/lib/duby/old/typer_old.rb +163 -0
  64. data/lib/duby/plugin/edb.rb +25 -0
  65. data/lib/duby/plugin/java.rb +42 -0
  66. data/lib/duby/plugin/math.rb +84 -0
  67. data/lib/duby/transform.rb +1028 -0
  68. data/lib/duby/typer.rb +369 -0
  69. data/test/TestUser.class +0 -0
  70. data/test/test_ast.rb +391 -0
  71. data/test/test_compilation.rb +98 -0
  72. data/test/test_java_typer.rb +199 -0
  73. data/test/test_javac_compiler.rb +58 -0
  74. data/test/test_jvm_compiler.rb +1770 -0
  75. data/test/test_math_plugin.rb +87 -0
  76. data/test/test_typer.rb +246 -0
  77. metadata +156 -0
@@ -0,0 +1,170 @@
1
+ require 'duby/ast'
2
+
3
+ module Duby::AST
4
+ class TempValue
5
+ def initialize(node, compiler=nil, value=nil)
6
+ if compiler.nil?
7
+ @tempname = node
8
+ else
9
+ @tempname = compiler.temp(node, value)
10
+ @tempvalue = value || node
11
+ end
12
+ end
13
+
14
+ def compile(compiler, expression)
15
+ if expression
16
+ compiler.method.print @tempname
17
+ end
18
+ end
19
+
20
+ def reload(compiler)
21
+ compiler.assign(@tempname, @tempvalue)
22
+ end
23
+ end
24
+
25
+ class Node
26
+ def expr?(compiler)
27
+ true
28
+ end
29
+
30
+ def precompile(compiler)
31
+ if expr?(compiler)
32
+ self
33
+ else
34
+ temp(compiler)
35
+ end
36
+ end
37
+
38
+ def temp(compiler, value=nil)
39
+ TempValue.new(self, compiler, value)
40
+ end
41
+ end
42
+
43
+ class Body
44
+ def expr?(compiler)
45
+ false
46
+ end
47
+ end
48
+
49
+ class If
50
+ def expr?(compiler)
51
+ return false unless condition.predicate.expr?(compiler)
52
+ return false unless body.nil? || body.expr?(compiler)
53
+ return false unless self.else.nil? || self.else.expr?(compiler)
54
+ true
55
+ end
56
+ end
57
+
58
+ class Loop
59
+ def expr?(compiler)
60
+ false
61
+ end
62
+
63
+ def precompile(compiler)
64
+ compile(compiler, false)
65
+ temp(compiler, 'null')
66
+ end
67
+ end
68
+
69
+ class Call
70
+ def method(compiler=nil)
71
+ @method ||= begin
72
+ arg_types = parameters.map {|p| p.inferred_type}
73
+ target.inferred_type.get_method(name, arg_types)
74
+ end
75
+ end
76
+
77
+ def expr?(compiler)
78
+ target.expr?(compiler) &&
79
+ parameters.all? {|p| p.expr?(compiler)} &&
80
+ !method.return_type.kind_of?(Duby::AST::InlineCode) &&
81
+ !method.actual_return_type.void?
82
+ end
83
+ end
84
+
85
+ class FunctionalCall
86
+ def method(compiler)
87
+ @method ||= begin
88
+ arg_types = parameters.map {|p| p.inferred_type}
89
+ compiler.self_type.get_method(name, arg_types)
90
+ end
91
+ end
92
+
93
+ def expr?(compiler)
94
+ parameters.all? {|p| p.expr?(compiler)} &&
95
+ (cast? || !method(compiler).actual_return_type.void?)
96
+ end
97
+ end
98
+
99
+ # TODO merge with FunctionalCall logic (almost identical)
100
+ class Super
101
+ def method(compiler)
102
+ @method ||= begin
103
+ arg_types = parameters.map {|p| p.inferred_type}
104
+ compiler.self_type.superclass.get_method(name, arg_types)
105
+ end
106
+ end
107
+
108
+ def expr?(compiler)
109
+ parameters.all? {|p| p.expr?(compiler)} &&
110
+ !method(compiler).actual_return_type.void?
111
+ end
112
+ end
113
+
114
+ class EmtpyArray
115
+ def expr?(compiler)
116
+ size.expr?(compiler)
117
+ end
118
+ end
119
+
120
+ class LocalAssignment
121
+ def expr?(compiler)
122
+ compiler.method.local?(name) && value.expr?(compiler)
123
+ end
124
+
125
+ def precompile(compiler)
126
+ if expr?(compiler)
127
+ self
128
+ else
129
+ compile(compiler, false)
130
+ TempValue.new(name)
131
+ end
132
+ end
133
+ end
134
+
135
+ class Return
136
+ def expr?(compiler)
137
+ false
138
+ end
139
+ end
140
+
141
+ class Raise
142
+ def expr?(compiler)
143
+ false
144
+ end
145
+ end
146
+
147
+ class Rescue
148
+ def expr?(compiler)
149
+ false
150
+ end
151
+ end
152
+
153
+ class Ensure
154
+ def expr?(compiler)
155
+ false
156
+ end
157
+ end
158
+
159
+ class FieldAssignment
160
+ def expr?(compiler)
161
+ false
162
+ end
163
+ end
164
+
165
+ class LocalAssignment
166
+ def expr?(compiler)
167
+ false
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,11 @@
1
+ require 'duby/jvm/typer'
2
+ require 'duby/jvm/source_generator/builder'
3
+
4
+ module Duby
5
+ module Typer
6
+ class JavaSource < JVM
7
+ include Duby::JVM::Types
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,131 @@
1
+ require 'duby/typer'
2
+ require 'duby/jvm/types'
3
+ require 'duby/jvm/types/factory'
4
+
5
+ module Duby
6
+ module Typer
7
+ class JVM < Simple
8
+ include Duby::JVM::Types
9
+
10
+ attr_reader :transformer
11
+
12
+ def initialize(filename, transformer)
13
+ @factory = AST.type_factory
14
+ @transformer = transformer
15
+ unless @factory.kind_of? TypeFactory
16
+ raise "TypeFactory not installed"
17
+ end
18
+ @known_types = @factory.known_types
19
+ classname = File.basename(filename, '.duby')
20
+ main_class = @factory.declare_type(classname)
21
+ @known_types['self'] = main_class.meta
22
+ @errors = []
23
+ end
24
+
25
+ def type_reference(name, array=false, meta=false)
26
+ @factory.type(name, array, meta)
27
+ end
28
+
29
+ def alias_types(short, long)
30
+ @known_types[short] = type_reference(long)
31
+ end
32
+
33
+ def name
34
+ "JVM"
35
+ end
36
+
37
+ def type_definition(name, superclass, interfaces)
38
+ @known_types[name]
39
+ end
40
+
41
+ def null_type
42
+ Null
43
+ end
44
+
45
+ def no_type
46
+ Void
47
+ end
48
+
49
+ def array_type
50
+ # TODO: allow other types for pre-1.2 profiles
51
+ type_reference("java.util.List")
52
+ end
53
+
54
+ def hash_type
55
+ # TODO: allow other types for pre-1.2 profiles
56
+ type_reference("java.util.Map")
57
+ end
58
+
59
+ def learn_method_type(target_type, name, parameter_types, type, exceptions)
60
+ static = target_type.meta?
61
+ unless target_type.unmeta.kind_of?(TypeDefinition)
62
+ raise "Method defined on #{target_type}"
63
+ end
64
+ if static
65
+ target_type.unmeta.declare_static_method(name, parameter_types, type, exceptions)
66
+ else
67
+ target_type.declare_method(name, parameter_types, type, exceptions)
68
+ end
69
+ super
70
+ end
71
+
72
+ def infer_signature(method_def)
73
+ signature = method_def.signature
74
+ sig_args = signature.dup
75
+ return_type = sig_args.delete(:return)
76
+ exceptions = sig_args.delete(:throws)
77
+ args = method_def.arguments.args || []
78
+ static = method_def.kind_of? Duby::AST::StaticMethodDefinition
79
+ if sig_args.size != args.size
80
+ # If the superclass declares one method with the same name and
81
+ # same number of arguments, assume we're overriding it.
82
+ found = nil
83
+ ambiguous = false
84
+ classes = [self_type.superclass] + self_type.interfaces
85
+ while classes.size > 0
86
+ cls = classes.pop
87
+ if static
88
+ methods = cls.declared_class_methods
89
+ else
90
+ methods = cls.declared_instance_methods
91
+ end
92
+ methods.each do |method|
93
+ if method.name == method_def.name &&
94
+ method.argument_types.size == args.size
95
+ if found && found.argument_types != method.argument_types
96
+ ambiguous = true
97
+ else
98
+ found ||= method
99
+ end
100
+ end
101
+ end
102
+ classes << cls.superclass if cls.superclass
103
+ end
104
+ if found && !ambiguous
105
+ signature[:return] = found.actual_return_type
106
+ signature[:throws] = found.exceptions
107
+ args.zip(found.argument_types) do |arg, type|
108
+ signature[arg.name.intern] = type
109
+ end
110
+ end
111
+ elsif signature[:return].nil? && !static
112
+ arg_types = args.map do |arg|
113
+ signature[arg.name.intern]
114
+ end
115
+ method = self_type.find_method(
116
+ self_type, method_def.name, arg_types, false)
117
+ interfaces = self_type.interfaces.dup
118
+ until method || interfaces.empty?
119
+ interface = interfaces.pop
120
+ method = interface.find_method(
121
+ interface, method_def.name, arg_types, false)
122
+ end
123
+ if method
124
+ signature[:return] = method.actual_return_type
125
+ signature[:throws] = method.exceptions
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,331 @@
1
+ require 'bitescript'
2
+ require 'duby/ast'
3
+ require 'duby/jvm/method_lookup'
4
+ require 'duby/jvm/compiler'
5
+
6
+ class Object
7
+ def class_builder?
8
+ self.class.name =~ /::ClassBuilder$/
9
+ end
10
+ end
11
+
12
+ module Duby
13
+ module JVM
14
+ module Types
15
+ class Type < AST::TypeReference
16
+ include Duby::JVM::MethodLookup
17
+
18
+ def log(message)
19
+ puts "* [JVM::Types] #{message}" if Duby::Compiler::JVM.verbose
20
+ end
21
+
22
+ def initialize(java_type)
23
+ orig_type = java_type
24
+ if !(java_type.kind_of?(Java::JavaClass) ||
25
+ java_type.class_builder?)
26
+ java_type = java_type.java_class
27
+ end
28
+ super(java_type.name, false, false)
29
+ raise ArgumentError, "Bad type #{orig_type}" if name =~ /Java::/
30
+ @type = java_type
31
+ end
32
+
33
+ def jvm_type
34
+ @type
35
+ end
36
+
37
+ def void?
38
+ false
39
+ end
40
+
41
+ def meta?
42
+ false
43
+ end
44
+
45
+ def array?
46
+ false
47
+ end
48
+
49
+ def primitive?
50
+ false
51
+ end
52
+
53
+ def interface?
54
+ @type.interface?
55
+ end
56
+
57
+ def is_parent(other)
58
+ assignable_from?(other)
59
+ end
60
+
61
+ def compatible?(other)
62
+ assignable_from?(other)
63
+ end
64
+
65
+ def assignable_from?(other)
66
+ return true if !primitive? && other == Null
67
+ return true if other == self
68
+ return true if other.error? || other.unreachable?
69
+ begin
70
+ jvm_type.assignable_from?(other.jvm_type)
71
+ rescue
72
+ assignable_from?(other.superclass) ||
73
+ other.interfaces.any? {|i| assignable_from?(i)}
74
+ end
75
+ end
76
+
77
+ def iterable?
78
+ ['java.lang.Iterable',
79
+ 'java.util.Iterator',
80
+ 'java.util.Enumeration'].any? {|n| AST.type(n).assignable_from(self)}
81
+ end
82
+
83
+ def component_type
84
+ AST.type('java.lang.Object') if iterable?
85
+ end
86
+
87
+ def meta
88
+ @meta ||= MetaType.new(self)
89
+ end
90
+
91
+ def unmeta
92
+ self
93
+ end
94
+
95
+ def basic_type
96
+ self
97
+ end
98
+
99
+ def array_type
100
+ @array_type ||= ArrayType.new(self)
101
+ end
102
+
103
+ def prefix
104
+ 'a'
105
+ end
106
+
107
+ # is this a 64 bit type?
108
+ def wide?
109
+ false
110
+ end
111
+
112
+ def inspect(indent=0)
113
+ "#{' ' * indent}#<#{self.class.name} #{name}>"
114
+ end
115
+
116
+ def newarray(method)
117
+ method.anewarray(self)
118
+ end
119
+
120
+ def superclass
121
+ raise "Incomplete type #{self}" unless jvm_type
122
+ AST.type(jvm_type.superclass) if jvm_type.superclass
123
+ end
124
+
125
+ def interfaces
126
+ @interfaces ||= jvm_type.interfaces.map do |interface|
127
+ AST.type(interface)
128
+ end
129
+ end
130
+
131
+ def astore(builder)
132
+ if primitive?
133
+ builder.send "#{name[0,1]}astore"
134
+ else
135
+ builder.aastore
136
+ end
137
+ end
138
+
139
+ def aload(builder)
140
+ if primitive?
141
+ builder.send "#{name[0,1]}aload"
142
+ else
143
+ builder.aaload
144
+ end
145
+ end
146
+ end
147
+
148
+ class PrimitiveType < Type
149
+ def initialize(type, wrapper)
150
+ @wrapper = wrapper
151
+ super(type)
152
+ end
153
+
154
+ def primitive?
155
+ true
156
+ end
157
+
158
+ def primitive_type
159
+ @wrapper::TYPE
160
+ end
161
+
162
+ def newarray(method)
163
+ method.send "new#{name}array"
164
+ end
165
+
166
+ def interfaces
167
+ []
168
+ end
169
+
170
+ def convertible_to?(type)
171
+ return true if type == self
172
+ a, b = TYPE_ORDERING.index(self), TYPE_ORDERING.index(type)
173
+ a && b && b > a
174
+ end
175
+ end
176
+
177
+ class MetaType < Type
178
+ attr_reader :unmeta
179
+
180
+ def initialize(unmeta)
181
+ @name = unmeta.name
182
+ @unmeta = unmeta
183
+ end
184
+
185
+ def basic_type
186
+ @unmeta.basic_type
187
+ end
188
+
189
+ def meta?
190
+ true
191
+ end
192
+
193
+ def meta
194
+ self
195
+ end
196
+
197
+ def superclass
198
+ @unmeta.superclass.meta if @unmeta.superclass
199
+ end
200
+
201
+ def interfaces
202
+ []
203
+ end
204
+
205
+ def jvm_type
206
+ unmeta.jvm_type
207
+ end
208
+ end
209
+
210
+ class NullType < Type
211
+ def initialize
212
+ super(java.lang.Object)
213
+ end
214
+
215
+ def compatible?(other)
216
+ !other.primitive?
217
+ end
218
+ end
219
+
220
+ class VoidType < PrimitiveType
221
+ def initialize
222
+ super(Java::JavaLang::Void, Java::JavaLang::Void)
223
+ @name = "void"
224
+ end
225
+
226
+ def void?
227
+ true
228
+ end
229
+
230
+ def return(builder)
231
+ builder.returnvoid
232
+ end
233
+ end
234
+
235
+ class ArrayType < Type
236
+ attr_reader :component_type
237
+
238
+ def initialize(component_type)
239
+ @component_type = component_type
240
+ @name = component_type.name
241
+ end
242
+
243
+ def jvm_type
244
+ @component_type.jvm_type
245
+ end
246
+
247
+ def array?
248
+ true
249
+ end
250
+
251
+ def iterable?
252
+ true
253
+ end
254
+
255
+ def basic_type
256
+ component_type.basic_type
257
+ end
258
+
259
+ def superclass
260
+ Object
261
+ end
262
+ end
263
+
264
+ class TypeDefinition < Type
265
+ attr_accessor :node
266
+
267
+ def initialize(name, node)
268
+ if name.class_builder?
269
+ super(name)
270
+ else
271
+ raise ArgumentError, "Bad name #{name}" if name[0,1] == '.'
272
+ @name = name
273
+ end
274
+ @node = node
275
+ raise ArgumentError, "Bad type #{name}" if self.name =~ /Java::/
276
+ end
277
+
278
+ def name
279
+ if @type
280
+ @type.name
281
+ else
282
+ @name
283
+ end
284
+ end
285
+
286
+ def superclass
287
+ (node && node.superclass) || Object
288
+ end
289
+
290
+ def interfaces
291
+ if node
292
+ node.interfaces
293
+ else
294
+ []
295
+ end
296
+ end
297
+
298
+ def define(builder)
299
+ class_name = @name.tr('.', '/')
300
+ @type ||= builder.public_class(class_name, superclass, *interfaces)
301
+ end
302
+
303
+ def meta
304
+ @meta ||= TypeDefMeta.new(self)
305
+ end
306
+ end
307
+
308
+ class InterfaceDefinition < TypeDefinition
309
+ def initialize(name, node)
310
+ super(name, node)
311
+ end
312
+
313
+ def define(builder)
314
+ @type ||= builder.public_interface(@name, *interfaces)
315
+ end
316
+ end
317
+
318
+ class TypeDefMeta < MetaType
319
+ end
320
+ end
321
+ end
322
+ end
323
+
324
+ require 'duby/jvm/types/intrinsics'
325
+ require 'duby/jvm/types/methods'
326
+ require 'duby/jvm/types/number'
327
+ require 'duby/jvm/types/integers'
328
+ require 'duby/jvm/types/boolean'
329
+ require 'duby/jvm/types/floats'
330
+ require 'duby/jvm/types/basic_types'
331
+ require 'duby/jvm/types/literals'