読者です 読者をやめる 読者になる 読者になる

Mae向きなブログ

Mae向きな日記のブログ版。ようやくこちらに移行してきました。

仮想スタックマシンの製作

今日は、「Javaコンパイラの基礎を理解する*1」を読んでみました。
非常に簡単な例で解説されていて分かりやすいです。
読んだだけでは、身についているか怪しいので、Rubyで書いてみました。
今日は、仮想スタックマシンを作っただけです。

svm1.rb

class Svm1
  attr_accessor :code, :operandStack, :alu, :pc
  def initialize
    @code = []
    @operandStack = []
    @alu = Alu.new
  end

  def execute
    @pc = 0
    while (@pc < @code.length)
      executeCommand(@code[@pc])
      @pc += 1
    end
  end

  def executeCommand(command)
    case command
    when 16
      @pc += 1
      @operandStack.push(@code[@pc])
    when 96 
      b = @operandStack.pop
      a = @operandStack.pop
      @operandStack.push(@alu.add(a, b))
    when 104
      b = @operandStack.pop
      a = @operandStack.pop
      @operandStack.push(@alu.multiply(a, b))
    when -48
      puts @operandStack.last
    end
  end

  def load(filename)
    File.open(filename) do |f|
      data = f.read
      @code = data.unpack("c*")
    end
  end

  class Alu
    def add(a, b)
      return a + b
    end
    def multiply(a, b)
      return a * b
    end
  end
end

if __FILE__ == $0
  filename = ARGV[0]
  svm1 = Svm1.new
  svm1.load(filename)
  svm1.execute()
end

実行結果

mmasa@debian:~/work/ruby/svm$ ruby svm1.rb code0.svm
3
mmasa@debian:~/work/ruby/svm$ ruby svm1.rb code1.svm
7
mmasa@debian:~/work/ruby/svm$ ruby svm1.rb code2.svm
9