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,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