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.
Files changed (69) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +68 -0
  3. data/README.txt +31 -0
  4. data/Rakefile +37 -0
  5. data/bin/duby +9 -0
  6. data/bin/dubyc +9 -0
  7. data/bin/dubyp +9 -0
  8. data/examples/appengine/src/com/google/appengine/ext/duby/db/Model.duby +132 -0
  9. data/examples/appengine/src/com/ribrdb/DubyApp.duby +28 -0
  10. data/examples/bench_fractal.duby +57 -0
  11. data/examples/construction.duby +8 -0
  12. data/examples/edb.duby +3 -0
  13. data/examples/fib.duby +24 -0
  14. data/examples/fields.duby +22 -0
  15. data/examples/java_thing.duby +13 -0
  16. data/examples/simple_class.duby +12 -0
  17. data/examples/swing.duby +20 -0
  18. data/examples/tak.duby +15 -0
  19. data/javalib/JRubyParser.jar +0 -0
  20. data/lib/duby.rb +170 -0
  21. data/lib/duby/ast.rb +340 -0
  22. data/lib/duby/ast/call.rb +73 -0
  23. data/lib/duby/ast/class.rb +145 -0
  24. data/lib/duby/ast/flow.rb +328 -0
  25. data/lib/duby/ast/intrinsics.rb +46 -0
  26. data/lib/duby/ast/literal.rb +93 -0
  27. data/lib/duby/ast/local.rb +77 -0
  28. data/lib/duby/ast/method.rb +187 -0
  29. data/lib/duby/ast/structure.rb +44 -0
  30. data/lib/duby/ast/type.rb +93 -0
  31. data/lib/duby/c/compiler.rb +134 -0
  32. data/lib/duby/compiler.rb +261 -0
  33. data/lib/duby/jvm/compiler.rb +684 -0
  34. data/lib/duby/jvm/method_lookup.rb +185 -0
  35. data/lib/duby/jvm/source_compiler.rb +516 -0
  36. data/lib/duby/jvm/source_generator/builder.rb +368 -0
  37. data/lib/duby/jvm/source_generator/loops.rb +132 -0
  38. data/lib/duby/jvm/source_generator/precompile.rb +154 -0
  39. data/lib/duby/jvm/source_generator/typer.rb +11 -0
  40. data/lib/duby/jvm/typer.rb +118 -0
  41. data/lib/duby/jvm/types.rb +326 -0
  42. data/lib/duby/jvm/types/basic_types.rb +18 -0
  43. data/lib/duby/jvm/types/boolean.rb +11 -0
  44. data/lib/duby/jvm/types/factory.rb +151 -0
  45. data/lib/duby/jvm/types/floats.rb +70 -0
  46. data/lib/duby/jvm/types/integers.rb +110 -0
  47. data/lib/duby/jvm/types/intrinsics.rb +157 -0
  48. data/lib/duby/jvm/types/literals.rb +82 -0
  49. data/lib/duby/jvm/types/methods.rb +344 -0
  50. data/lib/duby/jvm/types/number.rb +92 -0
  51. data/lib/duby/nbcompiler.rb +29 -0
  52. data/lib/duby/old/compiler_old.rb +845 -0
  53. data/lib/duby/old/declaration.rb +72 -0
  54. data/lib/duby/old/mapper.rb +72 -0
  55. data/lib/duby/old/signature.rb +52 -0
  56. data/lib/duby/old/typer_old.rb +163 -0
  57. data/lib/duby/plugin/edb.rb +25 -0
  58. data/lib/duby/plugin/java.rb +42 -0
  59. data/lib/duby/plugin/math.rb +84 -0
  60. data/lib/duby/transform.rb +908 -0
  61. data/lib/duby/typer.rb +359 -0
  62. data/test/test_ast.rb +391 -0
  63. data/test/test_compilation.rb +98 -0
  64. data/test/test_java_typer.rb +199 -0
  65. data/test/test_javac_compiler.rb +57 -0
  66. data/test/test_jvm_compiler.rb +1459 -0
  67. data/test/test_math_plugin.rb +87 -0
  68. data/test/test_typer.rb +246 -0
  69. metadata +155 -0
