duby 0.0.2-java → 0.0.3-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 (72) hide show
  1. data/History.txt +7 -0
  2. data/README.txt +18 -7
  3. data/Rakefile +72 -0
  4. data/examples/ant/example-build.xml +7 -0
  5. data/examples/appengine/Rakefile +8 -67
  6. data/examples/appengine/Readme +4 -3
  7. data/examples/appengine/lib/duby/appengine_tasks.rb +173 -0
  8. data/examples/appengine/lib/duby/plugin/datastore.rb +92 -31
  9. data/examples/appengine/lib/duby_task.rb +61 -0
  10. data/examples/appengine/src/com/ribrdb/DubyApp.duby +32 -6
  11. data/examples/appengine/src/com/ribrdb/list.dhtml +2 -2
  12. data/examples/appengine/{config.ru → src/config.ru} +0 -0
  13. data/examples/bintrees.duby +66 -0
  14. data/examples/dynamic.duby +17 -0
  15. data/examples/fib.duby +3 -11
  16. data/examples/fields.duby +3 -3
  17. data/examples/fractal.duby +1 -3
  18. data/examples/sort_closure.duby +7 -0
  19. data/examples/swing.duby +11 -11
  20. data/javalib/duby-bootstrap.jar +0 -0
  21. data/javalib/dynalang-invoke-0.1.jar +0 -0
  22. data/lib/duby.rb +168 -35
  23. data/lib/duby/ast.rb +224 -27
  24. data/lib/duby/ast/call.rb +85 -25
  25. data/lib/duby/ast/class.rb +112 -28
  26. data/lib/duby/ast/flow.rb +65 -44
  27. data/lib/duby/ast/intrinsics.rb +223 -21
  28. data/lib/duby/ast/literal.rb +67 -16
  29. data/lib/duby/ast/local.rb +36 -40
  30. data/lib/duby/ast/method.rb +83 -67
  31. data/lib/duby/ast/structure.rb +105 -23
  32. data/lib/duby/compiler.rb +83 -28
  33. data/lib/duby/env.rb +33 -0
  34. data/lib/duby/jvm/base.rb +210 -0
  35. data/lib/duby/jvm/compiler.rb +293 -219
  36. data/lib/duby/jvm/method_lookup.rb +77 -67
  37. data/lib/duby/jvm/source_compiler.rb +250 -157
  38. data/lib/duby/jvm/source_generator/builder.rb +53 -49
  39. data/lib/duby/jvm/source_generator/loops.rb +9 -9
  40. data/lib/duby/jvm/source_generator/precompile.rb +35 -25
  41. data/lib/duby/jvm/typer.rb +19 -10
  42. data/lib/duby/jvm/types.rb +127 -68
  43. data/lib/duby/jvm/types/basic_types.rb +26 -13
  44. data/lib/duby/jvm/types/enumerable.rb +6 -4
  45. data/lib/duby/jvm/types/factory.rb +49 -13
  46. data/lib/duby/jvm/types/floats.rb +16 -0
  47. data/lib/duby/jvm/types/integers.rb +63 -2
  48. data/lib/duby/jvm/types/intrinsics.rb +43 -21
  49. data/lib/duby/jvm/types/methods.rb +326 -86
  50. data/lib/duby/jvm/types/number.rb +3 -0
  51. data/lib/duby/nbcompiler.rb +1 -1
  52. data/lib/duby/plugin/edb.rb +1 -1
  53. data/lib/duby/plugin/java.rb +10 -1
  54. data/lib/duby/transform.rb +134 -46
  55. data/lib/duby/typer.rb +75 -50
  56. data/test/test_ast.rb +106 -106
  57. data/test/test_compilation.rb +46 -32
  58. data/test/test_env.rb +42 -0
  59. data/test/test_java_typer.rb +35 -51
  60. data/test/test_javac_compiler.rb +4 -1
  61. data/test/test_jvm_compiler.rb +564 -133
  62. data/test/test_typer.rb +68 -92
  63. metadata +37 -21
  64. data/examples/README +0 -16
  65. data/lib/duby/c/compiler.rb +0 -134
  66. data/lib/duby/old/compiler_old.rb +0 -845
  67. data/lib/duby/old/declaration.rb +0 -72
  68. data/lib/duby/old/mapper.rb +0 -72
  69. data/lib/duby/old/signature.rb +0 -52
  70. data/lib/duby/old/typer_old.rb +0 -163
  71. data/lib/duby/plugin/math.rb +0 -84
  72. data/test/test_math_plugin.rb +0 -87
