
require 'yarvcore'
require 'tempfile'

module YARVUtil
  
  def self.eval prog, file='<*YARV eval*>', line=1
eval_in_wrap(<<__EOMP__)
YARVCore.eval(<<'__EOP__', '#{file}', #{line})
#{prog}
__EOP__
__EOMP__
  end

  def self.parse prog, file='<*YARV parse*>', line=1
eval_in_wrap(<<__EOMP__)
YARVCore.parse(<<'__EOP__', '#{file}', #{line})
#{prog}
__EOP__
__EOMP__
  end

  def self.load file
prog = File.read(file)
eval_in_wrap(<<__EOMP__)
YARVCore.eval(<<'__EOP__', '#{file}', 1)
#{prog}
__EOP__
__EOMP__
  end

  def self.load_bm file
prog = File.read(file)
Kernel.eval(<<__EOMP__, TOPLEVEL_BINDING)
YARVCore.eval(<<'__EOP__', '#{file}', 1)
#{prog}
__EOP__
__EOMP__
  end

  def self.ruby_version
    "ruby #{RUBY_VERSION} #{RUBY_PLATFORM}(#{RUBY_RELEASE_DATE})"
  end

  def self.eval_in_wrap prog, fname='*eval*', line=1
    t = Tempfile.new('eval-in-rwap-')
t.write(<<__EOS__EIW__)
$ans = eval(<<'__EOP__EIW__', TOPLEVEL_BINDING, #{fname.inspect}, #{line})
#{prog}
__EOP__EIW__
__EOS__EIW__
     t.close
     Kernel.load(t.path, true)
     $ans
  end

  def self.dump_usage_analisys
    return if YARVCore::USAGE_ANALISYS_INSN.size == 0
    YARVCore::USAGE_ANALISYS_INSN.sort.each{|insn_no, iinfo|
      puts "#{YARVCore::InsnNameArray[insn_no]}\t#{iinfo[-1]}"
    }
    return
    puts "----------------"
    puts "= Usage Analisys"
    puts
    puts "== Insn/operand usage"
    YARVCore::USAGE_ANALISYS_INSN.sort.each{|insn_no, iinfo|
      puts "#{YARVCore::InsnNameArray[insn_no]}:"
      puts       "  count: #{iinfo[-1]}"
      puts       "  operands:"
      iinfo.sort.each{|op_no, ophash|
        if op_no == -1
          next
        else
          puts   "  = #{op_no}:"
          ophash.each{|v, count|
            puts "   > #{'%-8s' % v}: #{count}"
          }
        end
      }
    }
    puts
    puts "== Register usage:"
    YARVCore::USAGE_ANALISYS_REGS.sort_by{|e|
      e[0].to_i
    }.each{|reg, cnt|
      puts "  #{reg} : #{'%5d' % cnt}"
    }
    puts
    puts "== Insns bigram"
    YARVCore::USAGE_ANALISYS_INSN_BIGRAM.sort.each{|e, c|
      puts '%-16s - %-16s: %5d' %
      [YARVCore::InsnNameArray[e[0]], YARVCore::InsnNameArray[e[1]], c]
    }
  end
end

