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