Created
February 25, 2009 00:37
-
-
Save ingramj/69910 to your computer and use it in GitHub Desktop.
A Brainfuck interpreter written in Ruby.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
class BrainFuck | |
def initialize | |
@ops = create_ops | |
@tape = Array.new(1024,0) | |
@tp = 0 | |
@code = [] | |
@cp = 0 | |
end | |
def compile c | |
c.split("").each do |o| | |
if @ops.has_key? o | |
@code << o | |
end | |
end | |
return self | |
end | |
def run | |
while @cp < @code.size | |
run_op @code[@cp] | |
end | |
@cp = 0 | |
end | |
private | |
def run_op op | |
@ops[op].call | |
@cp += 1 | |
end | |
def get_input | |
@tape[@tp] = STDIN.getc | |
# getc returns nil on EOF. We want to use 0 instead. | |
@tape[@tp] = 0 unless @tape[@tp] | |
end | |
def create_ops | |
{ ">" => Proc.new { @tp = (@tp == @tape.size - 1 ? 0 : @tp + 1) }, | |
"<" => Proc.new { @tp = (@tp == 0 ? @tape.size - 1 : @tp - 1) }, | |
"+" => Proc.new { @tape[@tp] += 1 }, | |
"-" => Proc.new { @tape[@tp] -= 1 }, | |
"." => Proc.new { print @tape[@tp].chr if @tape[@tp] }, | |
"," => Proc.new { get_input }, | |
"[" => Proc.new { jump_to_close if @tape[@tp] == 0 }, | |
"]" => Proc.new { jump_to_open unless @tape[@tp] == 0 } | |
} | |
end | |
def jump_to_close | |
level = 1 | |
while @cp < @code.size | |
@cp += 1 | |
if @code[@cp] == '[' | |
level += 1 | |
elsif @code[@cp] == ']' | |
level -= 1 | |
end | |
break if level == 0 | |
end | |
end | |
def jump_to_open | |
level = 1 | |
while @cp >= 0 | |
@cp -= 1 | |
if @code[@cp] == ']' | |
level += 1 | |
elsif @code[@cp] == '[' | |
level -= 1 | |
end | |
break if level == 0 | |
end | |
end | |
end | |
if __FILE__ == $0 | |
app = BrainFuck.new | |
File.open(ARGV[0], 'r') { |f| | |
app.compile(f.read) | |
} | |
app.run | |
end |
Seems I stand corrected! Cool, thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As far as I can tell, they behave the same. Here are the lines from the original:
Here's what happens when you enter a ^C character:
% cat test.bf
,.
% ruby brainfuck.rb test.bf | hexdump
^V^C
0000000 0003
0000001