⚠️ 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;')