duby 0.0.2-java

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