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,387 @@
1
+ require 'duby/jvm/types'
2
+
3
+ module Duby
4
+ class JVM::Types::Type
5
+ def to_source
6
+ "#{name}#{'[]' if array?}"
7
+ end
8
+ end
9
+
10
+ module JavaSource
11
+ JVMTypes ||= Duby::JVM::Types
12
+
13
+ class Builder
14
+ attr_accessor :package, :classes, :filename, :compiler
15
+
16
+ def initialize(filename, compiler)
17
+ @filename = filename
18
+ @classes = []
19
+ @compiler = compiler
20
+ end
21
+
22
+ def public_class(name, superclass=nil, *interfaces)
23
+ cls = ClassBuilder.new(self, name, superclass, interfaces)
24
+ @classes << cls
25
+ cls
26
+ end
27
+
28
+ def public_interface(name, *interfaces)
29
+ cls = InterfaceBuilder.new(self, name, interfaces)
30
+ @classes << cls
31
+ cls
32
+ end
33
+
34
+ def generate
35
+ @classes.each do |cls|
36
+ yield cls.filename, cls
37
+ end
38
+ end
39
+ end
40
+
41
+ class Output
42
+ def initialize
43
+ @out = ""
44
+ @indent = 0
45
+ end
46
+
47
+ def puts(*lines)
48
+ lines.each do |line|
49
+ print_indent
50
+ @out << line.to_s
51
+ @out << "\n"
52
+ @indented = false
53
+ end
54
+ end
55
+
56
+ def print_indent
57
+ @indent ||= 0
58
+ @out << (' ' * @indent) unless @indented
59
+ @indented = true
60
+ end
61
+
62
+ def print(str)
63
+ print_indent
64
+ @out << str.to_s
65
+ end
66
+
67
+ def indent
68
+ @indent += 2
69
+ end
70
+
71
+ def dedent
72
+ @indent -= 2
73
+ end
74
+
75
+ def <<(other)
76
+ other.to_s.each_line do |line|
77
+ print_indent
78
+ print(line)
79
+ @indented = false
80
+ end
81
+ end
82
+
83
+ def to_s
84
+ @out
85
+ end
86
+ end
87
+
88
+ module Helper
89
+ def puts(*args)
90
+ @out.puts(*args)
91
+ end
92
+
93
+ def print(*args)
94
+ @out.print(*args)
95
+ end
96
+
97
+ def indent
98
+ @out.indent
99
+ end
100
+
101
+ def dedent
102
+ @out.dedent
103
+ end
104
+
105
+ def block(line='')
106
+ puts line + " {"
107
+ indent
108
+ yield
109
+ dedent
110
+ puts "}"
111
+ end
112
+
113
+ def init_value(type)
114
+ # TODO move this to types?
115
+ case type
116
+ when JVMTypes::Boolean
117
+ 'false'
118
+ when JVMTypes::PrimitiveType, JVMTypes::NarrowingType
119
+ '0'
120
+ else
121
+ 'null'
122
+ end
123
+ end
124
+
125
+ def annotate(annotations)
126
+ annotations.each do |annotation|
127
+ # TODO values
128
+ puts "@#{annotation.name}"
129
+ end
130
+ end
131
+ end
132
+
133
+ class ClassBuilder
134
+ include Helper
135
+ include Duby::Compiler::JVM::JVMLogger
136
+ attr_reader :package, :name, :superclass, :filename, :class_name, :out
137
+ attr_reader :interfaces
138
+ def initialize(builder, name, superclass, interfaces)
139
+ @builder = builder
140
+ @package = builder.package
141
+ if @package
142
+ @name = "#{@package}.#{name}"
143
+ else
144
+ @name = name
145
+ end
146
+ if name =~ %r{[/.]}
147
+ pieces = name.split(%r{[/.]})
148
+ name = pieces.pop
149
+ @package = pieces.join('.')
150
+ end
151
+ @class_name = name
152
+ @superclass = superclass || JVMTypes::Object
153
+ @interfaces = interfaces
154
+ @filename = "#{name}.java"
155
+ @filename = "#{package.tr('.', '/')}/#{@filename}" if @package
156
+ @out = Output.new
157
+ @stopped = false
158
+ @methods = []
159
+ @fields = {}
160
+ start
161
+ end
162
+
163
+ def compiler
164
+ @builder.compiler
165
+ end
166
+
167
+ def start
168
+ puts "// Generated from #{@builder.filename}"
169
+ puts "package #{package};" if package
170
+ end
171
+
172
+ def finish_declaration
173
+ return if @declaration_finished
174
+ @declaration_finished = true
175
+ print "public class #{class_name} extends #{superclass.name}"
176
+ unless @interfaces.empty?
177
+ print " implements "
178
+ @interfaces.each_with_index do |interface, index|
179
+ print ', ' unless index == 0
180
+ print interface.to_source
181
+ end
182
+ end
183
+ puts " {"
184
+ indent
185
+ end
186
+
187
+ def stop
188
+ finish_declaration
189
+ return if @stopped
190
+ @methods.each do |method|
191
+ @out << method.out
192
+ end
193
+ log "Class #{name} complete (#{@out.to_s.size})"
194
+ @stopped = true
195
+ dedent
196
+ puts "}"
197
+ log "Class #{name} complete (#{@out.to_s.size})"
198
+ end
199
+
200
+ def main
201
+ public_static_method('main', JVMTypes::Void, [],
202
+ [JVMTypes::String.array_type, 'argv'])
203
+ end
204
+
205
+ def declare_field(name, type, static, annotations=[])
206
+ finish_declaration
207
+ return if @fields[name]
208
+ static = static ? 'static' : ''
209
+ annotate(annotations)
210
+ puts "private #{static} #{type.to_source} #{name};"
211
+ @fields[name] = true
212
+ end
213
+
214
+ def public_method(name, type, exceptions, *args)
215
+ finish_declaration
216
+ @methods << MethodBuilder.new(self,
217
+ :name => name,
218
+ :return => type,
219
+ :args => args,
220
+ :exceptions => exceptions)
221
+ @methods[-1]
222
+ end
223
+
224
+ def public_static_method(name, type, exceptions, *args)
225
+ finish_declaration
226
+ @methods << MethodBuilder.new(self,
227
+ :name => name,
228
+ :return => type,
229
+ :args => args,
230
+ :static => true,
231
+ :exceptions => exceptions)
232
+ @methods[-1]
233
+ end
234
+
235
+ def public_constructor(exceptions, *args)
236
+ finish_declaration
237
+ @methods << MethodBuilder.new(self,
238
+ :name => class_name,
239
+ :args => args,
240
+ :exceptions => exceptions)
241
+ @methods[-1]
242
+ end
243
+
244
+ def generate
245
+ stop
246
+ @out.to_s
247
+ end
248
+ end
249
+
250
+ class InterfaceBuilder < ClassBuilder
251
+ def initialize(builder, name, interfaces)
252
+ super(builder, name, nil, interfaces)
253
+ end
254
+
255
+ def finish_declaration
256
+ return if @declaration_finished
257
+ @declaration_finished = true
258
+ print "public interface #{class_name}"
259
+ unless @interfaces.empty?
260
+ print " extends "
261
+ @interfaces.each_with_index do |interface, index|
262
+ print ', ' unless index == 0
263
+ print interface.to_source
264
+ end
265
+ end
266
+ puts " {"
267
+ indent
268
+ end
269
+
270
+ def public_method(name, type, exceptions, *args)
271
+ finish_declaration
272
+ @methods << MethodBuilder.new(self,
273
+ :name => name,
274
+ :return => type,
275
+ :args => args,
276
+ :abstract => true,
277
+ :exceptions => exceptions)
278
+ @methods[-1]
279
+ end
280
+ end
281
+
282
+ class MethodBuilder
283
+ include Helper
284
+
285
+ attr_accessor :name, :type, :out
286
+
287
+ def initialize(cls, options)
288
+ @class = cls
289
+ @compiler = cls.compiler
290
+ @out = Output.new
291
+ @name = options[:name]
292
+ @type = options[:return]
293
+ @typename = @type && @type.to_source
294
+ @locals = {}
295
+ @args = options[:args].map do |arg|
296
+ unless arg.kind_of? Array
297
+ arg = [arg.inferred_type, arg.name]
298
+ end
299
+ @locals[arg[1]] = arg[0]
300
+ arg
301
+ end
302
+ @static = options[:static] && ' static'
303
+ @abstract = options[:abstract] && ' abstract'
304
+ @exceptions = options[:exceptions] || []
305
+ @temps = 0
306
+ end
307
+
308
+ def start
309
+ print "public#{@static}#{@abstract} #{@typename} #{@name}("
310
+ @args.each_with_index do |(type, name), i|
311
+ print ', ' unless i == 0
312
+ print "#{type.to_source} #{name}"
313
+ end
314
+ print ')'
315
+ unless @exceptions.empty?
316
+ print ' throws '
317
+ @exceptions.each_with_index do |exception, i|
318
+ print ', ' unless i == 0
319
+ print exception.name
320
+ end
321
+ end
322
+ if @abstract
323
+ puts ";"
324
+ def self.puts(*args); end
325
+ def self.print(*args); end
326
+ else
327
+ puts " {"
328
+ end
329
+ indent
330
+ end
331
+
332
+ def stop
333
+ dedent
334
+ puts "}"
335
+ end
336
+
337
+ def declare_local(type, name)
338
+ unless @locals[name]
339
+ print "#{type.to_source} #{name} = "
340
+ if block_given?
341
+ yield self
342
+ else
343
+ print init_value(type)
344
+ end
345
+ puts ';'
346
+ @locals[name] = type
347
+ end
348
+ name
349
+ end
350
+
351
+ def local?(name)
352
+ !!@locals[name]
353
+ end
354
+
355
+ def tmp(type)
356
+ @temps += 1
357
+ declare_local(type, "temp$#{@temps}")
358
+ end
359
+
360
+ def label
361
+ @temps += 1
362
+ "label#{@temps}"
363
+ end
364
+
365
+ def push_int(value)
366
+ print value
367
+ end
368
+
369
+ def ldc_float(value)
370
+ print "(float)#{value}"
371
+ end
372
+
373
+ def ldc_double(value)
374
+ print value
375
+ end
376
+
377
+ def method_missing(name, *args)
378
+ if name.to_s =~ /.const_(m)?(\d)/
379
+ print '-' if $1
380
+ print $2
381
+ else
382
+ super
383
+ end
384
+ end
385
+ end
386
+ end
387
+ end
@@ -0,0 +1,110 @@
1
+ class Duby::Compiler::JavaSource
2
+ class SimpleWhileLoop
3
+ attr_reader :compiler, :loop
4
+ def initialize(loop, compiler)
5
+ @loop = loop
6
+ @compiler = compiler
7
+ end
8
+
9
+ def break
10
+ compiler.method.puts "break;"
11
+ end
12
+
13
+ def next
14
+ compiler.method.puts "continue;"
15
+ end
16
+
17
+ def redo
18
+ raise "#{self.class.name} doesn't support redo"
19
+ end
20
+
21
+ def compile(expression)
22
+ prepare
23
+ @loop.init.compile(compiler, false) if @loop.init?
24
+ @start.call
25
+ compiler.method.block do
26
+ @loop.pre.compile(compiler, false) if @loop.pre?
27
+ compile_body
28
+ @loop.post.compile(compiler, false) if @loop.post?
29
+ end
30
+ if @end_check
31
+ @end_check.call
32
+ compiler.method.puts ';'
33
+ end
34
+ if expression
35
+ compiler.method.puts "#{compiler.lvalue}null;"
36
+ end
37
+ end
38
+
39
+ def compile_body
40
+ loop.body.compile(compiler, false)
41
+ end
42
+
43
+ def prepare
44
+ predicate = loop.condition.predicate.precompile(compiler)
45
+ negative = loop.negative ? '!' : ''
46
+ check = lambda do
47
+ compiler.method.print "while (#{negative}"
48
+ predicate.compile(compiler, true)
49
+ compiler.method.print ')'
50
+ end
51
+ if loop.check_first
52
+ @start = check
53
+ else
54
+ @start = lambda {compiler.method.print 'do'}
55
+ @end_check = check
56
+ end
57
+ end
58
+ end
59
+
60
+ module Redoable
61
+ def compile_with_redo(block)
62
+ @redo = compiler.method.tmp(JVMTypes::Boolean)
63
+ compiler.method.puts "#{@inner}:"
64
+ compiler.method.block "do" do
65
+ compiler.method.puts "#{@redo} = false;"
66
+ block.compile(compiler, false)
67
+ end
68
+ compiler.method.puts "while (#{@redo});"
69
+ end
70
+
71
+ def break
72
+ compiler.method.puts "break #{@outer};"
73
+ end
74
+
75
+ def next
76
+ compiler.method.puts "break #{@inner};"
77
+ end
78
+
79
+ def redo
80
+ compiler.method.puts "#{@redo} = true;"
81
+ compiler.method.puts "continue #{@inner};"
82
+ end
83
+ end
84
+
85
+ class ComplexWhileLoop < SimpleWhileLoop
86
+ include Redoable
87
+ def prepare
88
+ super
89
+ @outer = compiler.method.label
90
+ @inner = compiler.method.label
91
+ @complex_predicate = !loop.condition.predicate.expr?(compiler)
92
+ super_start = @start
93
+ @start = lambda do
94
+ compiler.method.puts "#{@outer}:"
95
+ super_start.call
96
+ end
97
+ end
98
+
99
+ def compile_body
100
+ if @loop.redo?
101
+ compile_with_redo(@loop.body)
102
+ else
103
+ compiler.method.puts "#{@inner}:"
104
+ compiler.method.block do
105
+ loop.body.compile(compiler, false)
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end