今日は、「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