@@ -10,7 +10,16 @@ module Duby
10
10
  end
11
11
  end
12
12
  end
13
-
13
+
14
+ class Regexp
15
+ def compile(compiler, expression)
16
+ if expression
17
+ compiler.line(line_number)
18
+ compiler.regexp(literal)
19
+ end
20
+ end
21
+ end
22
+
14
23
  class String
15
24
  def compile(compiler, expression)
16
25
  if expression
@@ -19,7 +28,19 @@ module Duby
19
28
  end
20
29
  end
21
30
  end
22
-
31
+
32
+ class StringConcat
33
+ def compile(compiler, expression)
34
+ compiler.build_string(children, expression)
35
+ end
36
+ end
37
+
38
+ class ToString
39
+ def compile(compiler, expression)
40
+ compiler.to_string(body, expression)
41
+ end
42
+ end
43
+
23
44
  class Float
24
45
  def compile(compiler, expression)
25
46
  if expression
@@ -28,7 +49,7 @@ module Duby
28
49
  end
29
50
  end
30
51
  end
31
-
52
+
32
53
  class Boolean
33
54
  def compile(compiler, expression)
34
55
  if expression
@@ -43,7 +64,7 @@ module Duby
43
64
  compiler.array(self, expression)
44
65
  end
45
66
  end
46
-
67
+
47
68
  class Body
48
69
  def compile(compiler, expression)
49
70
  compiler.line(line_number)
@@ -51,6 +72,13 @@ module Duby
51
72
  end
52
73
  end
53
74
 
75
+ class ScopedBody
76
+ def compile(compiler, expression)
77
+ compiler.line(line_number)
78
+ compiler.scoped_body(self, expression)
79
+ end
80
+ end
81
+
54
82
  class Import
55
83
  def compile(compiler, expression)
56
84
  # TODO: what does it mean for import to be an expression?
@@ -74,12 +102,16 @@ module Duby
74
102
  compiler.print(self)
75
103
  end
76
104
  end
77
-
105
+
78
106
  class Local
79
107
  def compile(compiler, expression)
80
108
  if expression
81
109
  compiler.line(line_number)
82
- compiler.local(name, inferred_type)
110
+ if captured? && scope.has_binding?
111
+ compiler.captured_local(containing_scope, name, inferred_type)
112
+ else
113
+ compiler.local(containing_scope, name, inferred_type)
114
+ end
83
115
  end
84
116
  end
85
117
  end
@@ -87,58 +119,66 @@ module Duby
87
119
  class LocalDeclaration
88
120
  def compile(compiler, expression)
89
121
  compiler.line(line_number)
90
- compiler.local_declare(name, type)
122
+ if captured? && scope.has_binding?
123
+ compiler.captured_local_declare(containing_scope, name, type)
124
+ else
125
+ compiler.local_declare(containing_scope, name, type)
126
+ end
91
127
  end
92
128
  end
93
-
129
+
94
130
  class LocalAssignment
95
131
  def compile(compiler, expression)
96
132
  compiler.line(line_number)
97
- compiler.local_assign(name, inferred_type, expression, value)
133
+ if captured? && scope.has_binding?
134
+ compiler.captured_local_assign(self, expression)
135
+ else
136
+ compiler.local_assign(containing_scope, name, inferred_type, expression, value)
137
+ end
98
138
  end
99
139
  end
100
-
140
+
101
141
  class Script
102
142
  def compile(compiler, expression)
103
143
  # TODO: what does it mean for a script to be an expression? possible?
104
- compiler.define_main(body)
144
+ compiler.define_main(self)
105
145
  end
