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

Ruby で Brainfuck インタプリタ

以前から興味がありつつも、手をつけてなかった Brainfuck インタプリタRuby で実装してみました。*1

コード

class BrainFuck
  def convert(src)
    dst = Array.new(65536, 0)
    src_position = 0
    dst_position = 0
    while src_position < src.size
      case src[src_position]
        when ?>
          dst_position += 1
        when ?<
          dst_position -= 1
        when ?+
          dst[dst_position] += 1
        when ?-
          dst[dst_position] -= 1
        when ?.
          print dst[dst_position].chr
        when ?,
          dst[dst_position] = STDIN.getc
        when ?[
          if dst[dst_position] == 0
            pair = 1
            while pair != 0
              src_position = src_position + 1
              if(src[src_position] == ?[)
                pair += 1
              elsif(src[src_position] == ?])
                pair -= 1
              end
            end
          end
        when ?]
          if dst[dst_position] != 0
            pair = 1
            while pair != 0
              src_position -= 1
              if(src[src_position] == ?[)
                pair -= 1
              elsif(src[src_position] == ?])
                pair += 1
              end
            end
          end
        end
        src_position += 1
    end
  end
end

入力データサンプル

s = ">+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++
     ++>-]<.>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>
     ++++++++[<++++>-]<+.[-]++++++++++."

bf = BrainFuck.new
bf.convert(s)

実行結果

Hello World!

インタプリタの実装考えるの楽しいです。
にしても、えらく泥臭いコードになってしまった。。。
もうちょっとエレガントな実装にしたいんだけどなー。
そのうち、他の言語でも実装してみよっと。

*1:実際には1カ月くらい前の内容です、ブログアップ忘れてました