Execute Brain****/Ruby: Difference between revisions

From Rosetta Code
Content added Content deleted
m (needs attention: nested loops)
(handle nested loops)
Line 1: Line 1:
{{implementation|Brainf***}}{{collection|RCBF}}[[Category:Ruby]]
{{implementation|Brainf***}}{{collection|RCBF}}[[Category:Ruby]]
{{needs-review|Ruby|'''Does not handle nested loops.'''}}
More effort could be made to read a program from a file or from stdin.
More effort could be made to read a program from a file or from stdin.


Line 7: Line 6:
@d = [0] * 30_000
@d = [0] * 30_000
@program = program
@program = program
@jumpback_table = read_program
end
def read_program
jumpback_table = {}
nest_level = 0
start_idx = []
@program.each_char.each_with_index do |char, idx|
case char
when "["
start_idx[nest_level] = idx
nest_level += 1
when "]"
nest_level -= 1
jumpback_table[idx] = start_idx[nest_level]
end
end
jumpback_table
end
end


Line 36: Line 53:
when ?[ then
when ?[ then
if @d[dc] == 0
if @d[dc] == 0
pc += 1 while @program[pc] != ?]
pc = @jumpback_table.invert[pc]
p " #{[pc,@program[pc].chr].inspect}" if $DEBUG
p " #{[pc,@program[pc].chr].inspect}" if $DEBUG
end
end
when ?] then
when ?] then
if @d[dc] != 0
if @d[dc] != 0
pc -= 1 while @program[pc] != ?[
pc = @jumpback_table[pc]
p " #{[pc,@program[pc].chr].inspect}" if $DEBUG
p " #{[pc,@program[pc].chr].inspect}" if $DEBUG
end
end
Line 49: Line 66:
end
end
end
end
end</lang>
end

Test:
# output 'Hello World!\n'
<pre>irb(main):048:0> helloworld = '++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.'
helloworld = <<PROGRAM
=> "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."
++++++++++[>+++++++>++++++++++>+++>+<<<<-]
irb(main):049:0> bf = RCBF.new(helloworld)
>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
=> #<RCBF:0x7ff537d0 @d=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
PROGRAM
...
bf = RCBF.new(helloworld)
irb(main):050:0> bf.run
bf.run
Hello World!

=> nil</pre>
# use nested loop to increment count to 64 and print (should be '@')"
# 64 = 4*4*4
nestedloop = '>>++++[<++++[<++++>-]>-]<<.[-]++++++++++.'
bf = RCBF.new(nestedloop)
bf.run</lang>

Output:
<pre>Hello World!
@</pre>

Revision as of 18:13, 7 August 2009

Execute Brain****/Ruby is an implementation of Brainf***. Other implementations of Brainf***.
Execute Brain****/Ruby is part of RCBF. You may find other members of RCBF at Category:RCBF.

More effort could be made to read a program from a file or from stdin.

<lang ruby>class RCBF

 def initialize(program)
   @d = [0] * 30_000
   @program = program
   @jumpback_table = read_program
 end
 
 def read_program
   jumpback_table = {}
   nest_level = 0
   start_idx = []
   @program.each_char.each_with_index do |char, idx|
     case char
     when "["
       start_idx[nest_level] = idx
       nest_level += 1
     when "]"
       nest_level -= 1
       jumpback_table[idx] = start_idx[nest_level]
     end
   end
   jumpback_table
 end
 def run
   dc = 0
   pc = 0
   while pc < @program.length
     print [pc, @program[pc].chr].inspect if $DEBUG
     case @program[pc]
     when ?> 
       dc += 1
       print "\t#{dc}" if $DEBUG
     when ?< 
       dc -= 1
       print "\t#{dc}" if $DEBUG
     when ?+ 
       @d[dc] += 1
       print "\t#{dc},#{@d[dc]}" if $DEBUG
     when ?- 
       @d[dc] -= 1
       print "\t#{dc},#{@d[dc]}" if $DEBUG
     when ?. 
       print "\t#{dc},#{@d[dc]}\t" if $DEBUG
       print @d[dc].chr
     when ?, then
       @d[dc] = $stdin.getc
       print "\t#{dc},#{@d[dc]}" if $DEBUG
     when ?[ then
       if @d[dc] == 0
         pc = @jumpback_table.invert[pc]
         p "  #{[pc,@program[pc].chr].inspect}" if $DEBUG
       end
     when ?] then
       if @d[dc] != 0
         pc = @jumpback_table[pc]
         p "  #{[pc,@program[pc].chr].inspect}" if $DEBUG
       end
     end
     puts if $DEBUG
     pc += 1
   end
 end

end

  1. output 'Hello World!\n'

helloworld = <<PROGRAM ++++++++++[>+++++++>++++++++++>+++>+<<<<-] >++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>. PROGRAM bf = RCBF.new(helloworld) bf.run

  1. use nested loop to increment count to 64 and print (should be '@')"
  2. 64 = 4*4*4

nestedloop = '>>++++[<++++[<++++>-]>-]<<.[-]++++++++++.' bf = RCBF.new(nestedloop) bf.run</lang>

Output:

Hello World!
@