I wrote this interpreter for a code challenge. Can this be written any cleaner/smaller? Could I reduce the amount of nested conditional/loops?
def brain_luck(code, input)
output = ''
cp = 0 # code pointer
dp = 0 # data pointer
ip = 0 # input pointer
data = Array.new(10, 0)
while cp < code.length
case code[cp]
when '>'
dp += 1
if dp == data.length
data.push(0)
end
when '<'
dp -= 1
if dp == -1
dp = 0
data.unshift(0)
end
when '+'
data[dp] = (data[dp].ord+1)%256
when '-'
data[dp] = (data[dp].ord-1)%256
when '.'
output += data[dp].chr
when ','
data[dp] = input[ip].ord
ip += 1
when '['
if data[dp] == 0
nest_count = 1
while nest_count > 0
case code[cp += 1]
when '[' then nest_count += 1
when ']' then nest_count -= 1
end
end
end
when ']'
if data[dp] != 0
nest_count = 1
while nest_count > 0
case code[cp -= 1]
when ']' then nest_count += 1
when '[' then nest_count -= 1
end
end
end
end
cp += 1
end
output
end
1 Answer 1
Sure it can!
Steps I see to make it clean:
Create a class, define state attrs:
private attr_reader :output, :code_pointer, :data_pointer, :input_pointer
define initialize method
def initialize(args = {}) @code = args[:code] @input = args[:input] @output = '' @code_pointer, @data_pointer, @input_pointer = 0, 0, 0 end
define
whens
as a methods and give it right names:next_cell
,prev_cell
,increment
,decrement
,write_byte
,read_byte
and so ondefine constant for configuration:
OPERATORS = { '>' => :next_cell, '<' => :prev_cell, '+' => :increment, ... }
define method to evaluate code:
def evaluate_code code.each { |operator| public_send OPERATORS[operator] } end
Finally instantiate object of your class and call evaluate_code
BrainLuck.new(code: code, input: input).evaluate_code
I think you'll love your object oriented result.
Explore related questions
See similar questions with these tags.
brain_luck
is not the way to go. It's confusing since it doesn't make sense why there is a function like that. You could just do something likeeval_program
. \$\endgroup\$brain_luck
was how the code challenge presented it (same with the double*
inbrainf**k
) \$\endgroup\$,>+>>>>++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++++<<<<<<[>[>>>>>>+>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]<[>++++++++++[-<-[>>+>+<<<-]>>>[<<<+>>>-]+<[>[-]<[-]]>[<<[>>>+<<<-]>>[-]]<<]>>>[>>+>+<<<-]>>>[<<<+>>>-]+<[>[-]<[-]]>[<<+>>[-]]<<<<<<<]>>>>>[++++++++++++++++++++++++++++++++++++++++++++++++.[-]]++++++++++<[->-<]>++++++++++++++++++++++++++++++++++++++++++++++++.[-]<<<<<<<<<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<-[>>.>.<<<[-]]<<[>>+>+<<<-]>>>[<<<+>>>-]<<[<+>-]>[<+>-]<<<-]
\$\endgroup\$