On Nov 25, 2008, at 11:07 AM, brabuhr / gmail.com wrote: > 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 Seems like this program is: 1 1 + 2 3 + - . Which seems to be -3, not 3. I think you have your args out of order. Look at how the non-commutative ops are defined. -Rob Rob Biedenharn http://agileconsultingllc.com Rob / AgileConsultingLLC.com