⚠️ Warning: This is a draft ⚠️

This means it might contain formatting issues, incorrect code, conceptual problems, or other severe issues.

If you want to help to improve and eventually enable this page, please fork RosettaGit's repository and open a merge request on GitHub.

{{implementation|Brainfuck}}{{collection|RCBF}} ==Version 1== An implementation of a [[Brainfuck]] interpreter in [[Ruby]]. More effort could be made to read a program from a file or from stdin.

class RCBF
  def initialize(program)
    @d = [0] * 30_000
    @program = program
    @jumpback_table = read_program
  end

  def read_program
    jumpback_table = {}
    jump_to = []
    @program.each_char.with_index do |char, idx|
      case char
      when "[" then jump_to.push(idx)
      when "]" then jumpback_table[idx] = jump_to.pop
      end
    end
    jumpback_table
  end

  def run
    invert_table = @jumpback_table.invert
    dc = 0
    pc = 0
    while pc < @program.length
      print [pc, @program[pc]] 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 ?,
        @d[dc] = $stdin.getc
        print "\t#{dc},#{@d[dc]}" if $DEBUG
      when ?[
        if @d[dc] == 0
          pc = invert_table[pc]
          print "  #{[pc,@program[pc]]}" if $DEBUG
        end
      when ?]
        if @d[dc] != 0
          pc = @jumpback_table[pc]
          print "  #{[pc,@program[pc]]}" if $DEBUG
        end
      end
      puts if $DEBUG
      pc += 1
    end
  end
end

# output 'Hello World!\n'
helloworld = <<PROGRAM
++++++++++[>+++++++>++++++++++>+++>+<<<<-]
>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
PROGRAM
bf = RCBF.new(helloworld)
bf.run

# use nested loop to increment count to 64 and print (should be '@')
# followed by a newline
RCBF.new('>>++++[<++++[<++++>-]>-]<<.[-]++++++++++.').run

{{out}}

Hello World!
@

==Version 2== This variant converts the brainfuck into Ruby code and runs that instead. Do note that this requires Ruby1.9.1 or later, earlier versions need a somewhat more verbose variant.

BF code may be read from a file or taken from STDIN.

eval 'm=Hash.new(p=0);'+ARGF.read.gsub(
        /./,
        '>' => 'p+=1;',
        '<' => 'p-=1;',
        '+' => 'm[p]+=1;',
        '-' => 'm[p]-=1;',
        '[' => '(;',
        ']' => ')while((m[p]&=255)!=0);',
        '.' => 'putc(m[p]&=255);',
        ',' => 'm[p]=STDIN.getc.ord if !STDIN.eof;')