Skip to content

Instantly share code, notes, and snippets.

@dbrady
Created March 6, 2012 02:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dbrady/1982974 to your computer and use it in GitHub Desktop.
Save dbrady/1982974 to your computer and use it in GitHub Desktop.
Brainfuck to Ruby compiler
#!/usr/bin/env ruby
# bfr - brainfuck 2 ruby
# Usage:
# ./bfr "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."
# => Hello World!
INDENT = " "
START_CODE = <<CODE
r=[0]*30000
i=0
def getch()
system('stty raw -echo')
STDIN.getc.ord
end
CODE
END_CODE = ""
opcodes = {
'>' => 'i+=1',
'<' => 'i-=1',
'+' => 'r[i]+=1',
'-' => 'r[i]-=1',
'.' => 'print r[i].chr',
',' => 'r[i]=getch',
'[' => 'while !r[i].zero?',
']' => 'end'
}
bf_program = ARGV[0]
ruby_program = START_CODE + "\n"
keys = opcodes.keys
indent_level = 0
byte = 0
bf_program.split(//).each do |code|
byte += 1
raise "Illegal Opcode: '#{code}' at byte #{byte}" unless keys.include?(code)
indent_level -= 1 if code == ']'
raise "Unexpected ']' at byte #{byte}" if indent_level < 0
indentation = INDENT * indent_level
ruby_program += indentation + opcodes[code] + "\n"
indent_level += 1 if code == '['
end
raise "Unclosed '[' at end of program" unless indent_level == 0
ruby_program += END_CODE
File.open("brainfuck.ruby", "w") do |file|
file.puts ruby_program
end
if (system "ruby brainfuck.ruby")
system "rm brainfuck.ruby"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment