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
@@ -7,7 +7,7 @@ module Duby::JVM::Types
7
7
  end
8
8
 
9
9
  def add_enumerable_macros
10
- add_macro('all?') do |transformer, call|
10
+ all_proc = proc do |transformer, call|
11
11
  if !call.block
12
12
  # We need to create a block that just returns the item passed to it
13
13
  # First get a new temp for the block argument
@@ -39,9 +39,10 @@ module Duby::JVM::Types
39
39
  result = Duby::AST::Body.new(call.parent, call.position)
40
40
  result << forloop << transformer.eval("#{all}", '', nil, all)
41
41
  end
42
- intrinsics['all?'][[Duby::AST.block_type]] = intrinsics['all?'][[]]
42
+ add_macro('all?', &all_proc)
43
+ add_macro('all?', Duby::AST.block_type, &all_proc)
43
44
 
44
- add_macro('any?') do |transformer, call|
45
+ any_proc = proc do |transformer, call|
45
46
  if !call.block
46
47
  var = transformer.tmp
47
48
  call.block = transformer.eval("foo {|#{var}| #{var}}").block
@@ -57,7 +58,8 @@ module Duby::JVM::Types
57
58
  result = Duby::AST::Body.new(call.parent, call.position)
58
59
  result << forloop << transformer.eval("#{any}", '', nil, any)
59
60
  end
60
- intrinsics['any?'][[Duby::AST.block_type]] = intrinsics['any?'][[]]
61
+ add_macro('any?', &any_proc)
62
+ add_macro('any?', Duby::AST.block_type, &any_proc)
61
63
  end
62
64
  end
63
65
  end
@@ -1,3 +1,4 @@
1
+ require 'jruby'
1
2
  module Duby::JVM::Types
2
3
  class TypeFactory
3
4
  BASIC_TYPES = {
@@ -19,7 +20,8 @@ module Duby::JVM::Types
19
20
  "Iterable" => Iterable,
20
21
  "void" => Void,
21
22
  "notype" => Void,
22
- "null" => Null
23
+ "null" => Null,
24
+ "dynamic" => DynamicType.new
23
25
  }.freeze
24
26
 
25
27
  attr_accessor :package
@@ -39,6 +41,8 @@ module Duby::JVM::Types
39
41
  @package = File.dirname(filename).tr('/', '.')
40
42
  @package.sub! /^\.+/, ''
41
43
  @package = nil if @package.empty?
44
+ @search_packages = [@package, 'java.lang']
45
+ @mirrors = {}
42
46
  end
43
47
 
44
48
  def define_types(builder)
@@ -48,15 +52,22 @@ module Duby::JVM::Types
48
52
  end
49
53
 
50
54
  def type(name, array=false, meta=false)
