duby 0.0.2-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 (77) hide show
  1. data/History.txt +8 -0
  2. data/README.txt +39 -0
  3. data/Rakefile +13 -0
  4. data/bin/duby +9 -0
  5. data/bin/dubyc +9 -0
  6. data/bin/dubyp +9 -0
  7. data/examples/README +16 -0
  8. data/examples/appengine/Rakefile +72 -0
  9. data/examples/appengine/Readme +27 -0
  10. data/examples/appengine/config.ru +7 -0
  11. data/examples/appengine/lib/duby/plugin/datastore.rb +171 -0
  12. data/examples/appengine/src/com/google/appengine/ext/duby/db/Model.duby +132 -0
  13. data/examples/appengine/src/com/ribrdb/DubyApp.duby +28 -0
  14. data/examples/appengine/src/com/ribrdb/list.dhtml +15 -0
  15. data/examples/construction.duby +8 -0
  16. data/examples/edb.duby +3 -0
  17. data/examples/fib.duby +24 -0
  18. data/examples/fields.duby +22 -0
  19. data/examples/fractal.duby +57 -0
  20. data/examples/java_thing.duby +13 -0
  21. data/examples/simple_class.duby +12 -0
  22. data/examples/swing.duby +20 -0
  23. data/examples/tak.duby +15 -0
  24. data/examples/test.edb +9 -0
  25. data/javalib/JRubyParser.jar +0 -0
  26. data/lib/duby.rb +168 -0
  27. data/lib/duby/ast.rb +386 -0
  28. data/lib/duby/ast/call.rb +145 -0
  29. data/lib/duby/ast/class.rb +154 -0
  30. data/lib/duby/ast/flow.rb +332 -0
  31. data/lib/duby/ast/intrinsics.rb +56 -0
  32. data/lib/duby/ast/literal.rb +97 -0
  33. data/lib/duby/ast/local.rb +92 -0
  34. data/lib/duby/ast/method.rb +244 -0
  35. data/lib/duby/ast/structure.rb +62 -0
  36. data/lib/duby/ast/type.rb +93 -0
  37. data/lib/duby/c/compiler.rb +134 -0
  38. data/lib/duby/compiler.rb +282 -0
  39. data/lib/duby/jvm/compiler.rb +766 -0
  40. data/lib/duby/jvm/method_lookup.rb +193 -0
  41. data/lib/duby/jvm/source_compiler.rb +605 -0
  42. data/lib/duby/jvm/source_generator/builder.rb +387 -0
  43. data/lib/duby/jvm/source_generator/loops.rb +110 -0
  44. data/lib/duby/jvm/source_generator/precompile.rb +170 -0
  45. data/lib/duby/jvm/source_generator/typer.rb +11 -0
  46. data/lib/duby/jvm/typer.rb +131 -0
  47. data/lib/duby/jvm/types.rb +331 -0
  48. data/lib/duby/jvm/types/basic_types.rb +19 -0
  49. data/lib/duby/jvm/types/boolean.rb +11 -0
  50. data/lib/duby/jvm/types/enumerable.rb +63 -0
  51. data/lib/duby/jvm/types/factory.rb +155 -0
  52. data/lib/duby/jvm/types/floats.rb +70 -0
  53. data/lib/duby/jvm/types/integers.rb +110 -0
  54. data/lib/duby/jvm/types/intrinsics.rb +230 -0
  55. data/lib/duby/jvm/types/literals.rb +82 -0
  56. data/lib/duby/jvm/types/methods.rb +381 -0
  57. data/lib/duby/jvm/types/number.rb +92 -0
  58. data/lib/duby/nbcompiler.rb +29 -0
  59. data/lib/duby/old/compiler_old.rb +845 -0
  60. data/lib/duby/old/declaration.rb +72 -0
  61. data/lib/duby/old/mapper.rb +72 -0
  62. data/lib/duby/old/signature.rb +52 -0
  63. data/lib/duby/old/typer_old.rb +163 -0
  64. data/lib/duby/plugin/edb.rb +25 -0
  65. data/lib/duby/plugin/java.rb +42 -0
  66. data/lib/duby/plugin/math.rb +84 -0
  67. data/lib/duby/transform.rb +1028 -0
  68. data/lib/duby/typer.rb +369 -0
  69. data/test/TestUser.class +0 -0
  70. data/test/test_ast.rb +391 -0
  71. data/test/test_compilation.rb +98 -0
  72. data/test/test_java_typer.rb +199 -0
  73. data/test/test_javac_compiler.rb +58 -0
  74. data/test/test_jvm_compiler.rb +1770 -0
  75. data/test/test_math_plugin.rb +87 -0
  76. data/test/test_typer.rb +246 -0
  77. metadata +156 -0
@@ -0,0 +1,19 @@
1
+ module Duby::JVM::Types
2
+ Boolean = BooleanType.new(Java::boolean, java.lang.Boolean)
3
+ Byte = IntegerType.new(Java::byte, java.lang.Byte)
4
+ Char = IntegerType.new(Java::char, java.lang.Character)
5
+ Short = IntegerType.new(Java::short, java.lang.Short)
6
+ Int = IntegerType.new(Java::int, java.lang.Integer)
7
+ Long = LongType.new(Java::long, java.lang.Long)
8
+ Float = FloatType.new(Java::float, java.lang.Float)
9
+ Double = DoubleType.new(Java::double, java.lang.Double)
10
+
11
+ Object = Type.new(Java::JavaLang.Object)
12
+ String = StringType.new(Java::JavaLang.String)
13
+ Iterable = IterableType.new(Java::JavaLang.Iterable)
14
+
15
+ Void = VoidType.new
16
+ Null = NullType.new
17
+
18
+ TYPE_ORDERING = [Byte, Short, Int, Long, Float, Double]
19
+ end
@@ -0,0 +1,11 @@
1
+ module Duby::JVM::Types
2
+ class BooleanType < PrimitiveType
3
+ def init_value(builder)
4
+ builder.iconst_0
5
+ end
6
+
7
+ def prefix
8
+ 'i'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,63 @@
1
+ module Duby::JVM::Types
2
+ class Type
3
+ def expand_each(transformer, call)
4
+ arg_types = [Duby::AST.block_type]
5
+ code = intrinsics['each'][arg_types].return_type
6
+ code.inline(transformer, call)
7
+ end
8
+
9
+ def add_enumerable_macros
10
+ add_macro('all?') do |transformer, call|
11
+ if !call.block
12
+ # We need to create a block that just returns the item passed to it
13
+ # First get a new temp for the block argument
14
+ var = transformer.tmp
15
+ # Parse a fake function call to create a block. Then pull of the
16
+ # block and attach it to the real call.
17
+ call.block = transformer.eval("foo {|#{var}| #{var}}").block
18
+ end
19
+
20
+ # Now that we've got a block we can transform it into a Loop.
21
+ forloop = expand_each(transformer, call)
22
+
23
+ # Start adding stuff to the loop.
24
+ # At the beginning of the loop we create a temp initialized to true
25
+ all = transformer.tmp
26
+ forloop.init << transformer.eval("#{all} = true")
27
+
28
+ # Now we want to wrap the body of the loop. Start off by using
29
+ # foo as a placeholder.
30
+ body = transformer.eval(
31
+ "unless foo;#{all} = false;break;end", '', forloop)
32
+ # Then replace foo with the real body.
33
+ body.condition.predicate = call.block.body
34
+ # And finally patch the new body back into the forloop.
35
+ forloop.body = call.block.body.parent = body
36
+
37
+ # Loops don't have a return value, so we need somewhere to
38
+ # put the result.
39
+ result = Duby::AST::Body.new(call.parent, call.position)
40
+ result << forloop << transformer.eval("#{all}", '', nil, all)
41
+ end
42
+ intrinsics['all?'][[Duby::AST.block_type]] = intrinsics['all?'][[]]
43
+
44
+ add_macro('any?') do |transformer, call|
45
+ if !call.block
46
+ var = transformer.tmp
47
+ call.block = transformer.eval("foo {|#{var}| #{var}}").block
48
+ end
49
+ forloop = expand_each(transformer, call)
50
+ any = transformer.tmp
51
+ forloop.init << transformer.eval("#{any} = false")
52
+ body = transformer.eval(
53
+ "if foo;#{any} = true;break;end", '', forloop)
54
+ body.condition.predicate = call.block.body
55
+ forloop.body = call.block.body.parent = body
56
+
57
+ result = Duby::AST::Body.new(call.parent, call.position)
58
+ result << forloop << transformer.eval("#{any}", '', nil, any)
59
+ end
60
+ intrinsics['any?'][[Duby::AST.block_type]] = intrinsics['any?'][[]]
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,155 @@
1
+ module Duby::JVM::Types
2
+ class TypeFactory
3
+ BASIC_TYPES = {
4
+ "boolean" => Boolean,
5
+ "byte" => Byte,
6
+ "char" => Char,
7
+ "short" => Short,
8
+ "int" => Int,
9
+ "long" => Long,
10
+ "float" => Float,
11
+ "double" => Double,
12
+ "fixnum" => Int,
13
+ "string" => String,
14
+ "java.lang.String" => String,
15
+ "String" => String,
16
+ "java.lang.Object" => Object,
17
+ "Object" => Object,
18
+ "java.lang.Iterable" => Iterable,
19
+ "Iterable" => Iterable,
20
+ "void" => Void,
21
+ "notype" => Void,
22
+ "null" => Null
23
+ }.freeze
24
+
25
+ attr_accessor :package
26
+ attr_reader :known_types
27
+
28
+ class ParanoidHash < Hash
29
+ def []=(k, v)
30
+ raise ArgumentError, "Can't store nil for key #{k.inspect}" if v.nil?
31
+ super(k, v)
32
+ end
33
+ end
34
+
35
+ def initialize(filename='')
36
+ @known_types = ParanoidHash.new
37
+ @known_types.update(BASIC_TYPES)
38
+ @declarations = []
39
+ @package = File.dirname(filename).tr('/', '.')
40
+ @package.sub! /^\.+/, ''
41
+ @package = nil if @package.empty?
42
+ end
43
+
44
+ def define_types(builder)
45
+ @declarations.each do |declaration|
46
+ declaration.define(builder)
47
+ end
48
+ end
49
+
50
+ def type(name, array=false, meta=false)
51
+ type = basic_type(name)
52
+ type = type.meta if meta
53
+ type = type.array_type if array
54
+ return type
55
+ end
56
+
57
+ def basic_type(name)
58
+ if name.kind_of?(Type) || name.kind_of?(NarrowingType)
59
+ return name.basic_type
60
+ end
61
+ orig = name
62
+ if name.kind_of? Java::JavaClass
63
+ if name.array?
64
+ return type(name.component_type, true)
65
+ else
66
+ name = name.name
67
+ end
68
+ elsif name.respond_to? :java_class
69
+ name = name.java_class.name
70
+ end
71
+ name = name.to_s unless name.kind_of?(::String)
72
+ return @known_types[name].basic_type if @known_types[name]
73
+ raise ArgumentError, "Bad Type #{orig}" if name =~ /Java::/
74
+ raise ArgumentError, "Bad Type #{orig.inspect}" if name == '' || name.nil?
75
+ full_name = name
76
+ begin
77
+ @known_types[name] = Type.new(Java::JavaClass.for_name(full_name))
78
+ rescue NameError
79
+ unless full_name.include? '.'
80
+ full_name = "java.lang.#{full_name}"
81
+ retry
82
+ end
83
+ raise $!
84
+ end
85
+ end
86
+
87
+ def declare_type(node)
88
+ if node.kind_of? ::String
89
+ name = node
90
+ node = nil
91
+ else
92
+ name = node.name
93
+ end
94
+
95
+ if Duby::AST::InterfaceDeclaration === node
96
+ @known_types[name] = InterfaceDefinition.new(name, node)
97
+ elsif @known_types.include? name
98
+ existing = @known_types[name]
99
+ existing.node ||= node
100
+ existing
101
+ else
102
+ full_name = name
103
+ if !name.include?('.') && package
104
+ full_name = "#{package}.#{name}"
105
+ end
106
+ @known_types[full_name] = TypeDefinition.new(full_name, node)
107
+ @known_types[name] = @known_types[full_name]
108
+ end
109
+ end
110
+
111
+ def alias(from, to)
112
+ @known_types[from] = type(to)
113
+ end
114
+
115
+ def no_type
116
+ Void
117
+ end
118
+
119
+ def fixnum(parent, line_number, literal)
120
+ FixnumLiteralNode.new(parent, line_number, literal)
121
+ end
122
+
123
+ def float(parent, line_number, literal)
124
+ FloatLiteralNode.new(parent, line_number, literal)
125
+ end
126
+ end
127
+
128
+ class FixnumLiteralNode < AST::Fixnum
129
+ def infer(typer)
130
+ return @inferred_type if resolved?
131
+ resolved!
132
+ @inferred_type = FixnumLiteral.new(@literal)
133
+ end
134
+
135
+ def compile(compiler, expression)
136
+ if expression
137
+ inferred_type.literal(compiler.method, @literal)
138
+ end
139
+ end
140
+ end
141
+
142
+ class FloatLiteralNode < AST::Float
143
+ def infer(typer)
144
+ return @inferred_type if resolved?
145
+ resolved!
146
+ @inferred_type = FloatLiteral.new(@literal)
147
+ end
148
+
149
+ def compile(compiler, expression)
150
+ if expression
151
+ inferred_type.literal(compiler.method, @literal)
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,70 @@
1
+ module Duby::JVM::Types
2
+ class FloatType < Number
3
+ def prefix
4
+ 'f'
5
+ end
6
+
7
+ def suffix
8
+ 'g'
9
+ end
10
+
11
+ def init_value(builder)
12
+ builder.fconst_0
13
+ end
14
+
15
+ def literal(builder, value)
16
+ case value
17
+ when 0.0
18
+ builder.fconst_0
19
+ when 1.0
20
+ builder.fconst_1
21
+ when 2.0
22
+ builder.fconst_2
23
+ else
24
+ builder.ldc_float(value)
25
+ end
26
+ end
27
+
28
+ def widen(builder, type)
29
+ case type
30
+ when Float
31
+ # Do nothing
32
+ when Double
33
+ builder.f2d
34
+ else
35
+ raise ArgumentError, "Invalid widening conversion from Int to #{type}"
36
+ end
37
+ end
38
+ end
39
+
40
+ class DoubleType < FloatType
41
+ def prefix
42
+ 'd'
43
+ end
44
+
45
+ def wide?
46
+ true
47
+ end
48
+
49
+ def init_value(builder)
50
+ builder.dconst_0
51
+ end
52
+
53
+ def literal(builder, value)
54
+ case value
55
+ when 0.0
56
+ builder.dconst_0
57
+ when 1.0
58
+ builder.dconst_1
59
+ else
60
+ builder.ldc_double(value)
61
+ end
62
+ end
63
+
64
+ def widen(builder, type)
65
+ if type != Double
66
+ raise ArgumentError, "Invalid widening conversion from Int to #{type}"
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,110 @@
1
+ class BiteScript::MethodBuilder
2
+ def inot
3
+ iconst_m1
4
+ ixor
5
+ end
6
+
7
+ def lnot
8
+ # TODO would any of these be faster?
9
+ # iconst_m1; i2l
10
+ # lconst_1; lneg
11
+ ldc_long(-1)
12
+ ixor
13
+ end
14
+ end
15
+
16
+ module Duby::JVM::Types
17
+ class IntegerType < Number
18
+ def literal(builder, value)
19
+ builder.push_int(value)
20
+ end
21
+
22
+ def init_value(builder)
23
+ builder.iconst_0
24
+ end
25
+
26
+ def load(builder, index)
27
+ builder.iload(index)
28
+ end
29
+
30
+ def widen(builder, type)
31
+ case type
32
+ when Byte, Short, Int
33
+ # do nothing
34
+ when Long
35
+ builder.i2l
36
+ when Float
37
+ builder.i2f
38
+ when Double
39
+ builder.i2d
40
+ else
41
+ raise ArgumentError, "Invalid widening conversion from #{name} to #{type}"
42
+ end
43
+ end
44
+
45
+ def prefix
46
+ 'i'
47
+ end
48
+
49
+ def math_type
50
+ Int
51
+ end
52
+
53
+ def jump_if(builder, op, label)
54
+ builder.send "if_icmp#{op}", label
55
+ end
56
+
57
+ def add_intrinsics
58
+ super
59
+ math_operator('<<', 'shl')
60
+ math_operator('>>', 'shr')
61
+ math_operator('>>>', 'ushr')
62
+ math_operator('|', 'or')
63
+ math_operator('&', 'and')
64
+ math_operator('^', 'xor')
65
+ unary_operator('~', 'not')
66
+ end
67
+ end
68
+
69
+ class LongType < Number
70
+ def prefix
71
+ 'l'
72
+ end
73
+
74
+ def literal(builder, value)
75
+ builder.ldc_long(value)
76
+ end
77
+
78
+ def init_value(builder)
79
+ builder.lconst_0
80
+ end
81
+
82
+ def wide?
83
+ true
84
+ end
85
+
86
+ def widen(builder, type)
87
+ case type
88
+ when Long
89
+ # do nothing
90
+ when Float
91
+ builder.l2f
92
+ when Double
93
+ builder.l2d
94
+ else
95
+ raise ArgumentError, "Invalid widening conversion from Int to #{type}"
96
+ end
97
+ end
98
+
99
+ def add_intrinsics
100
+ super
101
+ math_operator('<<', 'shl')
102
+ math_operator('>>', 'shr')
103
+ math_operator('>>>', 'ushr')
104
+ math_operator('|', 'or')
105
+ math_operator('&', 'and')
106
+ math_operator('^', 'xor')
107
+ unary_operator('~', 'not')
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,230 @@
1
+ require 'bitescript'
2
+ require 'duby/jvm/types/enumerable'
3
+
4
+ class BiteScript::MethodBuilder
5
+ def op_to_bool
6
+ done_label = label
7
+ true_label = label
8
+
9
+ yield(true_label)
10
+ iconst_0
11
+ goto(done_label)
12
+ true_label.set!
13
+ iconst_1
14
+ done_label.set!
15
+ end
16
+ end
17
+
18
+ module Duby::JVM::Types
19
+ class Type
20
+ def load(builder, index)
21
+ builder.send "#{prefix}load", index
22
+ end
23
+
24
+ def store(builder, index)
25
+ builder.send "#{prefix}store", index
26
+ end
27
+
28
+ def return(builder)
29
+ builder.send "#{prefix}return"
30
+ end
31
+
32
+ def init_value(builder)
33
+ builder.aconst_null
34
+ end
35
+
36
+ def intrinsics
37
+ @intrinsics ||= begin
38
+ @intrinsics = Hash.new {|h, k| h[k] = {}}
39
+ add_intrinsics
40
+ @intrinsics
41
+ end
42
+ end
43
+
44
+ def add_method(name, args, method_or_type=nil, &block)
45
+ if block_given?
46
+ method_or_type = Intrinsic.new(self, name, args,
47
+ method_or_type, &block)
48
+ end
49
+ intrinsics[name][args] = method_or_type
50
+ end
51
+
52
+ def add_macro(name, *args, &block)
53
+ type = Duby::AST::InlineCode.new(&block)
54
+ intrinsics[name][args] = Intrinsic.new(self, name, args, type) do
55
+ raise "Macro should be expanded, no called!"
56
+ end
57
+ end
58
+
59
+ def declared_intrinsics
60
+ methods = []
61
+ intrinsics.each do |name, group|
62
+ group.each do |args, method|
63
+ methods << method
64
+ end
65
+ end
66
+ interfaces.each do |interface|
67
+ methods.concat(interface.declared_intrinsics)
68
+ end
69
+ methods
70
+ end
71
+
72
+ def add_intrinsics
73
+ add_method('nil?', [], Boolean) do |compiler, call, expression|
74
+ if expression
75
+ call.target.compile(compiler, true)
76
+ compiler.method.op_to_bool do |target|
77
+ compiler.method.ifnull(target)
78
+ end
79
+ end
80
+ end
81
+
82
+ add_method('==', [Object], Boolean) do |compiler, call, expression|
83
+ # Should this call Object.equals for consistency with Ruby?
84
+ if expression
85
+ call.target.compile(compiler, true)
86
+ call.parameters[0].compile(compiler, true)
87
+ compiler.method.op_to_bool do |target|
88
+ compiler.method.if_acmpeq(target)
89
+ end
90
+ end
91
+ end
92
+
93
+ add_method('!=', [Object], Boolean) do |compiler, call, expression|
94
+ # Should this call Object.equals for consistency with Ruby?
95
+ if expression
96
+ call.target.compile(compiler, true)
97
+ call.parameters[0].compile(compiler, true)
98
+ compiler.method.op_to_bool do |target|
99
+ compiler.method.if_acmpne(target)
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ class ArrayType
107
+ def add_intrinsics
108
+ super
109
+ add_enumerable_macros
110
+
111
+ add_method(
112
+ '[]', [Int], component_type) do |compiler, call, expression|
113
+ if expression
114
+ call.target.compile(compiler, true)
115
+ call.parameters[0].compile(compiler, true)
116
+ component_type.aload(compiler.method)
117
+ end
118
+ end
119
+
120
+ add_method('[]=',
121
+ [Int, component_type],
122
+ component_type) do |compiler, call, expression|
123
+ call.target.compile(compiler, true)
124
+ convert_args(compiler, call.parameters, [Int, component_type])
125
+ component_type.astore(compiler.method)
126
+ if expression
127
+ call.parameters[1].compile(compiler, true)
128
+ end
129
+ end
130
+
131
+ add_method('length', [], Int) do |compiler, call, expression|
132
+ call.target.compile(compiler, true)
133
+ compiler.method.arraylength
134
+ end
135
+
136
+ add_macro('each', Duby::AST.block_type) do |transformer, call|
137
+ Duby::AST::Loop.new(call.parent,
138
+ call.position, true, false) do |forloop|
139
+ index = transformer.tmp
140
+ array = transformer.tmp
141
+
142
+ init = transformer.eval("#{index} = 0;#{array} = nil")
143
+ array_assignment = init.children[-1]
144
+ array_assignment.value = call.target
145
+ call.target.parent = array_assignment
146
+ forloop.init << init
147
+
148
+ var = call.block.args.args[0]
149
+ if var
150
+ forloop.pre << transformer.eval(
151
+ "#{var.name} = #{array}[#{index}]", '', forloop, index, array)
152
+ end
153
+ forloop.post << transformer.eval("#{index} += 1")
154
+ call.block.body.parent = forloop if call.block.body
155
+ [
156
+ Duby::AST::Condition.new(forloop, call.position) do |c|
157
+ [transformer.eval("#{index} < #{array}.length",
158
+ '', forloop, index, array)]
159
+ end,
160
+ call.block.body
161
+ ]
162
+ end
163
+ end
164
+ end
165
+ end
166
+
167
+ class StringType < Type
168
+ def add_intrinsics
169
+ super
170
+ add_method('+', [String], String) do |compiler, call, expression|
171
+ if expression
172
+ java_method('concat', String).call(compiler, call, expression)
173
+ end
174
+ end
175
+ add_method('+', [Int], String) do |compiler, call, expression|
176
+ if expression
177
+ call.target.compile(compiler, true)
178
+ call.parameters[0].compile(compiler, true)
179
+ compiler.method.invokestatic String, "valueOf", [String, Int]
180
+ compiler.method.invokevirtual String, "concat", [String, String]
181
+ end
182
+ end
183
+ add_method('+', [Float], String) do |compiler, call, expression|
184
+ if expression
185
+ call.target.compile(compiler, true)
186
+ call.parameters[0].compile(compiler, true)
187
+ compiler.method.invokestatic String, "valueOf", [String, Float]
188
+ compiler.method.invokevirtual String, "concat", [String, String]
189
+ end
190
+ end
191
+ end
192
+ end
193
+
194
+ class IterableType < Type
195
+ def add_intrinsics
196
+ super
197
+ add_enumerable_macros
198
+ add_macro('each', Duby::AST.block_type) do |transformer, call|
199
+ Duby::AST::Loop.new(call.parent,
200
+ call.position, true, false) do |forloop|
201
+ it = transformer.tmp
202
+
203
+ assignment = transformer.eval("#{it} = foo.iterator")
204
+ assignment.value.target = call.target
205
+ call.target.parent = assignment.value
206
+ forloop.init << assignment
207
+
208
+ var = call.block.args.args[0]
209
+ if var
210
+ forloop.pre << transformer.eval(
211
+ "#{var.name} = #{it}.next", '', forloop, it)
212
+ end
213
+ call.block.body.parent = forloop if call.block.body
214
+ [
215
+ Duby::AST::Condition.new(forloop, call.position) do |c|
216
+ [transformer.eval("#{it}.hasNext", '', forloop, it)]
217
+ end,
218
+ call.block.body
219
+ ]
220
+ end
221
+ end
222
+ end
223
+ end
224
+
225
+ class PrimitiveType
226
+ # Primitives define their own intrinsics instead of getting the Object ones.
227
+ def add_intrinsics
228
+ end
229
+ end
230
+ end