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
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'duby'
|
2
|
+
module Duby
|
3
|
+
def self.source_path
|
4
|
+
@source_path ||= File.expand_path('.')
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.source_path=(path)
|
8
|
+
@source_path = File.expand_path(path)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.dest_path
|
12
|
+
@dest_path ||= File.expand_path('.')
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.dest_path=(path)
|
16
|
+
@dest_path = File.expand_path(path)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.dest_to_source_path(path)
|
20
|
+
source = File.expand_path(path).sub(/\.(?:java|class)/, '.duby')
|
21
|
+
source = source.sub(/^#{dest_path}\//, "#{source_path}/")
|
22
|
+
down = source[0,1].downcase + source[1,source.size]
|
23
|
+
return down if File.exist?(down)
|
24
|
+
source
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.compiler_options
|
28
|
+
@compiler_options ||= []
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.compiler_options=(args)
|
32
|
+
@compiler_options = args
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def dubyc(*files)
|
37
|
+
if files[-1].kind_of?(Hash)
|
38
|
+
options = files.pop
|
39
|
+
else
|
40
|
+
options = {}
|
41
|
+
end
|
42
|
+
source_dir = options.fetch(:dir, Duby.source_path)
|
43
|
+
dest = options.fetch(:dest, Duby.dest_path)
|
44
|
+
files = files.map {|f| f.sub(/^#{source_dir}\//, '')}
|
45
|
+
flags = options.fetch(:options, Duby.compiler_options)
|
46
|
+
args = ['-d', dest, *flags] + files
|
47
|
+
chdir(source_dir) do
|
48
|
+
puts $CLASSPATH.inspect
|
49
|
+
puts "dubyc #{args.join ' '}"
|
50
|
+
Duby.compile(*args)
|
51
|
+
Duby.reset
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
rule '.java' => [proc {|n| Duby.dest_to_source_path(n)}] do |t|
|
56
|
+
dubyc(t.source, :options=>['-java'])
|
57
|
+
end
|
58
|
+
|
59
|
+
rule '.class' => [proc {|n| Duby.dest_to_source_path(n)}] do |t|
|
60
|
+
dubyc(t.source)
|
61
|
+
end
|
@@ -1,28 +1,54 @@
|
|
1
1
|
import javax.servlet.http.HttpServlet
|
2
2
|
import com.google.appengine.ext.duby.db.Model
|
3
|
+
import java.util.HashMap
|
4
|
+
import java.util.regex.Pattern
|
3
5
|
|
4
6
|
class Post < Model
|
5
|
-
def initialize; end
|
6
|
-
|
7
7
|
property title, String
|
8
8
|
property body, Text
|
9
9
|
end
|
10
10
|
|
11
11
|
class DubyApp < HttpServlet
|
12
12
|
def_edb(list, 'com/ribrdb/list.dhtml')
|
13
|
-
|
13
|
+
|
14
14
|
def doGet(request, response)
|
15
|
-
returns :void
|
16
15
|
@posts = Post.all.run
|
17
16
|
response.getWriter.write(list)
|
18
17
|
end
|
19
|
-
|
18
|
+
|
20
19
|
def doPost(request, response)
|
21
20
|
post = Post.new
|
22
21
|
post.title = request.getParameter('title')
|
23
|
-
post.body =
|
22
|
+
post.body = request.getParameter('body')
|
24
23
|
post.save
|
25
24
|
doGet(request, response)
|
26
25
|
end
|
27
26
|
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
@escape_pattern = Pattern.compile("[<>&'\"]")
|
30
|
+
@escaped = HashMap.new
|
31
|
+
@escaped.put("<", "<")
|
32
|
+
@escaped.put(">", ">")
|
33
|
+
@escaped.put("&", "&")
|
34
|
+
@escaped.put("\"", """)
|
35
|
+
@escaped.put("'", "'")
|
36
|
+
end
|
37
|
+
|
38
|
+
def h(text:String)
|
39
|
+
return "" unless text
|
40
|
+
matcher = @escape_pattern.matcher(text)
|
41
|
+
buffer = StringBuffer.new
|
42
|
+
while matcher.find
|
43
|
+
replacement = String(@escaped.get(matcher.group))
|
44
|
+
matcher.appendReplacement(buffer, replacement)
|
45
|
+
end
|
46
|
+
matcher.appendTail(buffer)
|
47
|
+
return buffer.toString
|
48
|
+
end
|
49
|
+
|
50
|
+
def h(o:Object)
|
51
|
+
return "" unless o
|
52
|
+
h(o.toString)
|
53
|
+
end
|
28
54
|
end
|
File without changes
|
@@ -0,0 +1,66 @@
|
|
1
|
+
class BinaryTrees
|
2
|
+
def self.main(args:String[])
|
3
|
+
n = 0
|
4
|
+
n = Integer.parseInt(args[0]) if args.length > 0
|
5
|
+
|
6
|
+
maxDepth = (6 > n) ? 6 : n
|
7
|
+
stretchDepth = maxDepth + 1
|
8
|
+
|
9
|
+
check = TreeNode.bottomUpTree(0, stretchDepth).itemCheck
|
10
|
+
puts "stretch tree of depth #{stretchDepth}\t check: #{check}"
|
11
|
+
|
12
|
+
longLivedTree = TreeNode.bottomUpTree 0, maxDepth
|
13
|
+
|
14
|
+
depth = 4
|
15
|
+
while depth <= maxDepth
|
16
|
+
iterations = 1 << (maxDepth - depth + 4)
|
17
|
+
check = 0
|
18
|
+
|
19
|
+
i = 1
|
20
|
+
while i <= iterations
|
21
|
+
check += TreeNode.bottomUpTree(i, depth).itemCheck
|
22
|
+
check += TreeNode.bottomUpTree(-i,depth).itemCheck
|
23
|
+
i += 1
|
24
|
+
end
|
25
|
+
|
26
|
+
puts "#{iterations * 2}\t trees of depth #{depth}\t check: #{check}"
|
27
|
+
depth += 2
|
28
|
+
end
|
29
|
+
|
30
|
+
puts "long lived tree of depth #{maxDepth}\t check: #{longLivedTree.itemCheck}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class TreeNode
|
35
|
+
def initialize(left:TreeNode, right:TreeNode, item:int)
|
36
|
+
@item = item
|
37
|
+
@left = left
|
38
|
+
@right = right
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize(item:int)
|
42
|
+
@left = TreeNode(nil)
|
43
|
+
@right = TreeNode(nil)
|
44
|
+
@item = item
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.bottomUpTree(item:int, depth:int)
|
48
|
+
if depth > 0
|
49
|
+
TreeNode.new(
|
50
|
+
TreeNode.bottomUpTree(2*item-1, depth-1),
|
51
|
+
TreeNode.bottomUpTree(2*item, depth-1),
|
52
|
+
item)
|
53
|
+
else
|
54
|
+
TreeNode.new(item)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def itemCheck
|
59
|
+
# if necessary deallocate here
|
60
|
+
if @left == nil
|
61
|
+
@item
|
62
|
+
else
|
63
|
+
@item + @left.itemCheck - @right.itemCheck
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Example of using a dynamic type in a method definition
|
2
|
+
def foo(a:dynamic)
|
3
|
+
puts "I got a #{a.getClass.getName} of size #{a.size}"
|
4
|
+
end
|
5
|
+
|
6
|
+
class SizeThing
|
7
|
+
def initialize(size:int)
|
8
|
+
@size = size
|
9
|
+
end
|
10
|
+
|
11
|
+
def size
|
12
|
+
@size
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
foo([1,2,3])
|
17
|
+
foo(SizeThing.new(12))
|
data/examples/fib.duby
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
import "java.lang.System"
|
2
|
-
|
3
1
|
def fib(a:int)
|
4
2
|
if a < 2
|
5
3
|
a
|
@@ -8,17 +6,11 @@ def fib(a:int)
|
|
8
6
|
end
|
9
7
|
end
|
10
8
|
|
11
|
-
def bench(
|
12
|
-
|
9
|
+
def bench(n:int)
|
10
|
+
n.times do
|
13
11
|
time_start = System.currentTimeMillis
|
14
|
-
puts "fib(45):"
|
15
|
-
puts fib(45)
|
16
|
-
time_total = System.currentTimeMillis - time_start
|
17
|
-
puts "Total time:"
|
18
|
-
puts time_total
|
19
|
-
times -= 1
|
12
|
+
puts "fib(45): #{fib(45)}\nTotal time: #{System.currentTimeMillis - time_start}"
|
20
13
|
end
|
21
|
-
nil
|
22
14
|
end
|
23
15
|
|
24
16
|
bench 10
|
data/examples/fields.duby
CHANGED
@@ -2,10 +2,10 @@ import 'java.util.ArrayList'
|
|
2
2
|
|
3
3
|
class Bar
|
4
4
|
def initialize
|
5
|
-
@a = ArrayList
|
5
|
+
@a = ArrayList(nil)
|
6
6
|
end
|
7
7
|
|
8
|
-
def list
|
8
|
+
def list(a:ArrayList)
|
9
9
|
@a = a
|
10
10
|
end
|
11
11
|
|
@@ -18,5 +18,5 @@ b = Bar.new
|
|
18
18
|
list = ArrayList.new
|
19
19
|
list.add('hello')
|
20
20
|
list.add('world')
|
21
|
-
b.list
|
21
|
+
b.list(list)
|
22
22
|
b.foo
|
data/examples/fractal.duby
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
import java.lang.System
|
2
|
-
|
3
1
|
def run
|
4
2
|
puts "Rendering"
|
5
3
|
y = -39.0
|
@@ -52,6 +50,6 @@ i = 0
|
|
52
50
|
while i < 10
|
53
51
|
start = System.currentTimeMillis
|
54
52
|
run
|
55
|
-
puts "Time:
|
53
|
+
puts "Time: #{(System.currentTimeMillis - start) / 1000.0}"
|
56
54
|
i += 1
|
57
55
|
end
|
data/examples/swing.duby
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
import javax.swing.JFrame
|
2
2
|
import javax.swing.JButton
|
3
|
-
import java.awt.event.ActionListener
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
# FIXME blocks need to be inside a MethodDefinition, but main doesn't
|
5
|
+
# have one.
|
6
|
+
def self.run
|
7
|
+
frame = JFrame.new "Welcome to Duby"
|
8
|
+
frame.setSize 300, 300
|
9
|
+
frame.setVisible true
|
8
10
|
|
9
|
-
button = JButton.new "Press me"
|
10
|
-
frame.add button
|
11
|
-
frame.show
|
11
|
+
button = JButton.new "Press me"
|
12
|
+
frame.add button
|
13
|
+
frame.show
|
12
14
|
|
13
|
-
|
14
|
-
def initialize; end
|
15
|
-
def actionPerformed(event)
|
15
|
+
button.addActionListener do |event|
|
16
16
|
JButton(event.getSource).setText "Duby Rocks!"
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
run
|
Binary file
|
Binary file
|
data/lib/duby.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'fileutils'
|
2
|
+
require 'rbconfig'
|
2
3
|
require 'duby/transform'
|
3
4
|
require 'duby/ast'
|
4
5
|
require 'duby/typer'
|
5
6
|
require 'duby/compiler'
|
7
|
+
require 'duby/env'
|
6
8
|
begin
|
7
9
|
require 'bitescript'
|
8
10
|
rescue LoadError
|
@@ -18,42 +20,130 @@ module Duby
|
|
18
20
|
def self.run(*args)
|
19
21
|
DubyImpl.new.run(*args)
|
20
22
|
end
|
21
|
-
|
23
|
+
|
22
24
|
def self.compile(*args)
|
23
25
|
DubyImpl.new.compile(*args)
|
24
26
|
end
|
25
|
-
|
27
|
+
|
26
28
|
def self.parse(*args)
|
27
29
|
DubyImpl.new.parse(*args)
|
28
30
|
end
|
31
|
+
|
32
|
+
def self.plugins
|
33
|
+
@plugins ||= []
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.reset
|
37
|
+
@plugins.each {|x| x.reset if x.respond_to?(:reset)}
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.print_error(message, position)
|
41
|
+
puts "#{position.file}:#{position.start_line + 1}: #{message}"
|
42
|
+
file_offset = 0
|
43
|
+
startline = position.start_line
|
44
|
+
endline = position.end_line
|
45
|
+
start_offset = position.start_offset
|
46
|
+
end_offset = position.end_offset
|
47
|
+
# don't try to search dash_e
|
48
|
+
# TODO: show dash_e source the same way
|
49
|
+
if File.exist? position.file
|
50
|
+
File.open(position.file).each_with_index do |line, lineno|
|
51
|
+
line_end = file_offset + line.size
|
52
|
+
skip = [start_offset - file_offset, line.size].min
|
53
|
+
if lineno >= startline && lineno <= endline
|
54
|
+
puts line.chomp
|
55
|
+
if skip > 0
|
56
|
+
print ' ' * (skip)
|
57
|
+
else
|
58
|
+
skip = 0
|
59
|
+
end
|
60
|
+
if line_end <= end_offset
|
61
|
+
puts '^' * (line.size - skip)
|
62
|
+
else
|
63
|
+
puts '^' * [end_offset - skip - file_offset, 1].max
|
64
|
+
end
|
65
|
+
end
|
66
|
+
file_offset = line_end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class CompilationState
|
72
|
+
attr_accessor :verbose, :destination
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# This is a custom classloader impl to allow loading classes with
|
77
|
+
# interdependencies by having findClass retrieve classes as needed from the
|
78
|
+
# collection of all classes generated by the target script.
|
79
|
+
class DubyClassLoader < java::security::SecureClassLoader
|
80
|
+
def initialize(parent, class_map)
|
81
|
+
super(parent)
|
82
|
+
@class_map = class_map
|
83
|
+
end
|
84
|
+
|
85
|
+
def findClass(name)
|
86
|
+
if @class_map[name]
|
87
|
+
bytes = @class_map[name].to_java_bytes
|
88
|
+
defineClass(name, bytes, 0, bytes.length)
|
89
|
+
else
|
90
|
+
raise java.lang.ClassNotFoundException.new(name)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def loadClass(name, resolve)
|
95
|
+
cls = findLoadedClass(name)
|
96
|
+
if cls == nil
|
97
|
+
if @class_map[name]
|
98
|
+
cls = findClass(name)
|
99
|
+
else
|
100
|
+
cls = super(name, false)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
resolveClass(cls) if resolve
|
105
|
+
|
106
|
+
cls
|
107
|
+
end
|
29
108
|
end
|
30
109
|
|
31
110
|
class DubyImpl
|
32
111
|
def run(*args)
|
33
112
|
ast = parse(*args)
|
113
|
+
main = nil
|
114
|
+
class_map = {}
|
34
115
|
|
35
|
-
|
116
|
+
# generate all bytes for all classes
|
36
117
|
compile_ast(ast) do |outfile, builder|
|
37
118
|
bytes = builder.generate
|
38
119
|
name = builder.class_name.gsub(/\//, '.')
|
39
|
-
|
40
|
-
|
120
|
+
class_map[name] = bytes
|
121
|
+
end
|
122
|
+
|
123
|
+
# load all classes
|
124
|
+
dcl = DubyClassLoader.new(java.lang.ClassLoader.system_class_loader, class_map)
|
125
|
+
class_map.each do |name,|
|
126
|
+
cls = dcl.load_class(name)
|
41
127
|
# TODO: using first main; find correct one
|
42
|
-
|
43
|
-
main_cls ||= proxy_cls
|
44
|
-
end
|
128
|
+
main ||= cls.get_method("main", java::lang::String[].java_class) #rescue nil
|
45
129
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
130
|
+
|
131
|
+
# run the main method we found
|
132
|
+
if main
|
133
|
+
begin
|
134
|
+
main.invoke(nil, [args.to_java(:string)].to_java)
|
135
|
+
rescue java.lang.Exception => e
|
136
|
+
e = e.cause if e.cause
|
137
|
+
raise e
|
138
|
+
end
|
49
139
|
else
|
50
140
|
puts "No main found"
|
51
141
|
end
|
52
142
|
end
|
53
|
-
|
143
|
+
|
54
144
|
def compile(*args)
|
55
145
|
process_flags!(args)
|
56
|
-
|
146
|
+
|
57
147
|
expand_files(args).each do |duby_file|
|
58
148
|
if duby_file == '-e'
|
59
149
|
@filename = '-e'
|
@@ -66,7 +156,7 @@ class DubyImpl
|
|
66
156
|
exit 1 if @error
|
67
157
|
|
68
158
|
compile_ast(ast) do |filename, builder|
|
69
|
-
filename = "#{@
|
159
|
+
filename = "#{@state.destination}#{filename}"
|
70
160
|
FileUtils.mkdir_p(File.dirname(filename))
|
71
161
|
bytes = builder.generate
|
72
162
|
File.open(filename, 'w') {|f| f.write(bytes)}
|
@@ -79,19 +169,29 @@ class DubyImpl
|
|
79
169
|
process_flags!(args)
|
80
170
|
@filename = args.shift
|
81
171
|
|
82
|
-
if @filename
|
83
|
-
@filename
|
84
|
-
|
172
|
+
if @filename
|
173
|
+
if @filename == '-e'
|
174
|
+
@filename = 'DashE'
|
175
|
+
src = args[0]
|
176
|
+
else
|
177
|
+
src = File.read(@filename)
|
178
|
+
end
|
85
179
|
else
|
86
|
-
|
180
|
+
print_help
|
181
|
+
exit(1)
|
87
182
|
end
|
88
183
|
Duby::AST.type_factory = Duby::JVM::Types::TypeFactory.new(@filename)
|
89
|
-
|
90
|
-
|
184
|
+
begin
|
185
|
+
ast = Duby::AST.parse_ruby(src, @filename)
|
186
|
+
rescue org.jrubyparser.lexer.SyntaxException => ex
|
187
|
+
Duby.print_error(ex.message, ex.position)
|
188
|
+
raise ex if @state.verbose
|
189
|
+
end
|
190
|
+
@transformer = Duby::Transform::Transformer.new(@state)
|
91
191
|
ast = @transformer.transform(ast, nil)
|
92
192
|
@transformer.errors.each do |ex|
|
93
|
-
|
94
|
-
|
193
|
+
Duby.print_error(ex.message, ex.position)
|
194
|
+
raise ex.cause || ex if @state.verbose
|
95
195
|
end
|
96
196
|
@error = @transformer.errors.size > 0
|
97
197
|
ast
|
@@ -101,11 +201,18 @@ class DubyImpl
|
|
101
201
|
typer = Duby::Typer::JVM.new(@filename, @transformer)
|
102
202
|
typer.infer(ast)
|
103
203
|
begin
|
104
|
-
typer.resolve(
|
204
|
+
typer.resolve(false)
|
105
205
|
ensure
|
106
|
-
|
107
|
-
|
108
|
-
|
206
|
+
puts ast.inspect if @state.verbose
|
207
|
+
|
208
|
+
failed = !typer.errors.empty?
|
209
|
+
if failed
|
210
|
+
puts "Inference Error:"
|
211
|
+
typer.errors.each do |ex|
|
212
|
+
Duby.print_error(ex.message, ex.node.position)
|
213
|
+
puts ex.backtrace if @state.verbose
|
214
|
+
end
|
215
|
+
exit 1
|
109
216
|
end
|
110
217
|
end
|
111
218
|
|
@@ -115,35 +222,61 @@ class DubyImpl
|
|
115
222
|
end
|
116
223
|
|
117
224
|
def process_flags!(args)
|
118
|
-
|
225
|
+
@state ||= Duby::CompilationState.new
|
226
|
+
while args.length > 0 && args[0] =~ /^-/
|
119
227
|
case args[0]
|
120
|
-
when '-V'
|
228
|
+
when '--verbose', '-V'
|
121
229
|
Duby::Typer.verbose = true
|
122
230
|
Duby::AST.verbose = true
|
123
231
|
Duby::Compiler::JVM.verbose = true
|
124
|
-
@verbose = true
|
232
|
+
@state.verbose = true
|
125
233
|
args.shift
|
126
|
-
when '
|
234
|
+
when '--java', '-j'
|
127
235
|
require 'duby/jvm/source_compiler'
|
128
236
|
@compiler_class = Duby::Compiler::JavaSource
|
129
237
|
args.shift
|
130
|
-
when '-d'
|
238
|
+
when '--dest', '-d'
|
239
|
+
args.shift
|
240
|
+
@state.destination = File.join(File.expand_path(args.shift), '')
|
241
|
+
when '--cd'
|
131
242
|
args.shift
|
132
|
-
|
133
|
-
when '-p'
|
243
|
+
Dir.chdir(args.shift)
|
244
|
+
when '--plugin', '-p'
|
134
245
|
args.shift
|
135
246
|
plugin = args.shift
|
136
247
|
require "duby/plugin/#{plugin}"
|
137
248
|
when '-I'
|
138
249
|
args.shift
|
139
250
|
$: << args.shift
|
140
|
-
|
251
|
+
when '--classpath', '-c'
|
252
|
+
args.shift
|
253
|
+
Duby::Env.decode_paths(args.shift, $CLASSPATH)
|
254
|
+
when '--help', '-h'
|
255
|
+
print_help
|
256
|
+
exit(0)
|
257
|
+
when '-e'
|
141
258
|
break
|
259
|
+
else
|
260
|
+
puts "unrecognized flag: " + args[0]
|
261
|
+
print_help
|
262
|
+
exit(1)
|
142
263
|
end
|
143
264
|
end
|
265
|
+
@state.destination ||= File.join(File.expand_path('.'), '')
|
144
266
|
@compiler_class ||= Duby::Compiler::JVM
|
145
267
|
end
|
146
|
-
|
268
|
+
|
269
|
+
def print_help
|
270
|
+
$stdout.print "#{$0} [flags] <files or \"-e SCRIPT\">
|
271
|
+
-V, --verbose\t\tVerbose logging
|
272
|
+
-j, --java\t\tOutput .java source (jrubyc only)
|
273
|
+
-d, --dir DIR\t\tUse DIR as the base dir for compilation, packages
|
274
|
+
-p, --plugin PLUGIN\tLoad and use plugin during compilation
|
275
|
+
-c, --classpath PATH\tAdd PATH to the Java classpath for compilation
|
276
|
+
-h, --help\t\tPrint this help message
|
277
|
+
-e\t\t\tCompile or run the script following -e (naming it \"DashE\")"
|
278
|
+
end
|
279
|
+
|
147
280
|
def expand_files(files)
|
148
281
|
expanded = []
|
149
282
|
files.each do |filename|
|