summaryrefslogtreecommitdiffstats
path: root/tool/compile.rb
blob: 66960f985115dc972cf0ac779a73fadaceb15f49 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
require 'optparse'
require 'pp'

OutputCompileOption = {
  # enable
  :peephole_optimization    =>true,
  :inline_const_cache       =>true,
  
  # disable
  :specialized_instruction  =>false,
  :operands_unification     =>false,
  :instructions_unification =>false,
  :stack_caching            =>false,
}

def compile_to_rb infile, outfile
  iseq = VM::InstructionSequence.compile_file(infile, OutputCompileOption)

  open(outfile, 'w'){|f|
    f.puts "VM::InstructionSequence.load(" +
           "Marshal.load(<<EOS____.unpack('m*')[0])).eval"
    f.puts [Marshal.dump(iseq.to_a)].pack('m*')
    f.puts "EOS____"
  }
end

def compile_to_rbc infile, outfile, type
  iseq = VM::InstructionSequence.compile_file(infile, OutputCompileOption)

  case type
  when 'm'
    open(outfile, 'wb'){|f|
      f.print "RBCM"
      f.puts Marshal.dump(iseq.to_a, f)
    }
  else
    raise "Unsupported compile type: #{type}"
  end
end

## main

outfile = 'a.rb'
type    = 'm'
opt = OptionParser.new{|opt|
  opt.on('-o file'){|o|
    outfile = o
  }
  opt.on('-t type', '--type type'){|o|
    type = o
  }
  opt.version = '0.0.1'
}

opt.parse!(ARGV)

ARGV.each{|file|
  case outfile
  when /\.rb\Z/
    compile_to_rb file, outfile
  when /\.rbc\Z/
    compile_to_rbc file, outfile, type
  else
    raise
  end
}