Class: BfRb::Interpreter
- Inherits:
-
Object
- Object
- BfRb::Interpreter
- Defined in:
- lib/bfrb/interpreter.rb
Overview
interprets brainfuck code
Instance Attribute Summary collapse
-
#input_stream ⇒ Object
Returns the value of attribute input_stream.
-
#memory_counter ⇒ Object
readonly
Returns the value of attribute memory_counter.
-
#output_stream ⇒ Object
Returns the value of attribute output_stream.
-
#program_counter ⇒ Object
readonly
Returns the value of attribute program_counter.
Instance Method Summary collapse
-
#check_for_matching_braces ⇒ Object
checks the code to be run to make sure all braces match.
-
#current_memory ⇒ Object
returns the value in the current memory cell.
-
#evaluate_code ⇒ Object
evaluate each instruction in the current code.
-
#evaluate_instruction(instruction) ⇒ Object
evaluate an individual instruction.
-
#initialize ⇒ Interpreter
constructor
initialize the interpreter.
-
#initialize_environment ⇒ Object
cleans the memory and initializes member variables.
-
#run(code) ⇒ Object
run a given piece of code.
Constructor Details
#initialize ⇒ Interpreter
initialize the interpreter
11 12 13 14 15 16 |
# File 'lib/bfrb/interpreter.rb', line 11 def initialize @memory = Memory.new initialize_environment @input_stream = $stdin @output_stream = $stdout end |
Instance Attribute Details
#input_stream ⇒ Object
Returns the value of attribute input_stream.
8 9 10 |
# File 'lib/bfrb/interpreter.rb', line 8 def input_stream @input_stream end |
#memory_counter ⇒ Object (readonly)
Returns the value of attribute memory_counter.
7 8 9 |
# File 'lib/bfrb/interpreter.rb', line 7 def memory_counter @memory_counter end |
#output_stream ⇒ Object
Returns the value of attribute output_stream.
8 9 10 |
# File 'lib/bfrb/interpreter.rb', line 8 def output_stream @output_stream end |
#program_counter ⇒ Object (readonly)
Returns the value of attribute program_counter.
7 8 9 |
# File 'lib/bfrb/interpreter.rb', line 7 def program_counter @program_counter end |
Instance Method Details
#check_for_matching_braces ⇒ Object
checks the code to be run to make sure all braces match
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/bfrb/interpreter.rb', line 38 def check_for_matching_braces brace_counter = 0 @code.each_char do |char| if char == "[" brace_counter += 1 elsif char == "]" brace_counter -= 1 if brace_counter < 0 @output_stream.puts "Unmatched ]" return false end end end if brace_counter > 0 @output_stream.puts "Unmatched [" return false end return true end |
#current_memory ⇒ Object
returns the value in the current memory cell
123 124 125 |
# File 'lib/bfrb/interpreter.rb', line 123 def current_memory return @memory.get(@memory_counter) end |
#evaluate_code ⇒ Object
evaluate each instruction in the current code
59 60 61 62 63 |
# File 'lib/bfrb/interpreter.rb', line 59 def evaluate_code while ((0 <= @program_counter) and (@program_counter < @code.length)) evaluate_instruction(@code[@program_counter]) end end |
#evaluate_instruction(instruction) ⇒ Object
evaluate an individual instruction
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/bfrb/interpreter.rb', line 66 def evaluate_instruction(instruction) case instruction # shift right in memory when ">" @memory_counter += 1 # shift left in memory, unless we're at the beginning when "<" if @memory_counter > 1 @memory_counter -= 1 else @memory_counter = 0 end # increment value in memory when "+" @memory.set(@memory_counter, current_memory + 1) # decrement value in memory when "-" unless current_memory == 0 @memory.set(@memory_counter, current_memory - 1) end # print value in memory when "." @output_stream.print current_memory.chr # input a character into memory when "," @output_stream.puts input = @input_stream.gets.getbyte(0) if input == 24 throw :quit end @memory.set(@memory_counter, input) # jump to the closing bracket if memory is 0 when "[" if current_memory != 0 @loop_stack.push @program_counter else bracket_counter = 1 while ((bracket_counter != 0) and (@program_counter < @code.length - 1)) @program_counter += 1 if @code[@program_counter] == "[" bracket_counter += 1 elsif @code[@program_counter] == "]" bracket_counter -= 1 end end end # return to the opening bracket if memory is not zero when "]" matching_bracket = @loop_stack.pop if current_memory != 0 @program_counter = matching_bracket - 1 end end @program_counter += 1 end |
#initialize_environment ⇒ Object
cleans the memory and initializes member variables
19 20 21 22 23 24 25 |
# File 'lib/bfrb/interpreter.rb', line 19 def initialize_environment @memory.clear @program_counter = 0 @memory_counter = 0 @code = "" @loop_stack = [] end |
#run(code) ⇒ Object
run a given piece of code
28 29 30 31 32 33 34 35 |
# File 'lib/bfrb/interpreter.rb', line 28 def run(code) @code += code.delete "^[]<>.,+-" if check_for_matching_braces catch :quit do evaluate_code end end end |