duby 0.0.1
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 +4 -0
- data/Manifest.txt +68 -0
- data/README.txt +31 -0
- data/Rakefile +37 -0
- data/bin/duby +9 -0
- data/bin/dubyc +9 -0
- data/bin/dubyp +9 -0
- data/examples/appengine/src/com/google/appengine/ext/duby/db/Model.duby +132 -0
- data/examples/appengine/src/com/ribrdb/DubyApp.duby +28 -0
- data/examples/bench_fractal.duby +57 -0
- data/examples/construction.duby +8 -0
- data/examples/edb.duby +3 -0
- data/examples/fib.duby +24 -0
- data/examples/fields.duby +22 -0
- data/examples/java_thing.duby +13 -0
- data/examples/simple_class.duby +12 -0
- data/examples/swing.duby +20 -0
- data/examples/tak.duby +15 -0
- data/javalib/JRubyParser.jar +0 -0
- data/lib/duby.rb +170 -0
- data/lib/duby/ast.rb +340 -0
- data/lib/duby/ast/call.rb +73 -0
- data/lib/duby/ast/class.rb +145 -0
- data/lib/duby/ast/flow.rb +328 -0
- data/lib/duby/ast/intrinsics.rb +46 -0
- data/lib/duby/ast/literal.rb +93 -0
- data/lib/duby/ast/local.rb +77 -0
- data/lib/duby/ast/method.rb +187 -0
- data/lib/duby/ast/structure.rb +44 -0
- data/lib/duby/ast/type.rb +93 -0
- data/lib/duby/c/compiler.rb +134 -0
- data/lib/duby/compiler.rb +261 -0
- data/lib/duby/jvm/compiler.rb +684 -0
- data/lib/duby/jvm/method_lookup.rb +185 -0
- data/lib/duby/jvm/source_compiler.rb +516 -0
- data/lib/duby/jvm/source_generator/builder.rb +368 -0
- data/lib/duby/jvm/source_generator/loops.rb +132 -0
- data/lib/duby/jvm/source_generator/precompile.rb +154 -0
- data/lib/duby/jvm/source_generator/typer.rb +11 -0
- data/lib/duby/jvm/typer.rb +118 -0
- data/lib/duby/jvm/types.rb +326 -0
- data/lib/duby/jvm/types/basic_types.rb +18 -0
- data/lib/duby/jvm/types/boolean.rb +11 -0
- data/lib/duby/jvm/types/factory.rb +151 -0
- data/lib/duby/jvm/types/floats.rb +70 -0
- data/lib/duby/jvm/types/integers.rb +110 -0
- data/lib/duby/jvm/types/intrinsics.rb +157 -0
- data/lib/duby/jvm/types/literals.rb +82 -0
- data/lib/duby/jvm/types/methods.rb +344 -0
- data/lib/duby/jvm/types/number.rb +92 -0
- data/lib/duby/nbcompiler.rb +29 -0
- data/lib/duby/old/compiler_old.rb +845 -0
- data/lib/duby/old/declaration.rb +72 -0
- data/lib/duby/old/mapper.rb +72 -0
- data/lib/duby/old/signature.rb +52 -0
- data/lib/duby/old/typer_old.rb +163 -0
- data/lib/duby/plugin/edb.rb +25 -0
- data/lib/duby/plugin/java.rb +42 -0
- data/lib/duby/plugin/math.rb +84 -0
- data/lib/duby/transform.rb +908 -0
- data/lib/duby/typer.rb +359 -0
- data/test/test_ast.rb +391 -0
- data/test/test_compilation.rb +98 -0
- data/test/test_java_typer.rb +199 -0
- data/test/test_javac_compiler.rb +57 -0
- data/test/test_jvm_compiler.rb +1459 -0
- data/test/test_math_plugin.rb +87 -0
- data/test/test_typer.rb +246 -0
- metadata +155 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
module Duby::AST
|
2
|
+
class Print < Node
|
3
|
+
attr_accessor :parameters
|
4
|
+
attr_accessor :println
|
5
|
+
|
6
|
+
def initialize(parent, line_number, println, &block)
|
7
|
+
super(parent, line_number, &block)
|
8
|
+
@parameters = children
|
9
|
+
@println = println
|
10
|
+
end
|
11
|
+
|
12
|
+
def infer(typer)
|
13
|
+
if parameters.size > 0
|
14
|
+
resolved = parameters.select {|param| typer.infer(param); param.resolved?}
|
15
|
+
resolved! if resolved.size == parameters.size
|
16
|
+
else
|
17
|
+
resolved!
|
18
|
+
end
|
19
|
+
typer.no_type
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
defmacro('puts') do |transformer, fcall, parent|
|
24
|
+
Print.new(parent, fcall.position, true) do |print|
|
25
|
+
if fcall.respond_to?(:args_node) && fcall.args_node
|
26
|
+
fcall.args_node.child_nodes.map do |arg|
|
27
|
+
transformer.transform(arg, print)
|
28
|
+
end
|
29
|
+
else
|
30
|
+
[]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
defmacro('print') do |transformer, fcall, parent|
|
36
|
+
Print.new(parent, fcall.position, false) do |print|
|
37
|
+
if fcall.respond_to?(:args_node) && fcall.args_node
|
38
|
+
fcall.args_node.child_nodes.map do |arg|
|
39
|
+
transformer.transform(arg, print)
|
40
|
+
end
|
41
|
+
else
|
42
|
+
[]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module Duby::AST
|
2
|
+
class Array < Node
|
3
|
+
def initialize(parent, line_number, &block)
|
4
|
+
super(parent, line_number, &block)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class Fixnum < Node
|
9
|
+
include Literal
|
10
|
+
|
11
|
+
def initialize(parent, line_number, literal)
|
12
|
+
super(parent, line_number)
|
13
|
+
@literal = literal
|
14
|
+
end
|
15
|
+
|
16
|
+
def infer(typer)
|
17
|
+
return @inferred_type if resolved?
|
18
|
+
resolved!
|
19
|
+
@inferred_type = typer.fixnum_type
|
20
|
+
end
|
21
|
+
|
22
|
+
def ==(other)
|
23
|
+
@literal == other.literal
|
24
|
+
end
|
25
|
+
|
26
|
+
def eql?(other)
|
27
|
+
self.class == other.class && @literal.eql?(other.literal)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Float < Node
|
32
|
+
include Literal
|
33
|
+
|
34
|
+
def initialize(parent, line_number, literal)
|
35
|
+
super(parent, line_number)
|
36
|
+
@literal = literal
|
37
|
+
end
|
38
|
+
|
39
|
+
def infer(typer)
|
40
|
+
return @inferred_type if resolved?
|
41
|
+
resolved!
|
42
|
+
@inferred_type = typer.float_type
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Hash < Node; end
|
47
|
+
|
48
|
+
class String < Node
|
49
|
+
include Literal
|
50
|
+
|
51
|
+
def initialize(parent, line_number, literal)
|
52
|
+
super(parent, line_number)
|
53
|
+
@literal = literal
|
54
|
+
end
|
55
|
+
|
56
|
+
def infer(typer)
|
57
|
+
return @inferred_type if resolved?
|
58
|
+
resolved!
|
59
|
+
@inferred_type ||= typer.string_type
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class Symbol < Node; end
|
64
|
+
|
65
|
+
class Boolean < Node
|
66
|
+
include Literal
|
67
|
+
|
68
|
+
def initialize(parent, line_number, literal)
|
69
|
+
super(parent, line_number)
|
70
|
+
@literal = literal
|
71
|
+
end
|
72
|
+
|
73
|
+
def infer(typer)
|
74
|
+
return @inferred_type if resolved?
|
75
|
+
resolved!
|
76
|
+
@inferred_type ||= typer.boolean_type
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class Null < Node
|
81
|
+
include Literal
|
82
|
+
|
83
|
+
def initialize(parent, line_number)
|
84
|
+
super(parent, line_number)
|
85
|
+
end
|
86
|
+
|
87
|
+
def infer(typer)
|
88
|
+
return @inferred_type if resolved?
|
89
|
+
resolved!
|
90
|
+
@inferred_type ||= typer.null_type
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Duby::AST
|
2
|
+
class LocalDeclaration < Node
|
3
|
+
include Named
|
4
|
+
include Typed
|
5
|
+
include Scoped
|
6
|
+
|
7
|
+
def initialize(parent, line_number, name, &block)
|
8
|
+
super(parent, line_number, &block)
|
9
|
+
@name = name
|
10
|
+
@type = children[0]
|
11
|
+
end
|
12
|
+
|
13
|
+
def infer(typer)
|
14
|
+
unless resolved?
|
15
|
+
resolved!
|
16
|
+
@inferred_type = typer.known_types[type] || type
|
17
|
+
if @inferred_type
|
18
|
+
resolved!
|
19
|
+
typer.learn_local_type(scope, name, @inferred_type)
|
20
|
+
else
|
21
|
+
typer.defer(self)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
@inferred_type
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class LocalAssignment < Node
|
29
|
+
include Named
|
30
|
+
include Valued
|
31
|
+
include Scoped
|
32
|
+
|
33
|
+
def initialize(parent, line_number, name, &block)
|
34
|
+
super(parent, line_number, children, &block)
|
35
|
+
@value = children[0]
|
36
|
+
@name = name
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_s
|
40
|
+
"LocalAssignment(name = #{name}, scope = #{scope})"
|
41
|
+
end
|
42
|
+
|
43
|
+
def infer(typer)
|
44
|
+
unless @inferred_type
|
45
|
+
@inferred_type = typer.learn_local_type(scope, name, typer.infer(value))
|
46
|
+
|
47
|
+
@inferred_type ? resolved! : typer.defer(self)
|
48
|
+
end
|
49
|
+
|
50
|
+
@inferred_type
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class Local < Node
|
55
|
+
include Named
|
56
|
+
include Scoped
|
57
|
+
|
58
|
+
def initialize(parent, line_number, name)
|
59
|
+
super(parent, line_number, [])
|
60
|
+
@name = name
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_s
|
64
|
+
"Local(name = #{name}, scope = #{scope})"
|
65
|
+
end
|
66
|
+
|
67
|
+
def infer(typer)
|
68
|
+
unless @inferred_type
|
69
|
+
@inferred_type = typer.local_type(scope, name)
|
70
|
+
|
71
|
+
@inferred_type ? resolved! : typer.defer(self)
|
72
|
+
end
|
73
|
+
|
74
|
+
@inferred_type
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
module Duby::AST
|
2
|
+
class Arguments < Node
|
3
|
+
attr_accessor :args, :opt_args, :rest_arg, :block_arg
|
4
|
+
|
5
|
+
def initialize(parent, line_number, &block)
|
6
|
+
super(parent, line_number, &block)
|
7
|
+
@args, @opt_args, @rest_arg, @block_arg = children
|
8
|
+
end
|
9
|
+
|
10
|
+
def infer(typer)
|
11
|
+
unless @inferred_type
|
12
|
+
@inferred_type = args ? args.map {|arg| typer.infer(arg)} : []
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Argument < Node
|
18
|
+
include Typed
|
19
|
+
end
|
20
|
+
|
21
|
+
class RequiredArgument < Argument
|
22
|
+
include Named
|
23
|
+
include Scoped
|
24
|
+
|
25
|
+
def initialize(parent, line_number, name)
|
26
|
+
super(parent, line_number)
|
27
|
+
|
28
|
+
@name = name
|
29
|
+
end
|
30
|
+
|
31
|
+
def infer(typer)
|
32
|
+
unless @inferred_type
|
33
|
+
# if not already typed, check parent of parent (MethodDefinition) for signature info
|
34
|
+
method_def = parent.parent
|
35
|
+
signature = method_def.signature
|
36
|
+
|
37
|
+
# if signature, search for this argument
|
38
|
+
if signature[name.intern]
|
39
|
+
@inferred_type = typer.learn_local_type(scope, name, signature[name.intern])
|
40
|
+
else
|
41
|
+
@inferred_type = typer.local_type(scope, name)
|
42
|
+
end
|
43
|
+
|
44
|
+
unless @inferred_type
|
45
|
+
typer.defer(self)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
@inferred_type
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class OptionalArgument < Argument
|
54
|
+
include Named
|
55
|
+
include Scoped
|
56
|
+
attr_accessor :child
|
57
|
+
|
58
|
+
def initialize(parent, line_number, name, &block)
|
59
|
+
super(parent, line_number, &block)
|
60
|
+
@child = children[0]
|
61
|
+
@name = name
|
62
|
+
end
|
63
|
+
|
64
|
+
def infer(typer)
|
65
|
+
unless @inferred_type
|
66
|
+
# if not already typed, check parent of parent (MethodDefinition) for signature info
|
67
|
+
method_def = parent.parent
|
68
|
+
signature = method_def.signature
|
69
|
+
|
70
|
+
# if signature, search for this argument
|
71
|
+
@inferred_type = child.infer(typer)
|
72
|
+
if @inferred_type
|
73
|
+
typer.learn_local_type(scope, name, @inferred_type)
|
74
|
+
signature[name.intern] = @inferred_type
|
75
|
+
else
|
76
|
+
typer.defer(self)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
@inferred_type
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class RestArgument < Argument
|
85
|
+
include Named
|
86
|
+
include Scoped
|
87
|
+
|
88
|
+
def initialize(parent, line_number, name)
|
89
|
+
super(parent, line_number)
|
90
|
+
|
91
|
+
@name = name
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class BlockArgument < Argument
|
96
|
+
include Named
|
97
|
+
|
98
|
+
def initialize(parent, line_number, name)
|
99
|
+
super(parent, line_number)
|
100
|
+
|
101
|
+
@name = name
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
class MethodDefinition < Node
|
106
|
+
include Named
|
107
|
+
include Scope
|
108
|
+
attr_accessor :signature, :arguments, :body, :defining_class
|
109
|
+
|
110
|
+
def initialize(parent, line_number, name, &block)
|
111
|
+
super(parent, line_number, &block)
|
112
|
+
@signature, @arguments, @body = children
|
113
|
+
@name = name
|
114
|
+
end
|
115
|
+
|
116
|
+
def infer(typer)
|
117
|
+
@defining_class ||= typer.self_type
|
118
|
+
typer.infer(arguments)
|
119
|
+
typer.infer_signature(self)
|
120
|
+
forced_type = signature[:return]
|
121
|
+
inferred_type = body ? typer.infer(body) : typer.no_type
|
122
|
+
|
123
|
+
if !inferred_type
|
124
|
+
typer.defer(self)
|
125
|
+
else
|
126
|
+
actual_type = if forced_type.nil?
|
127
|
+
inferred_type
|
128
|
+
else
|
129
|
+
forced_type
|
130
|
+
end
|
131
|
+
if actual_type.unreachable?
|
132
|
+
actual_type = typer.no_type
|
133
|
+
end
|
134
|
+
|
135
|
+
if !abstract? &&
|
136
|
+
forced_type != typer.no_type &&
|
137
|
+
!actual_type.is_parent(inferred_type)
|
138
|
+
raise Duby::Typer::InferenceError.new(
|
139
|
+
"Inferred return type %s is incompatible with declared %s" %
|
140
|
+
[inferred_type, actual_type], self)
|
141
|
+
end
|
142
|
+
|
143
|
+
@inferred_type = typer.learn_method_type(defining_class, name, arguments.inferred_type, actual_type, signature[:throws])
|
144
|
+
|
145
|
+
# learn the other overloads as well
|
146
|
+
args_for_opt = []
|
147
|
+
if arguments.args
|
148
|
+
arguments.args.each do |arg|
|
149
|
+
if OptionalArgument === arg
|
150
|
+
arg_types_for_opt = args_for_opt.map do |arg_for_opt|
|
151
|
+
arg_for_opt.infer(typer)
|
152
|
+
end
|
153
|
+
typer.learn_method_type(defining_class, name, arg_types_for_opt, actual_type, signature[:throws])
|
154
|
+
end
|
155
|
+
args_for_opt << arg
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
signature[:return] = @inferred_type
|
160
|
+
end
|
161
|
+
|
162
|
+
@inferred_type
|
163
|
+
end
|
164
|
+
|
165
|
+
def abstract?
|
166
|
+
node = parent
|
167
|
+
while node && !node.kind_of?(Scope)
|
168
|
+
node = node.parent
|
169
|
+
end
|
170
|
+
InterfaceDeclaration === node
|
171
|
+
end
|
172
|
+
|
173
|
+
def static?
|
174
|
+
false
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
class StaticMethodDefinition < MethodDefinition
|
179
|
+
def defining_class
|
180
|
+
@defining_class.meta
|
181
|
+
end
|
182
|
+
|
183
|
+
def static?
|
184
|
+
true
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Duby::AST
|
2
|
+
class Body < Node
|
3
|
+
def initialize(parent, line_number, &block)
|
4
|
+
super(parent, line_number, &block)
|
5
|
+
end
|
6
|
+
|
7
|
+
# Type of a block is the type of its final element
|
8
|
+
def infer(typer)
|
9
|
+
unless @inferred_type
|
10
|
+
if children.size == 0
|
11
|
+
@inferred_type = typer.default_type
|
12
|
+
else
|
13
|
+
children.each {|child| @inferred_type = typer.infer(child)}
|
14
|
+
end
|
15
|
+
|
16
|
+
unless @inferred_type
|
17
|
+
typer.defer(self)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
@inferred_type
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Noop < Node
|
26
|
+
def infer(typer)
|
27
|
+
@inferred_type ||= typer.no_type
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Script < Node
|
32
|
+
include Scope
|
33
|
+
attr_accessor :body
|
34
|
+
|
35
|
+
def initialize(parent, line_number, &block)
|
36
|
+
super(parent, line_number, children, &block)
|
37
|
+
@body = children[0]
|
38
|
+
end
|
39
|
+
|
40
|
+
def infer(typer)
|
41
|
+
@inferred_type ||= typer.infer(body) || (typer.defer(self); nil)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|