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.
- data/History.txt +7 -0
- data/README.txt +18 -7
- data/Rakefile +72 -0
- data/examples/ant/example-build.xml +7 -0
- data/examples/appengine/Rakefile +8 -67
- data/examples/appengine/Readme +4 -3
- data/examples/appengine/lib/duby/appengine_tasks.rb +173 -0
- data/examples/appengine/lib/duby/plugin/datastore.rb +92 -31
- data/examples/appengine/lib/duby_task.rb +61 -0
- data/examples/appengine/src/com/ribrdb/DubyApp.duby +32 -6
- data/examples/appengine/src/com/ribrdb/list.dhtml +2 -2
- data/examples/appengine/{config.ru → src/config.ru} +0 -0
- data/examples/bintrees.duby +66 -0
- data/examples/dynamic.duby +17 -0
- data/examples/fib.duby +3 -11
- data/examples/fields.duby +3 -3
- data/examples/fractal.duby +1 -3
- data/examples/sort_closure.duby +7 -0
- data/examples/swing.duby +11 -11
- data/javalib/duby-bootstrap.jar +0 -0
- data/javalib/dynalang-invoke-0.1.jar +0 -0
- data/lib/duby.rb +168 -35
- data/lib/duby/ast.rb +224 -27
- data/lib/duby/ast/call.rb +85 -25
- data/lib/duby/ast/class.rb +112 -28
- data/lib/duby/ast/flow.rb +65 -44
- data/lib/duby/ast/intrinsics.rb +223 -21
- data/lib/duby/ast/literal.rb +67 -16
- data/lib/duby/ast/local.rb +36 -40
- data/lib/duby/ast/method.rb +83 -67
- data/lib/duby/ast/structure.rb +105 -23
- data/lib/duby/compiler.rb +83 -28
- data/lib/duby/env.rb +33 -0
- data/lib/duby/jvm/base.rb +210 -0
- data/lib/duby/jvm/compiler.rb +293 -219
- data/lib/duby/jvm/method_lookup.rb +77 -67
- data/lib/duby/jvm/source_compiler.rb +250 -157
- data/lib/duby/jvm/source_generator/builder.rb +53 -49
- data/lib/duby/jvm/source_generator/loops.rb +9 -9
- data/lib/duby/jvm/source_generator/precompile.rb +35 -25
- data/lib/duby/jvm/typer.rb +19 -10
- data/lib/duby/jvm/types.rb +127 -68
- data/lib/duby/jvm/types/basic_types.rb +26 -13
- data/lib/duby/jvm/types/enumerable.rb +6 -4
- data/lib/duby/jvm/types/factory.rb +49 -13
- data/lib/duby/jvm/types/floats.rb +16 -0
- data/lib/duby/jvm/types/integers.rb +63 -2
- data/lib/duby/jvm/types/intrinsics.rb +43 -21
- data/lib/duby/jvm/types/methods.rb +326 -86
- data/lib/duby/jvm/types/number.rb +3 -0
- data/lib/duby/nbcompiler.rb +1 -1
- data/lib/duby/plugin/edb.rb +1 -1
- data/lib/duby/plugin/java.rb +10 -1
- data/lib/duby/transform.rb +134 -46
- data/lib/duby/typer.rb +75 -50
- data/test/test_ast.rb +106 -106
- data/test/test_compilation.rb +46 -32
- data/test/test_env.rb +42 -0
- data/test/test_java_typer.rb +35 -51
- data/test/test_javac_compiler.rb +4 -1
- data/test/test_jvm_compiler.rb +564 -133
- data/test/test_typer.rb +68 -92
- metadata +37 -21
- data/examples/README +0 -16
- data/lib/duby/c/compiler.rb +0 -134
- data/lib/duby/old/compiler_old.rb +0 -845
- data/lib/duby/old/declaration.rb +0 -72
- data/lib/duby/old/mapper.rb +0 -72
- data/lib/duby/old/signature.rb +0 -52
- data/lib/duby/old/typer_old.rb +0 -163
- data/lib/duby/plugin/math.rb +0 -84
- 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
|
-
|
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
|
-
|
42
|
+
add_macro('all?', &all_proc)
|
43
|
+
add_macro('all?', Duby::AST.block_type, &all_proc)
|
43
44
|
|
44
|
-
|
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
|
-
|
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(
|
93
|
+
@known_types[name] = Type.new(get_mirror(full_name))
|
78
94
|
rescue NameError
|
79
|
-
unless
|
80
|
-
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|