Created
January 18, 2022 10:18
-
-
Save marek22k/7e90c0ec2608b027437e7b201cdad618 to your computer and use it in GitHub Desktop.
Ruby script that interprets brainfuck code
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 BrainfuckInterpreter | |
| BF_CHARS = { | |
| inc_ptr: ">", | |
| dec_ptr: "<", | |
| inc_val: "+", | |
| dec_val: "-", | |
| loop_begin: "[", | |
| loop_end: "]", | |
| output: ".", | |
| input: "," | |
| } | |
| attr_reader :rounds, :max, :output, :pointer | |
| attr_accessor :code | |
| def initialize | |
| @code = "" | |
| @code_pointer = 0 | |
| @cells = [] | |
| @pointer = 0 | |
| @rounds = 0 | |
| @max = 1 | |
| end | |
| def reset! | |
| @code_pointer = 0 | |
| @cells = [] | |
| @pointer = 0 | |
| @rounds = 0 | |
| @max = 1 | |
| end | |
| def interpret! bf_cmds = BF_CHARS, input: $stdin, output: $stdout | |
| loops = [] | |
| while @code_pointer < @code.length | |
| c = @code[@code_pointer] | |
| case c | |
| when bf_cmds[:dec_ptr] | |
| @pointer -= 1 | |
| when bf_cmds[:inc_ptr] | |
| @pointer += 1 | |
| when bf_cmds[:inc_val] | |
| @cells[@pointer] = @cells[@pointer].to_i + 1 | |
| when bf_cmds[:dec_val] | |
| @cells[@pointer] -= 1 if @cells[@pointer].to_i > 0 | |
| when bf_cmds[:output] | |
| output.putc @cells[@pointer].to_i.chr | |
| when bf_cmds[:input] | |
| @cells[@pointer] = "#{input.getc.to_s} ".ord | |
| when bf_cmds[:loop_begin] | |
| loops << @code_pointer | |
| @code_pointer = find_closing_bracket(bf_cmds) - 1 | |
| when bf_cmds[:loop_end] | |
| if @cells[@pointer].to_i == 0 | |
| loops.pop | |
| else | |
| @code_pointer = loops[-1] | |
| end | |
| else | |
| end | |
| @code_pointer += 1 | |
| @rounds += 1 | |
| @max = @pointer if @pointer > max | |
| end | |
| @max += 1 | |
| end | |
| protected | |
| def find_closing_bracket bf_cmds | |
| counter = 0 | |
| search = @code_pointer + 1 | |
| while search < @code.length | |
| case @code[search] | |
| when bf_cmds[:loop_begin] | |
| counter += 1 | |
| when bf_cmds[:loop_end] | |
| if counter > 0 | |
| counter -= 1 | |
| else | |
| break | |
| end | |
| end | |
| search += 1 | |
| end | |
| return search | |
| end | |
| end | |
| =begin | |
| Example: | |
| int = BrainfuckInterpreter.new | |
| # simple caeser crypt with key 1 | |
| int.code = "[-]>,[>,]<[+<]>[.>]" | |
| int.interpret! | |
| =end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment