Created
August 25, 2021 18:37
-
-
Save 4hg/fe3c843b868e10986c25ba9add395bea to your computer and use it in GitHub Desktop.
My first and messy brainfuck interpreter written in ruby.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Interpreter | |
def initialize | |
@stack = Array.new(30_000, 0) | |
@loop_stack = Array.new | |
@prog = "" | |
@instruction_pointer = 0 | |
@data_pointer = 0 | |
end | |
def load_file file_name | |
@prog = open(file_name).readlines(chomp: true).join | |
end | |
def simple_exit_check = @instruction_pointer >= @prog.size | |
def mov_data_pointer op | |
if (@data_pointer - 1 < 0 && op == '<') || (@data_pointer + 1 >= @stack.size && op == '>') | |
raise "Cannot move data pointer outside array bounds" | |
else | |
@data_pointer += op == '<' ? -1 : 1 | |
end | |
end | |
def incr_curr_byte = @stack[@data_pointer] = (@stack[@data_pointer] + 1) % 256 | |
def decr_curr_byte = @stack[@data_pointer] = (@stack[@data_pointer] - 1) % 256 | |
def output_curr_byte = print(@stack[@data_pointer].chr) | |
def read_byte_and_store | |
input = gets[0] | |
input = 10 if input == '\n' | |
@stack[@data_pointer] = input == "4" ? 0 : input.ord | |
end | |
def exec_next_command | |
op = @prog[@instruction_pointer] | |
case op | |
when '>' | |
self.mov_data_pointer(op) | |
when '<' | |
self.mov_data_pointer(op) | |
when '+' | |
self.incr_curr_byte() | |
when '-' | |
self.decr_curr_byte() | |
when '.' | |
self.output_curr_byte() | |
when ',' | |
self.read_byte_and_store() | |
when '[' | |
if @stack[@data_pointer] == 0 | |
@instruction_pointer += 1 while @prog[@instruction_pointer] != ']' | |
@instruction_pointer += 1 | |
else | |
@loop_stack.push @instruction_pointer | |
end | |
when ']' | |
@stack[@data_pointer] != 0 ? @instruction_pointer = @loop_stack.last : @loop_stack.pop | |
end | |
@instruction_pointer += 1 | |
end | |
end | |
i = Interpreter.new | |
print "Enter a bf filename: " | |
i.load_file(gets.chomp) | |
while not i.simple_exit_check() | |
i.exec_next_command() | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment