Skip to content

Instantly share code, notes, and snippets.

@dtan4
Last active December 14, 2015 14:29
Show Gist options
  • Save dtan4/5100887 to your computer and use it in GitHub Desktop.
Save dtan4/5100887 to your computer and use it in GitHub Desktop.
Brainf*ck interpreter
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
MEMORY_SIZE = 30000
ASCII_SIZE = 256
def parse(code)
memory = []
MEMORY_SIZE.times do
memory << 0
end
ptr = 0
idx = 0
step = 0
output = ""
while idx < code.length
c = code[idx]
step += 1
case c
when '>' # increment pointer
ptr += 1
if ptr >= MEMORY_SIZE
puts "pointer out of range (too big) <#{idx}>"
exit 1
end
when '<' # decrement pointer
ptr -= 1
if ptr < 0
puts "pointer out of range (too small) <#{idx}>"
exit 1
end
when '+' # increment memory num
memory[ptr] += 1
if memory[ptr] >= ASCII_SIZE
puts "memory[#{ptr}] out of range (too big) <#{idx}>"
exit 1
end
when '-' # decrement memory num
memory[ptr] -= 1
if memory[ptr] < 0
puts "memory[#{ptr}] out of range (too small) <#{idx}>"
exit 1
end
when '.' # output the character at pointer
output += memory[ptr].chr()
when ',' # input the character
puts "Sorry, but input operator(,) is NOT supported..."
exit 1
when '['
if memory[ptr] == 0
depth = 0
loop do
idx += 1
step += 1
if idx >= code.length
puts "index out of range <#{idx}>"
exit 1
end
if code[idx] == '['
depth += 1
elsif code[idx] == ']'
if depth == 0
break
else
depth -= 1
end
end
end
end
when ']'
if memory[ptr] > 0
depth = 0
loop do
idx -= 1
step += 1
if idx < 0
puts "index out of range (#{i})"
exit 1
end
if code[idx] == ']'
depth += 1
elsif code[idx] == '['
if depth == 0
break
else
depth -= 1
end
end
end
end
else
puts "Invalid operator: #{c}"
exit 1
end
idx += 1
end
puts "output: #{output}"
puts "step : #{step}"
end
# ----- main ----- #
if ARGV.length < 0
exit 1
end
# remove except operator
code = ARGV.join.gsub(/[^><+-.,\[\]]/, "")
puts code
parse(code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment