Class: DubyImpl

Inherits:
Object show all
Defined in:
lib/duby.rb

Instance Method Summary collapse

Instance Method Details

#compile(*args) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/duby.rb', line 56

def compile(*args)
  process_flags!(args)
  
  expand_files(args).each do |duby_file|
    if duby_file == '-e'
      @filename = '-e'
      next
    elsif @filename == '-e'
      ast = parse('-e', duby_file)
    else
      ast = parse(duby_file)
    end
    exit 1 if @error

    compile_ast(ast) do |filename, builder|
      filename = "#{@dest}#{filename}"
      FileUtils.mkdir_p(File.dirname(filename))
      bytes = builder.generate
      File.open(filename, 'w') {|f| f.write(bytes)}
    end
    @filename = nil
  end
end

#compile_ast(ast, &block) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/duby.rb', line 102

def compile_ast(ast, &block)
  typer = Duby::Typer::JVM.new(@filename)
  typer.infer(ast)
  begin
    typer.resolve(true)
  ensure
    typer.errors.each do |ex|
      puts ex.message
      puts ex.backtrace if @verbose
    end
  end

  compiler = @compiler_class.new(@filename)
  ast.compile(compiler, false)
  compiler.generate(&block)
end

#expand_files(files) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/duby.rb', line 149

def expand_files(files)
  expanded = []
  files.each do |filename|
    if File.directory?(filename)
      Dir[File.join(filename, '*')].each do |child|
        if File.directory?(child)
          files << child
        elsif child =~ /\.duby$/
          expanded << child
        end
      end
    else
      expanded << filename
    end
  end
  expanded
end

#parse(*args) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/duby.rb', line 80

def parse(*args)
  process_flags!(args)
  @filename = args.shift

  if @filename == '-e'
    @filename = 'dash_e'
    src = args[0]
  else
    src = File.read(@filename)
  end
  Duby::AST.type_factory = Duby::JVM::Types::TypeFactory.new(@filename)
  ast = Duby::AST.parse_ruby(src, @filename)
  @transformer = Duby::Transform::Transformer.new
  ast = @transformer.transform(ast, nil)
  @transformer.errors.each do |ex|
    raise ex.cause || ex if @verbose
    puts "#@filename:#{ex.position.start_line+1}: #{ex.message}"
  end
  @error = @transformer.errors.size > 0
  ast
end

#process_flags!(args) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/duby.rb', line 119

def process_flags!(args)
  while args.length > 0
    case args[0]
    when '-V'
      Duby::Typer.verbose = true
      Duby::AST.verbose = true
      Duby::Compiler::JVM.verbose = true
      @verbose = true
      args.shift
    when '-java'
      require 'duby/jvm/source_compiler'
      @compiler_class = Duby::Compiler::JavaSource
      args.shift
    when '-d'
      args.shift
      @dest = File.join(args.shift, '')
    when '-p'
      args.shift
      plugin = args.shift
      require "duby/plugin/#{plugin}"
    when '-I'
      args.shift
      $: << args.shift
    else
      break
    end
  end
  @compiler_class ||= Duby::Compiler::JVM
end

#run(*args) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/duby.rb', line 34

def run(*args)
  ast = parse(*args)

  main_cls = nil
  compile_ast(ast) do |outfile, builder|
    bytes = builder.generate
    name = builder.class_name.gsub(/\//, '.')
    cls = JRuby.runtime.jruby_class_loader.define_class(name, bytes.to_java_bytes)
    proxy_cls = JavaUtilities.get_proxy_class(name)
    # TODO: using first main; find correct one
    if proxy_cls.respond_to? :main
      main_cls ||= proxy_cls
    end
  end

  if main_cls
    main_cls.main(args.to_java(:string))
  else
    puts "No main found"
  end
end