106
146
  end
107
-
147
+
108
148
  class MethodDefinition
109
149
  def compile(compiler, expression)
110
150
  # TODO: what does it mean for a method to be an expression?
111
151
  compiler.define_method(self)
112
152
  end
113
153
  end
114
-
154
+
115
155
  class ConstructorDefinition
116
156
  def compile(compiler, expression)
117
157
  compiler.constructor(self)
118
158
  end
119
159
  end
120
-
160
+
121
161
  class Arguments
122
162
  def compile(compiler, expression)
123
163
  # TODO: what does it mean for a method to be an expression?
124
164
  args.each {|arg| compiler.declare_argument(arg.name, arg.inferred_type)} if args
125
165
  end
126
166
  end
127
-
167
+
128
168
  class Noop
129
169
  def compile(compiler, expression)
130
170
  # TODO: what does it mean for a noop to be an expression
131
171
  # nothing
132
172
  end
133
173
  end
134
-
174
+
135
175
  class If
136
176
  def compile(compiler, expression)
137
177
  compiler.line(line_number)
138
178
  compiler.branch(self, expression)
139
179
  end
140
180
  end
141
-
181
+
142
182
  class Condition
143
183
  def compile(compiler, expression)
144
184
  # TODO: can a condition ever be an expression? I don't think it can...
@@ -146,14 +186,14 @@ module Duby
146
186
  predicate.compile(compiler, expression)
147
187
  end
148
188
  end
149
-
189
+
150
190
  class FunctionalCall
151
191
  def compile(compiler, expression)
152
192
  compiler.line(line_number)
153
193
  compiler.self_call(self, expression)
154
194
  end
155
195
  end
156
-
196
+
157
197
  class Call
158
198
  def compile(compiler, expression)
159
199
  compiler.line(line_number)
@@ -167,20 +207,26 @@ module Duby
167
207
  compiler.super_call(self, expression)
168
208
  end
169
209
  end
170
-
210
+
171
211
  class Loop
172
212
  def compile(compiler, expression)
173
213
  compiler.line(line_number)
174
214
  compiler.loop(self, expression)
175
215
  end
176
216
  end
177
-
217
+
178
218
  class ClassDefinition
179
219
  def compile(compiler, expression)
180
220
  compiler.define_class(self, expression)
181
221
  end
182
222
  end
183
223
 
224
+ class ClosureDefinition
225
+ def compile(compiler, expression)
226
+ compiler.define_closure(self, expression)
227
+ end
228
+ end
229
+
184
230
  class FieldDeclaration
185
231
  def compile(compiler, expression)
186
232
  compiler.field_declare(name, inferred_type, annotations)
@@ -218,7 +264,7 @@ module Duby
218
264
  end
219
265
  end
220
266
  end
221
-
267
+
222
268
  class Null
223
269
  def compile(compiler, expression)
224
270
  if expression
@@ -227,21 +273,21 @@ module Duby
227
273
  end
228
274
  end
229
275
  end
230
-
276
+
231
277
  class Break
232
278
  def compile(compiler, expression)
233
279
  compiler.line(line_number)
234
280
  compiler.break(self)
235
281
  end
236
282
  end
237
-
283
+
238
284
  class Next
239
285
  def compile(compiler, expression)
240
286
  compiler.line(line_number)
241
287
  compiler.next(self)
242
288
  end
243
289
  end
244
-
290
+
245
291
  class Redo
246
292
  def compile(compiler, expression)
247
293
  compiler.line(line_number)
@@ -252,7 +298,7 @@ module Duby
252
298
  class Raise
253
299
  def compile(compiler, expression)
254
300
  compiler.line(line_number)
255
- compiler._raise(@exception)
301
+ compiler._raise(exception)
256
302
  end
257
303
  end
258
304
 
@@ -262,14 +308,14 @@ module Duby
262
308
  compiler.rescue(self, expression)
263
309
  end
264
310
  end
265
-
311
+
266
312
  class Ensure
267
313
  def compile(compiler, expression)
268
314
  compiler.line(line_number)
269
315
  compiler.ensure(self, expression)
270
316
  end
271
317
  end
272
-
318
+
273
319
  class Self
274
320
  def compile(compiler, expression)
275
321
  if expression
@@ -278,5 +324,14 @@ module Duby
278
324
  end
279
325
  end
280
326
  end
327
+
328
+ class BindingReference
329
+ def compile(compiler, expression)
330
+ if expression
331
+ compiler.line(line_number)
332
+ compiler.binding_reference
333
+ end
334
+ end
335
+ end
281
336
  end
282
337
  end
@@ -0,0 +1,33 @@
1
+ require 'rbconfig'
2
+
3
+ module Duby
4
+ module Env
5
+
6
+ # Returns the system PATH_SEPARATOR environment variable value. This is used when
7
+ # separating multiple paths in one string. If none is defined then a : (colon)
8
+ # is returned
9
+ def self.path_seperator
10
+ ps = RbConfig::CONFIG['PATH_SEPARATOR']
11
+ ps = ':' if ps.nil? || ps == ''
12
+ ps
13
+ end
14
+
15
+ # Takes an array of strings and joins them using the path_separator returning
16
+ # a single string value
17
+ def self.encode_paths(paths)
18
+ paths.join(path_seperator)
19
+ end
20
+
21
+ # Takes a single string value "paths" and returns an array of strings containing the
22
+ # original string separated using the path_separator. An option second parameter
23
+ # is an array that will have the strings appended to it. If the optional array parameter
24
+ # is supplied it is returned as the result
25
+ def self.decode_paths(paths, dest = nil)
26
+ result = dest ? dest : []
27
+ paths.split(path_seperator).each do |path|
28
+ result << path
29
+ end
30
+ result
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,210 @@
1
+ module Duby
2
+ module Compiler
3
+ class JVMCompilerBase
4
+ attr_accessor :filename, :method, :static, :class
5
+
6
+ def initialize(filename)
7
+ @filename = File.basename(filename)
8
+ @static = true
9
+ classname = JVM.classname_from_filename(filename)
10
+ @type = AST::type(classname)
11
+ @jump_scope = []
12
+ @bindings = Hash.new {|h, type| h[type] = type.define(@file)}
13
+ @captured_locals = Hash.new {|h, binding| h[binding] = {}}
14
+ end
15
+
16
+ def compile(ast, expression = false)
17
+ ast.compile(self, expression)
18
+ log "Compilation successful!"
19
+ end
20
+
21
+ def log(message); JVM.log(message); end
22
+
23
+ def toplevel_class
24
+ @class = @type.define(@file)
25
+ end
26
+
27
+ def generate
28
+ log "Generating #{output_type}..."
29
+ @file.generate do |filename, builder|
30
+ log " #{builder.class_name}"
31
+ if block_given?
32
+ yield filename, builder
33
+ else
34
+ File.open(filename, 'w') {|f| f.write(builder.generate)}
35
+ end
36
+ end
37
+ log "...done!"
38
+ end
39
+
40
+ def define_main(script)
41
+ body = script.body
42
+ body = body[0] if body.children.size == 1
43
+ if body.class != AST::ClassDefinition
44
+ @class = @type.define(@file)
45
+ with :method => @class.main do
46
+ log "Starting main method"
47
+
48
+ @method.start
49
+ @current_scope = script.static_scope
50
+ begin_main
51
+
52
+ prepare_binding(script) do
53
+ body.compile(self, false)
54
+ end
55
+
56
+ finish_main
57
+ @method.stop
58
+ end
59
+ @class.stop
60
+ else
61
+ body.compile(self, false)
62
+ end
63
+
64
+ log "Main method complete!"
65
+ end
66
+
67
+ def begin_main; end
68
+ def finish_main; end
69
+
70
+ def define_method(node, args_are_types)
71
+ name, signature, args = node.name, node.signature, node.arguments.args
72
+ if name == "initialize" && node.static?
73
+ name = "<clinit>"
74
+ end
75
+ if args_are_types
76
+ arg_types = args.map { |arg| arg.inferred_type } if args
77
+ else
78
+ arg_types = args
79
+ end
80
+ arg_types ||= []
81
+ return_type = signature[:return]
82
+ exceptions = signature[:throws]
83
+ puts "exceptions: #{exceptions.inspect}" if exceptions && exceptions.size > 0
84
+
85
+ with :static => @static || node.static?, :current_scope => node.static_scope do
86
+ if @static
87
+ method = @class.public_static_method(name.to_s, exceptions, return_type, *arg_types)
88
+ else
89
+ method = @class.public_method(name.to_s, exceptions, return_type, *arg_types)
90
+ end
91
+ annotate(method, node.annotations)
92
+ yield method, arg_types
93
+ end
94
+
95
+ arg_types_for_opt = []
96
+ args_for_opt = []
97
+ if args
98
+ args.each do |arg|
99
+ if AST::OptionalArgument === arg
100
+ new_args = if args_are_types
101
+ arg_types_for_opt
102
+ else
103
+ args_for_opt
104
+ end
105
+ if @static
106
+ method = @class.public_static_method(name.to_s, exceptions, return_type, *new_args)
107
+ else
108
+ method = @class.public_method(name.to_s, exceptions, return_type, *new_args)
109
+ end
110
+
111
+ with :method => method do
112
+ log "Starting new method #{name}(#{arg_types_for_opt})"
113
+
114
+ annotate(method, node.annotations)
115
+ @method.start
116
+
117
+ define_optarg_chain(name, arg,
118
+ return_type,
119
+ args_for_opt,
120
+ arg_types_for_opt)
121
+
122
+ @method.stop
123
+ end
124
+ end
125
+ arg_types_for_opt << arg.inferred_type
126
+ args_for_opt << arg
127
+ end
128
+ end
129
+ end
130
+
131
+ def constructor(node, args_are_types)
132
+ args = node.arguments.args || []
133
+ arg_types = if args_are_types
134
+ args.map { |arg| arg.inferred_type }
135
+ else
136
+ args
137
+ end
138
+ exceptions = node.signature[:throws]
139
+ method = @class.public_constructor(exceptions, *arg_types)
140
+ annotate(method, node.annotations)
141
+ with :current_scope => node.static_scope do
142
+ yield(method, args)
143
+ end
144
+ end
145
+
146
+ def define_class(class_def, expression)
147
+ with(:type => class_def.inferred_type,
148
+ :class => class_def.inferred_type.define(@file),
149
+ :static => false) do
150
+ annotate(@class, class_def.annotations)
151
+ class_def.body.compile(self, false) if class_def.body
152
+ @class.stop
153
+ end
154
+ end
155
+
156
+ def declare_argument(name, type)
157
+ # declare local vars for arguments here
158
+ end
159
+
160
+ def body(body, expression)
161
+ # all except the last element in a body of code is treated as a statement
162
+ i, last = 0, body.children.size - 1
163
+ while i < last
164
+ body.children[i].compile(self, false)
165
+ i += 1
166
+ end
167
+ yield body.children[last] if last >= 0
168
+ end
169
+
170
+ def scoped_body(scope, expression)
171
+ body(scope, expression)
172
+ end
173
+
174
+ def scoped_local_name(name, scope=nil)
175
+ if scope.nil? || scope == @current_scope
176
+ name
177
+ else
178
+ "#{name}$#{scope.object_id}"
179
+ end
180
+ end
181
+
182
+ def import(short, long)
183
+ end
184
+
185
+ def get_binding(type)
186
+ @bindings[type]
187
+ end
188
+
189
+ def declared_captures(binding=nil)
190
+ @captured_locals[binding || @binding]
191
+ end
192
+
193
+ def with(vars)
194
+ orig_values = {}
195
+ begin
196
+ vars.each do |name, new_value|
197
+ name = "@#{name}"
198
+ orig_values[name] = instance_variable_get name
199
+ instance_variable_set name, new_value
200
+ end
201
+ yield
202
+ ensure
203
+ orig_values.each do |name, value|
204
+ instance_variable_set name, value
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end