@@ -0,0 +1,93 @@
1
+ module Duby::AST
2
+ class Import < Node
3
+ attr_accessor :short
4
+ attr_accessor :long
5
+ def initialize(parent, line_number, short, long)
6
+ @short = short
7
+ @long = long
8
+ super(parent, line_number, [])
9
+ Duby::AST.type_factory.alias(short, long) if Duby::AST.type_factory
10
+ end
11
+
12
+ def to_s
13
+ "Import(#{short} = #{long})"
14
+ end
15
+
16
+ def infer(typer)
17
+ # add both the meta and non-meta imports
18
+ typer.alias_types(short, long)
19
+ typer.no_type
20
+ end
21
+ end
22
+
23
+ defmacro('import') do |transformer, fcall, parent|
24
+ args_node = fcall.args_node
25
+ case args_node
26
+ when JRubyAst::ArrayNode
27
+ case args_node.size
28
+ when 1
29
+ node = args_node.get(0)
30
+ case node
31
+ when JRubyAst::StrNode
32
+ long = node.value
33
+ short = long[(long.rindex('.') + 1)..-1]
34
+ when JRubyAst::CallNode
35
+ case node.args_node.size
36
+ when 0
37
+ pieces = [node.name]
38
+ while node.kind_of? JRubyAst::CallNode
39
+ node = node.receiver_node
40
+ pieces << node.name
41
+ end
42
+ long = pieces.reverse.join '.'
43
+ short = pieces[0]
44
+ when 1
45
+ arg = node.args_node.get(0)
46
+ unless (JRubyAst::FCallNode === arg &&
47
+ arg.name == 'as' && arg.args_node.size == 1)
48
+ raise Duby::TransformError.new("unknown import syntax", args_node)
49
+ end
50
+ short = arg.args_node.get(0).name
51
+ pieces = [node.name]
52
+ while node.kind_of? JRubyAst::CallNode
53
+ node = node.receiver_node
54
+ pieces << node.name
55
+ end
56
+ long = pieces.reverse.join '.'
57
+ else
58
+ raise Duby::TransformError.new("unknown import syntax", args_node)
59
+ end
60
+ else
61
+ raise Duby::TransformError.new("unknown import syntax", args_node)
62
+ end
63
+ when 2
64
+ short = args_node.child_nodes[0].value
65
+ long = args_node.child_nodes[1].value
66
+ else
67
+ raise Duby::TransformError.new("unknown import syntax", args_node)
68
+ end
69
+ else
70
+ raise Duby::TransformError.new("unknown import syntax", args_node)
71
+ end
72
+ Import.new(parent, fcall.position, short, long)
73
+ end
74
+
75
+ class EmptyArray < Node
76
+ attr_accessor :size
77
+ attr_accessor :component_type
78
+ def initialize(parent, line_number, type, &block)
79
+ super(parent, line_number, [])
80
+ @component_type = type
81
+ @size = size
82
+ @inferred_type = Duby::AST::type(type.name, true)
83
+
84
+ @size = yield(self)
85
+ end
86
+
87
+ def infer(typer)
88
+ typer.infer(size)
89
+ resolved!
90
+ return @inferred_type
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,134 @@
1
+ require 'duby'
2
+ require 'duby/compiler'
3
+
4
+ module Duby
5
+ module Compiler
6
+ class C
7
+ class MathCompiler
8
+ def call(compiler, call)
9
+ call.target.compile(compiler)
10
+
11
+ compiler.src << " #{call.name} "
12
+
13
+ call.parameters.each {|param| param.compile(compiler)}
14
+ end
15
+ end
16
+
17
+ attr_accessor :filename, :src
18
+
19
+ def initialize(filename)
20
+ @filename = filename
21
+ @src = ""
22
+
23
+ self.type_mapper[AST::TypeReference.new(:fixnum)] = "int"
24
+
25
+ self.call_compilers[AST::TypeReference.new(:fixnum)] = MathCompiler.new
26
+ end
27
+
28
+ def compile(ast)
29
+ ast.compile(self)
30
+ end
31
+
32
+ def define_main(body)
33
+ old_src, @src = @src, "int main(int argc, char **argv)\n{\n"
34
+
35
+ body.compile(self)
36
+
37
+ @src << "}\n\n"
38
+
39
+ @src = old_src + @src
40
+ end
41
+
42
+ def define_method(name, signature, args, body)
43
+ old_src, @src = @src, "#{type_mapper[signature[:return]]} #{name}("
44
+
45
+ args.compile(self)
46
+
47
+ @src << ")\n{\n"
48
+
49
+ body.compile(self)
50
+
51
+ @src << "\n}\n\n"
52
+
53
+ @src = old_src + @src
54
+ end
55
+
56
+ def declare_argument(name, type)
57
+ @src << "#{type_mapper[type]} #{name}"
58
+ end
59
+
60
+ def branch(iff)
61
+ @src << "if ("
62
+
63
+ iff.condition.compile(self)
64
+
65
+ @src << ") {"
66
+
67
+ iff.body.compile(self)
68
+
69
+ if iff.else
70
+ @src << "} else {"
71
+
72
+ iff.else.compile(self)
73
+ end
74
+
75
+ @src << "}"
76
+ end
77
+
78
+ def call(call)
79
+ call_compilers[call.target.inferred_type].call(self, call)
80
+ end
81
+
82
+ def call_compilers
83
+ @call_compilers ||= {}
84
+ end
85
+
86
+ def self_call(fcall)
87
+ @src << "#{fcall.name}("
88
+
89
+ fcall.parameters.each {|param| param.compile(self)}
90
+
91
+ @src << ")"
92
+ end
93
+
94
+ def local(name, type)
95
+ @src << name
96
+ end
97
+
98
+ def fixnum(value)
99
+ @src << value.to_s
100
+ end
101
+
102
+ def newline
103
+ @src << ";\n"
104
+ end
105
+
106
+ def ret
107
+ @src << "return "
108
+
109
+ yield
110
+ end
111
+
112
+ def generate
113
+ @src
114
+ end
115
+
116
+ def type_mapper
117
+ @type_mapper ||= {}
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ if __FILE__ == $0
124
+ ast = Duby::AST.parse(File.read(ARGV[0]))
125
+
126
+ typer = Duby::Typer::Simple.new(:script)
127
+ ast.infer(typer)
128
+ typer.resolve(true)
129
+
130
+ compiler = Duby::Compiler::C.new("#{ARGV[0]}.c")
131
+ ast.compile(compiler)
132
+
133
+ File.open(compiler.filename, "w") {|file| file.write(compiler.generate)}
134
+ end
@@ -0,0 +1,261 @@
1
+ require 'duby'
2
+
3
+ module Duby
4
+ module AST
5
+ class Fixnum
6
+ def compile(compiler, expression)
7
+ if expression
8
+ compiler.line(line_number)
9
+ compiler.fixnum(literal)
10
+ end
11
+ end
12
+ end
13
+
14
+ class String
15
+ def compile(compiler, expression)
16
+ if expression
17
+ compiler.line(line_number)
18
+ compiler.string(literal)
19
+ end
20
+ end
21
+ end
22
+
23
+ class Float
24
+ def compile(compiler, expression)
25
+ if expression
26
+ compiler.line(line_number)
27
+ compiler.float(literal)
28
+ end
29
+ end
30
+ end
31
+
32
+ class Boolean
33
+ def compile(compiler, expression)
34
+ if expression
35
+ compiler.line(line_number)
36
+ compiler.boolean(literal)
37
+ end
38
+ end
39
+ end
40
+
41
+ class Body
42
+ def compile(compiler, expression)
43
+ compiler.line(line_number)
44
+ compiler.body(self, expression)
45
+ end
46
+ end
47
+
48
+ class Import
49
+ def compile(compiler, expression)
50
+ # TODO: what does it mean for import to be an expression?
51
+ compiler.import(short, long)
52
+ end
53
+ end
54
+
55
+ class Constant
56
+ def compile(compiler, expression)
57
+ if expression
58
+ compiler.line(line_number)
59
+ compiler.constant(self)
60
+ end
61
+ end
62
+ end
63
+
64
+ class Print
65
+ def compile(compiler, expression)
66
+ # TODO: what does it mean for printline to be an expression?
67
+ compiler.line(line_number)
68
+ compiler.print(self)
69
+ end
70
+ end
71
+
72
+ class Local
73
+ def compile(compiler, expression)
74
+ if expression
75
+ compiler.line(line_number)
76
+ compiler.local(name, inferred_type)
77
+ end
78
+ end
79
+ end
80
+
81
+ class LocalDeclaration
82
+ def compile(compiler, expression)
83
+ compiler.line(line_number)
84
+ compiler.local_declare(name, type)
85
+ end
86
+ end
87
+
88
+ class LocalAssignment
89
+ def compile(compiler, expression)
90
+ compiler.line(line_number)
91
+ compiler.local_assign(name, inferred_type, expression, value)
92
+ end
93
+ end
94
+
95
+ class Script
96
+ def compile(compiler, expression)
97
+ # TODO: what does it mean for a script to be an expression? possible?
98
+ compiler.define_main(body)
99
+ end
100
+ end
101
+
102
+ class MethodDefinition
103
+ def compile(compiler, expression)
104
+ # TODO: what does it mean for a method to be an expression?
105
+ compiler.define_method(name, signature, arguments, body, static?)
106
+ end
107
+ end
108
+
109
+ class Arguments
110
+ def compile(compiler, expression)
111
+ # TODO: what does it mean for a method to be an expression?
112
+ args.each {|arg| compiler.declare_argument(arg.name, arg.inferred_type)} if args
113
+ end
114
+ end
115
+
116
+ class Noop
117
+ def compile(compiler, expression)
118
+ # TODO: what does it mean for a noop to be an expression
119
+ # nothing
120
+ end
121
+ end
122
+
123
+ class If
124
+ def compile(compiler, expression)
125
+ compiler.line(line_number)
126
+ compiler.branch(self, expression)
127
+ end
128
+ end
129
+
130
+ class Condition
131
+ def compile(compiler, expression)
132
+ # TODO: can a condition ever be an expression? I don't think it can...
133
+ compiler.line(line_number)
134
+ predicate.compile(compiler, expression)
135
+ end
136
+ end
137
+
138
+ class FunctionalCall
139
+ def compile(compiler, expression)
140
+ compiler.line(line_number)
141
+ compiler.self_call(self, expression)
142
+ end
143
+ end
144
+
145
+ class Call
146
+ def compile(compiler, expression)
147
+ compiler.line(line_number)
148
+ compiler.call(self, expression)
149
+ end
150
+ end
151
+
152
+ class WhileLoop
153
+ def compile(compiler, expression)
154
+ compiler.line(line_number)
155
+ compiler.while_loop(self, expression)
156
+ end
157
+ end
158
+
159
+ class ForLoop
160
+ def compile(compiler, expression)
161
+ compiler.line(line_number)
162
+ compiler.for_loop(self, expression)
163
+ end
164
+ end
165
+
166
+ class ClassDefinition
167
+ def compile(compiler, expression)
168
+ compiler.define_class(self, expression)
169
+ end
170
+ end
171
+
172
+ class FieldDeclaration
173
+ def compile(compiler, expression)
174
+ compiler.field_declare(name, inferred_type)
175
+ end
176
+ end
177
+
178
+ class FieldAssignment
179
+ def compile(compiler, expression)
180
+ compiler.line(line_number)
181
+ compiler.field_assign(name, inferred_type, expression, value)
182
+ end
183
+ end
184
+
185
+ class Field
186
+ def compile(compiler, expression)
187
+ compiler.line(line_number)
188
+ if expression
189
+ compiler.field(name, inferred_type)
190
+ end
191
+ end
192
+ end
193
+
194
+ class Return
195
+ def compile(compiler, expression)
196
+ compiler.line(line_number)
197
+ compiler.return(self)
198
+ end
199
+ end
200
+
201
+ class EmptyArray
202
+ def compile(compiler, expression)
203
+ if expression
204
+ compiler.line(line_number)
205
+ compiler.empty_array(component_type, size)
206
+ end
207
+ end
208
+ end
209
+
210
+ class Null
211
+ def compile(compiler, expression)
212
+ if expression
213
+ compiler.line(line_number)
214
+ compiler.null
215
+ end
216
+ end
217
+ end
218
+
219
+ class Break
220
+ def compile(compiler, expression)
221
+ compiler.line(line_number)
222
+ compiler.break(self)
223
+ end
224
+ end
225
+
226
+ class Next
227
+ def compile(compiler, expression)
228
+ compiler.line(line_number)
229
+ compiler.next(self)
230
+ end
231
+ end
232
+
233
+ class Redo
234
+ def compile(compiler, expression)
235
+ compiler.line(line_number)
236
+ compiler.redo(self)
237
+ end
238
+ end
239
+
240
+ class Raise
241
+ def compile(compiler, expression)
242
+ compiler.line(line_number)
243
+ compiler._raise(@exception)
244
+ end
245
+ end
246
+
247
+ class Rescue
248
+ def compile(compiler, expression)
249
+ compiler.line(line_number)
250
+ compiler.rescue(self, expression)
251
+ end
252
+ end
253
+
254
+ class Ensure
255
+ def compile(compiler, expression)
256
+ compiler.line(line_number)
257
+ compiler.ensure(self, expression)
258
+ end
259
+ end
260
+ end
261
+ end