patternrubyMinor
Brainf**k to Ruby converter, written in Ruby -- v1.0
Viewed 0 times
converterwrittenbrainfruby
Problem
I've seen a lot of Brainfk interpreters in various languages. I decided that actually interpreting Brainfk is too hard, so instead of that, I wrote a 'compiler' in Ruby that directly transcribes BF to Ruby code. This is Version 1.0, and I'm looking for any tips on how to make it more efficient.
There are a few things that really bug me:
Demo
Input:
Output:
`# Automatically generated by bf_to_ruby.rb
# Source available at GitHub
data = Hash.new(0)
pointer = 0
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
until data[pointer] == 0
pointer += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
until data[pointer] == 0
pointer += 1
data[pointer] += 1
data[pointer] += 1
pointer += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
pointer += 1
data[pointer] += 1
data[pointer] += 1
data[pointer
There are a few things that really bug me:
replacementsfeels like it's messed up somehow, but I can't put my finger on how.
$stdin.readbytefeels entirely too long, but I can't find an alternative that's shorter.
- Should I be using
$stdinat all?
input_file = $ARGV[0]
output_file = $ARGV[1]
start = ', replacement: 'pointer += 1' },
{ replacing: '<', replacement: 'pointer -= 1' },
{ replacing: '.', replacement: 'putc data[pointer]' },
{ replacing: ',', replacement: 'data[pointer] = $stdin.readbyte' },
{ replacing: '[', replacement: 'until data[pointer] == 0' },
{ replacing: ']', replacement: 'end' },
]
output = open(output_file, File::CREAT | File::WRONLY)
output.puts(start)
open(input_file, File::RDONLY) do |input|
input.each_char do |char|
replacements.each do |data|
if data[:replacing] == char
output.puts(data[:replacement])
end
end
end
endDemo
Input:
++++++++[>++++[>++>+++>+++>++>+>->>+[>.>---.+++++++..+++.>>.>+.>++.Output:
`# Automatically generated by bf_to_ruby.rb
# Source available at GitHub
data = Hash.new(0)
pointer = 0
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
until data[pointer] == 0
pointer += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
until data[pointer] == 0
pointer += 1
data[pointer] += 1
data[pointer] += 1
pointer += 1
data[pointer] += 1
data[pointer] += 1
data[pointer] += 1
pointer += 1
data[pointer] += 1
data[pointer] += 1
data[pointer
Solution
You should open the input file before the output file, so that if the input file is unreadable, no file is created at all. File opening should be done using blocks for automatic closure and cleanup.
This is too complicated:
One big
This is too complicated:
replacements.each do |data|
if data[:replacing] == char
output.puts(data[:replacement])
end
endreplacements would be better as a Hash:replacements = {
'+' => 'data[pointer] += 1',
'-' => 'data[pointer] -= 1',
'>' => 'pointer += 1',
' 'pointer -= 1',
'.' => 'putc data[pointer]',
',' => 'data[pointer] = $stdin.readbyte',
'[' => 'until data[pointer] == 0',
']' => 'end',
}
open(input_file, File::RDONLY) do |input|
open(output_file, File::CREAT | File::WRONLY) do |output|
output.puts(start)
output.puts(input.each_char.map { |c| replacements[c] }.compact.join("\n"))
end
endOne big
puts should be faster than many indivual puts.Code Snippets
replacements.each do |data|
if data[:replacing] == char
output.puts(data[:replacement])
end
endreplacements = {
'+' => 'data[pointer] += 1',
'-' => 'data[pointer] -= 1',
'>' => 'pointer += 1',
'<' => 'pointer -= 1',
'.' => 'putc data[pointer]',
',' => 'data[pointer] = $stdin.readbyte',
'[' => 'until data[pointer] == 0',
']' => 'end',
}
open(input_file, File::RDONLY) do |input|
open(output_file, File::CREAT | File::WRONLY) do |output|
output.puts(start)
output.puts(input.each_char.map { |c| replacements[c] }.compact.join("\n"))
end
endContext
StackExchange Code Review Q#94489, answer score: 6
Revisions (0)
No revisions yet.