duby 0.0.2-java → 0.0.3-java

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