55
+ if name.kind_of?(BiteScript::ASM::Type)
56
+ if name.getDescriptor[0] == ?[
57
+ return type(name.getElementType, true, meta)
58
+ else
59
+ name = name.getClassName
60
+ end
61
+ end
51
62
  type = basic_type(name)
52
63
  type = type.meta if meta
53
64
  type = type.array_type if array
54
65
  return type
55
66
  end
56
-
67
+
57
68
  def basic_type(name)
58
69
  if name.kind_of?(Type) || name.kind_of?(NarrowingType)
59
- return name.basic_type
70
+ return name.basic_type
60
71
  end
61
72
  orig = name
62
73
  if name.kind_of? Java::JavaClass
@@ -72,18 +83,27 @@ module Duby::JVM::Types
72
83
  return @known_types[name].basic_type if @known_types[name]
73
84
  raise ArgumentError, "Bad Type #{orig}" if name =~ /Java::/
74
85
  raise ArgumentError, "Bad Type #{orig.inspect}" if name == '' || name.nil?
86
+ if name.include? '.'
87
+ alt_names = []
88
+ else
89
+ alt_names = @search_packages.map {|package| "#{package}.#{name}"}
90
+ end
75
91
  full_name = name
76
92
  begin
77
- @known_types[name] = Type.new(Java::JavaClass.for_name(full_name))
93
+ @known_types[name] = Type.new(get_mirror(full_name))
78
94
  rescue NameError
79
- unless full_name.include? '.'
80
- full_name = "java.lang.#{full_name}"
95
+ unless alt_names.empty?
96
+ full_name = alt_names.shift
81
97
  retry
82
98
  end
83
99
  raise $!
84
100
  end
85
101
  end
86
102
 
103
+ def known_type(name)
104
+ basic_type(name) rescue nil
105
+ end
106
+
87
107
  def declare_type(node)
88
108
  if node.kind_of? ::String
89
109
  name = node
@@ -92,9 +112,7 @@ module Duby::JVM::Types
92
112
  name = node.name
93
113
  end
94
114
 
95
- if Duby::AST::InterfaceDeclaration === node
96
- @known_types[name] = InterfaceDefinition.new(name, node)
97
- elsif @known_types.include? name
115
+ if @known_types.include? name
98
116
  existing = @known_types[name]
99
117
  existing.node ||= node
100
118
  existing
@@ -103,26 +121,44 @@ module Duby::JVM::Types
103
121
  if !name.include?('.') && package
104
122
  full_name = "#{package}.#{name}"
105
123
  end
106
- @known_types[full_name] = TypeDefinition.new(full_name, node)
124
+ if Duby::AST::InterfaceDeclaration === node
125
+ klass = InterfaceDefinition
126
+ else
127
+ klass = TypeDefinition
128
+ end
129
+ @known_types[full_name] = klass.new(full_name, node)
107
130
  @known_types[name] = @known_types[full_name]
108
131
  end
109
132
  end
110
133
 
111
134
  def alias(from, to)
112
- @known_types[from] = type(to)
135
+ if from == '*'
136
+ @search_packages << to.sub(".*", "")
137
+ else
138
+ @known_types[from] = type(to)
139
+ end
113
140
  end
114
141
 
115
142
  def no_type
116
143
  Void
117
144
  end
118
-
145
+
119
146
  def fixnum(parent, line_number, literal)
120
147
  FixnumLiteralNode.new(parent, line_number, literal)
121
148
  end
122
-
149
+
123
150
  def float(parent, line_number, literal)
124
151
  FloatLiteralNode.new(parent, line_number, literal)
125
152
  end
153
+
154
+ def get_mirror(name)
155
+ @mirrors[name] ||= begin
156
+ classname = name.tr('.', '/') + ".class"
157
+ stream = JRuby.runtime.jruby_class_loader.getResourceAsStream(classname)
158
+ raise NameError, "Class '#{name}' not found." unless stream
159
+ BiteScript::ASM::ClassMirror.load(stream)
160
+ end
161
+ end
126
162
  end
127
163
 
128
164
  class FixnumLiteralNode < AST::Fixnum
@@ -3,6 +3,14 @@ module Duby::JVM::Types
3
3
  def prefix
4
4
  'f'
5
5
  end
6
+
7
+ def math_type
8
+ Float
9
+ end
10
+
11
+ def box_type
12
+ java.lang.Float
13
+ end
6
14
 
7
15
  def suffix
8
16
  'g'
@@ -42,6 +50,14 @@ module Duby::JVM::Types
42
50
  'd'
43
51
  end
44
52
 
53
+ def math_type
54
+ Double
55
+ end
56
+
57
+ def box_type
58
+ java.lang.Double
59
+ end
60
+
45
61
  def wide?
46
62
  true
47
63
  end
@@ -50,10 +50,49 @@ module Duby::JVM::Types
50
50
  Int
51
51
  end
52
52
 
53
+ def box_type
54
+ java.lang.Integer
55
+ end
56
+
53
57
  def jump_if(builder, op, label)
54
58
  builder.send "if_icmp#{op}", label
55
59
  end
56
60
 
61
+ def build_loop(parent, position, duby, block, first_value,
62
+ last_value, ascending, inclusive)
63
+ if ascending
64
+ comparison = "<"
65
+ op = "+="
66
+ else
67
+ comparison = ">"
68
+ op = "-="
69
+ end
70
+ comparison << "=" if inclusive
71
+ forloop = Duby::AST::Loop.new(parent, position, true, false) do |forloop|
72
+ first, last = duby.tmp, duby.tmp
73
+ init = duby.eval("#{first} = 0; #{last} = 0;")
74
+ init.children[-2].value = first_value
75
+ init.children[-1].value = last_value
76
+ forloop.init << init
77
+
78
+ var = (block.args.args || [])[0]
79
+ if var
80
+ forloop.pre << duby.eval(
81
+ "#{var.name} = #{first}", '', forloop, first, last)
82
+ end
83
+ forloop.post << duby.eval("#{first} #{op} 1")
84
+ [
85
+ Duby::AST::Condition.new(forloop, position) do |c|
86
+ [duby.eval("#{first} #{comparison} #{last}",
87
+ '', forloop, first, last)]
88
+ end,
89
+ nil
90
+ ]
91
+ end
92
+ forloop.body = block.body
93
+ forloop
94
+ end
95
+
57
96
  def add_intrinsics
58
97
  super
59
98
  math_operator('<<', 'shl')
@@ -63,14 +102,36 @@ module Duby::JVM::Types
63
102
  math_operator('&', 'and')
64
103
  math_operator('^', 'xor')
65
104
  unary_operator('~', 'not')
105
+
106
+ add_macro('downto', Int, Duby::AST.block_type) do |transformer, call|
107
+ build_loop(call.parent, call.position, transformer,
108
+ call.block, call.target, call.parameters[0], false, true)
109
+ end
110
+ add_macro('upto', Int, Duby::AST.block_type) do |transformer, call|
111
+ build_loop(call.parent, call.position, transformer,
112
+ call.block, call.target, call.parameters[0], true, true)
113
+ end
114
+ add_macro('times', Duby::AST.block_type) do |transformer, call|
115
+ build_loop(call.parent, call.position, transformer,
116
+ call.block, Duby::AST::fixnum(nil, call.position, 0),
117
+ call.target, true, false)
118
+ end
66
119
  end
67
120
  end
68
-
121
+
69
122
  class LongType < Number
70
123
  def prefix
71
124
  'l'
72
125
  end
73
126
 
127
+ def math_type
128
+ Long
129
+ end
130
+
131
+ def box_type
132
+ java.lang.Long
133
+ end
134
+
74
135
  def literal(builder, value)
75
136
  builder.ldc_long(value)
76
137
  end
@@ -107,4 +168,4 @@ module Duby::JVM::Types
107
168
  unary_operator('~', 'not')
108
169
  end
109
170
  end
110
- end
171
+ end
@@ -20,19 +20,19 @@ module Duby::JVM::Types
20
20
  def load(builder, index)
21
21
  builder.send "#{prefix}load", index
22
22
  end
23
-
23
+
24
24
  def store(builder, index)
25
25
  builder.send "#{prefix}store", index
26
26
  end
27
-
27
+
28
28
  def return(builder)
29
29
  builder.send "#{prefix}return"
30
30
  end
31
-
31
+
32
32
  def init_value(builder)
33
33
  builder.aconst_null
34
34
  end
35
-
35
+
36
36
  def intrinsics
37
37
  @intrinsics ||= begin
38
38
  @intrinsics = Hash.new {|h, k| h[k] = {}}
@@ -40,7 +40,7 @@ module Duby::JVM::Types
40
40
  @intrinsics
41
41
  end
42
42
  end
43
-
43
+
44
44
  def add_method(name, args, method_or_type=nil, &block)
45
45
  if block_given?
46
46
  method_or_type = Intrinsic.new(self, name, args,
@@ -56,15 +56,20 @@ module Duby::JVM::Types
56
56
  end
57
57
  end
58
58
 
59
- def declared_intrinsics
59
+ def declared_intrinsics(name=nil)
60
60
  methods = []
61
- intrinsics.each do |name, group|
61
+ all_intrinsics = if name.nil?
62
+ intrinsics
63
+ else
64
+ [[name, intrinsics[name]]]
65
+ end
66
+ all_intrinsics.each do |name, group|
62
67
  group.each do |args, method|
63
68
  methods << method
64
69
  end
65
70
  end
66
71
  interfaces.each do |interface|
67
- methods.concat(interface.declared_intrinsics)
72
+ methods.concat(interface.declared_intrinsics(name))
68
73
  end
69
74
  methods
70
75
  end
@@ -78,7 +83,7 @@ module Duby::JVM::Types
78
83
  end
79
84
  end
80
85
  end
81
-
86
+
82
87
  add_method('==', [Object], Boolean) do |compiler, call, expression|
83
88
  # Should this call Object.equals for consistency with Ruby?
84
89
  if expression
@@ -89,7 +94,7 @@ module Duby::JVM::Types
89
94
  end
90
95
  end
91
96
  end
92
-
97
+
93
98
  add_method('!=', [Object], Boolean) do |compiler, call, expression|
94
99
  # Should this call Object.equals for consistency with Ruby?
95
100
  if expression
@@ -102,7 +107,7 @@ module Duby::JVM::Types
102
107
  end
103
108
  end
104
109
  end
105
-
110
+
106
111
  class ArrayType
107
112
  def add_intrinsics
108
113
  super
@@ -119,7 +124,7 @@ module Duby::JVM::Types
119
124
 
120
125
  add_method('[]=',
121
126
  [Int, component_type],
122
- component_type) do |compiler, call, expression|
127
+ component_type) do |compiler, call, expression|
123
128
  call.target.compile(compiler, true)
124
129
  convert_args(compiler, call.parameters, [Int, component_type])
125
130
  component_type.astore(compiler.method)
@@ -127,24 +132,24 @@ module Duby::JVM::Types
127
132
  call.parameters[1].compile(compiler, true)
128
133
  end
129
134
  end
130
-
135
+
131
136
  add_method('length', [], Int) do |compiler, call, expression|
132
137
  call.target.compile(compiler, true)
133
- compiler.method.arraylength
138
+ compiler.method.arraylength
134
139
  end
135
-
140
+
136
141
  add_macro('each', Duby::AST.block_type) do |transformer, call|
137
142
  Duby::AST::Loop.new(call.parent,
138
143
  call.position, true, false) do |forloop|
139
144
  index = transformer.tmp
140
145
  array = transformer.tmp
141
-
146
+
142
147
  init = transformer.eval("#{index} = 0;#{array} = nil")
143
148
  array_assignment = init.children[-1]
144
149
  array_assignment.value = call.target
145
150
  call.target.parent = array_assignment
146
151
  forloop.init << init
147
-
152
+
148
153
  var = call.block.args.args[0]
149
154
  if var
150
155
  forloop.pre << transformer.eval(
@@ -163,7 +168,7 @@ module Duby::JVM::Types
163
168
  end
164
169
  end
165
170
  end
166
-
171
+
167
172
  class StringType < Type
168
173
  def add_intrinsics
169
174
  super
@@ -188,6 +193,23 @@ module Duby::JVM::Types
188
193
  compiler.method.invokevirtual String, "concat", [String, String]
189
194
  end
190
195
  end
196
+ add_method('[]', [Int], Char) do |compiler, call, expression|
197
+ if expression
198
+ call.target.compile(compiler, true)
199
+ call.parameters[0].compile(compiler, true)
200
+ compiler.method.invokevirtual String, "charAt", [Char, Int]
201
+ end
202
+ end
203
+ add_method('[]', [Int, Int], String) do |compiler, call, expression|
204
+ if expression
205
+ call.target.compile(compiler, true)
206
+ call.parameters[0].compile(compiler, true)
207
+ compiler.method.dup
208
+ call.parameters[1].compile(compiler, true)
209
+ compiler.method.iadd
210
+ compiler.method.invokevirtual String, "substring", [String, Int, Int]
211
+ end
212
+ end
191
213
  end
192
214
  end
193
215
 
@@ -199,12 +221,12 @@ module Duby::JVM::Types
199
221
  Duby::AST::Loop.new(call.parent,
200
222
  call.position, true, false) do |forloop|
201
223
  it = transformer.tmp
202
-
224
+
203
225
  assignment = transformer.eval("#{it} = foo.iterator")
204
226
  assignment.value.target = call.target
205
227
  call.target.parent = assignment.value
206
228
  forloop.init << assignment
207
-
229
+
208
230
  var = call.block.args.args[0]
209
231
  if var
210
232
  forloop.pre << transformer.eval(
@@ -221,7 +243,7 @@ module Duby::JVM::Types
221
243
  end
222
244
  end
223
245
  end
224
-
246
+
225
247
  class PrimitiveType
226
248
  # Primitives define their own intrinsics instead of getting the Object ones.
227
249
  def add_intrinsics