HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyMinor

Brainf**k to Ruby interpreter -- v3

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
interpreterbrainfruby

Problem

Previous iteration.

I think this is about as good as it's gonna get, but just for kicks, let's do one more round of iterations.

As before, it's a very simple substitution from Brainfuck to Ruby, with fancy things like joining duplicate lines into one and indentation.

Some things that bug me:

  • The regex (/\++|-+|+|[.,\[\]]/) feels like it can be simplified, but I can't figure out how.



  • I feel like the map can be simplified, but I can't figure out how.



  • The constant repetition of #{' ' * indent_level} bugs me, but I can't see how to get rid of it.



  • indent_level being declared outside of the scope of each feels like an anti-pattern, but AFAICT there's no better way to do it.



input_file, output_file = ARGV
code = IO.read(input_file).delete('^+-<>.,[]')

open(output_file, File::CREAT | File::WRONLY) do |output|
  output.puts +|[.,\[\]]/)
      .map do |string|
        case string[0]
          when '+' #String of "+"
            next "#{'  ' * indent_level}data[pointer] += #{string.length}"
          when '-' #String of "-"
            next "#{'  ' * indent_level}data[pointer] -= #{string.length}"
          when '' #String of ">"
            next "#{'  ' * indent_level}pointer += #{string.length}"
          when '[' #Single "["
            ret = "#{'  ' * indent_level}until data[pointer] == 0"
            indent_level += 1
            next ret #Split it so that it's clear that indent is increased *after* the line
          when ']' #Single "]"
            indent_level -= 1
            next "#{'  ' * indent_level}end"
          when ',' #Single ","
            next "#{'  ' * indent_level}data[pointer] = $stdin.readbyte"
          when '.' #Single "."
            next "#{'  ' * indent_level}putc data[pointer]"
        end
      end.each { |line| output.puts(line) }
end

Solution

I'm not 100% sure this works in Ruby, but can you use constants with string interpolation? This string is repeated a lot. I doubt it will ever change, but if it does, it would be nice to only have to change it once.

"#{'  ' * indent_level}data[pointer]"


Could be #{' ' * indent_level}#{DATA}.

Code Snippets

"#{'  ' * indent_level}data[pointer]"

Context

StackExchange Code Review Q#94596, answer score: 5

Revisions (0)

No revisions yet.