Matthew Moss <> 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,

osition, :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