Branfuckインタプリタ

30分プログラム、その361。ネタ言語とし有名なBrainfuckインタプリタを書いてみた。
ちなみに、サンプルコードはこのへんからもらってきた。

使い方

$ ruby brainfuck.rb HELLOBF.BF
Hello World!

ソースコード

#! /opt/local/bin/ruby -w
# -*- mode:ruby; coding:utf-8 -*-
#
# brainfuck.rb -
#
# Copyright(C) 2008 by mzp
# Author: MIZUNO Hiroki / mzpppp at gmail dot com
# http://howdyworld.org
#
# Timestamp: 2008/09/09 21:19:31
#
# This program is free software; you can redistribute it and/or
# modify it under MIT Lincence.
#

class Memory
  def initialize
    @memory = []
    @index  = 0
  end

  def value
    @memory[@index]
  end

  def value=(val)
    @memory[@index] = val
  end

  def inc_ptr
    @index += 1
  end

  def dec_ptr
    @index -= 1
  end

  def inc_val
    @memory[@index] = 0 unless @memory[@index]
    @memory[@index] += 1
  end

  def dec_val
    @memory[@index] = 0 unless @memory[@index]
    @memory[@index] -= 1
  end
end

def parse(xs)
  memory = Memory.new
  bytes = xs.unpack 'C*'
  index = 0
  stack = []
  until bytes.size == index + 1
    b = bytes[index]
    index += 1

    case b
    when ?>
      memory.inc_ptr
    when ?<
      memory.dec_ptr
    when ?+
      memory.inc_val
    when ?-
      memory.dec_val
    when ?.
      putc memory.value.chr
    when ?,
      c = STDIN.getc
      memory.value = c
    when ?[
      stack.push(index-1)
      if memory.value == 0
        count = 1
        until count == 0
          index+=1
          case bytes[index]
          when ?[
            count += 1
          when ?]
            count -= 1
          end
        end
      end
    when ?]
      index = stack.pop unless memory.value == 0
    end
  end
end

parse $<.read