Matthew Moss <matt / moss.name> wrote:
>  def run
>    loop do
>      if @stringmode
>        case curr
>        when ?"
>          @stringmode = false
>        else
>          push curr
>        end
>      else
>        case curr
>        when ?0..?9
>          push (curr - ?0)
>        when ?+, ?-, ?*, ?/, ?%
>          b, a = pop, pop
>          push a.send(curr.to_sym, b)

My first thought was a big case statement like that, but wanted
something a bit more "fun".  My next thoughts were to try something
with lambda or define_method.  Here's a really rough, partial (and
almost entirely untested) implementation built around define_method:

class Befunge93
  instance_methods.each { |m| undef_method m unless (m =~ /^__|send/) }

  attr_accessor :stack, :memory, :position, :direction

  def initialize
    @stack = []
    @memory = {}
    @position = [0,0]
    @direction = [1,0]
  end

  def move
    @position[0] = (@position[0] + @direction[0]) % 80
    @position[1] = (@position[1] + @direction[1]) % 25
  end

  def run
    loop do
      send @memory[@position]
      move
    end
  end

  (0..9).each do |d|
    define_method :"#{d}" do
      @stack.push d
    end
  end

  %w{ + - * / }.each do |o|
    define_method :"#{o}" do
      a, b = @stack.pop, @stack.pop
      @stack.push a.send(:"#{o}", b)
    end
  end

  [
    [ '^', [ 0,-1] ],
    [ 'v', [ 0, 1] ],
    [ '<', [-1, 0] ],
    [ '>', [ 1, 0] ]
  ].each do |d|
    define_method :"#{d[0]}" do
      @direction = d[1]
    end
  end

  define_method :"." do
    print @stack.pop
  end

  define_method :"@" do
    puts
    exit
  end
end

bf = Befunge93.new

bf.memory = {
  [0,0] => "v", [1,0] => " ", [2,0] => " ", [3,0] => " ", [4,0] => " ",
  [0,1] => "1", [1,1] => "v", [2,1] => "<", [3,1] => " ", [4,1] => " ",
  [0,2] => "1", [1,2] => "3", [2,2] => "2", [3,2] => " ", [4,2] => " ",
  [0,3] => ">", [1,3] => "+", [2,3] => "^", [3,3] => " ", [4,3] => " ",
  [0,4] => " ", [1,4] => "-", [2,4] => " ", [3,4] => " ", [4,4] => " ",
  [0,5] => " ", [1,5] => ".", [2,5] => " ", [3,5] => " ", [4,5] => " ",
  [0,6] => " ", [1,6] => "@", [2,6] => " ", [3,6] => " ", [4,6] => " ",
  [0,7] => " ", [1,7] => " ", [2,7] => " ", [3,7] => " ", [4,7] => " ",
  [0,8] => " ", [1,8] => " ", [2,8] => " ", [3,8] => " ", [4,8] => " ",
}

bf.run #=> 3