Class: BrainFuck
- Inherits:
-
Object
- Object
- BrainFuck
- Defined in:
- lib/brain_fuck.rb
Constant Summary collapse
- DEFAULT_MEMORY_SIZE =
30_000
- DEFAULT_EXEC_LIMIT =
Stop badly constructed scripts going forever
1_000_000
- OPS =
{ '+' => :increment, '-' => :decrement, '>' => :move_pointer_left, '<' => :move_pointer_right, ',' => :read_in, '.' => :print_out, '[' => :loop_start, ']' => :loop_end }
- DIALECTS =
{ :ook => { 'Ook. Ook.' => '+', 'Ook! Ook!' => '-', 'Ook. Ook?' => '>', 'Ook? Ook.' => '<', 'Ook! Ook?' => '[', 'Ook? Ook!' => ']', 'Ook! Ook.' => '.', 'Ook. Ook!' => ',' }, :spoon => { 1 => '+', 0 => { 0 => { 0 => '-', 1 => { 0 => { 0 => '[', 1 => { 0 => '.', 1 => { 0 => ',' } } }, 1 => ']' } }, 1 => { 0 => '>', 1 => '<' } } } }
Instance Attribute Summary collapse
-
#data_pointer ⇒ Object
Returns the value of attribute data_pointer.
-
#instruction_pointer ⇒ Object
Returns the value of attribute instruction_pointer.
-
#memory ⇒ Object
Returns the value of attribute memory.
-
#pointer_stack ⇒ Object
Returns the value of attribute pointer_stack.
Class Method Summary collapse
Instance Method Summary collapse
- #decrement ⇒ Object
- #dump ⇒ Object
- #ended? ⇒ Boolean
- #execute(op) ⇒ Object
- #increment ⇒ Object
-
#initialize(program_input_stream, options = {}) ⇒ BrainFuck
constructor
A new instance of BrainFuck.
- #loop_end ⇒ Object
- #loop_start ⇒ Object
- #move_pointer_left ⇒ Object
- #move_pointer_right ⇒ Object
- #next_instruction ⇒ Object
- #print_out ⇒ Object
- #read_in ⇒ Object
- #run ⇒ Object
Constructor Details
#initialize(program_input_stream, options = {}) ⇒ BrainFuck
Returns a new instance of BrainFuck.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/brain_fuck.rb', line 60 def initialize(program_input_stream, ={}) @debug = [:debug] || false @exec_limit = [:execution_limit] || DEFAULT_EXEC_LIMIT @execution_count = 0 @instruction_pointer = -1 @memory_size = [:memory_size] || DEFAULT_MEMORY_SIZE @memory = Array.new(@memory_size){ 0 } @data_pointer = 0 @pointer_stack = [] @input_stream = [:input_stream] || STDIN @output_stream = [:output_stream] || STDOUT @program = get_program(program_input_stream) @program_end = @program.size end |
Instance Attribute Details
#data_pointer ⇒ Object
Returns the value of attribute data_pointer.
55 56 57 |
# File 'lib/brain_fuck.rb', line 55 def data_pointer @data_pointer end |
#instruction_pointer ⇒ Object
Returns the value of attribute instruction_pointer.
55 56 57 |
# File 'lib/brain_fuck.rb', line 55 def instruction_pointer @instruction_pointer end |
#memory ⇒ Object
Returns the value of attribute memory.
55 56 57 |
# File 'lib/brain_fuck.rb', line 55 def memory @memory end |
#pointer_stack ⇒ Object
Returns the value of attribute pointer_stack.
55 56 57 |
# File 'lib/brain_fuck.rb', line 55 def pointer_stack @pointer_stack end |
Class Method Details
.bf_to_ook(bf) ⇒ Object
147 148 149 150 151 152 153 154 155 156 |
# File 'lib/brain_fuck.rb', line 147 def self.bf_to_ook(bf) ook = '' ook_bf = DIALECTS[:ook].invert bf.each_char do |op| next unless op.match(/[\>\<\+\-\.,\[\]]/) ook << ook_bf[op] ook << ' ' end ook end |
.ook_to_bf(ook) ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/brain_fuck.rb', line 135 def self.ook_to_bf(ook) bf = '' ook.scan(/(Ook[\.\?\!])\s*(Ook[\.\?\!])/) do |m| command = "#{m[0]} #{m[1]}" unless DIALECTS[:ook].include?(command) raise "Got confused, thought it was Ook!" end bf << DIALECTS[:ook][command] end bf end |
.spoon_to_bf(spoon) ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/brain_fuck.rb', line 158 def self.spoon_to_bf(spoon) src = spoon.gsub(/[^01]/, '') bf = '' current = DIALECTS[:spoon] spoon.each_char do |i| current = current[i.to_i] unless current.is_a?(Hash) bf << current current = DIALECTS[:spoon] end end bf end |
Instance Method Details
#decrement ⇒ Object
89 90 91 |
# File 'lib/brain_fuck.rb', line 89 def decrement @memory[@data_pointer] -= 1 end |
#dump ⇒ Object
192 193 194 195 196 197 198 199 |
# File 'lib/brain_fuck.rb', line 192 def dump puts puts "instruction_pointer = #{@instruction_pointer}" puts "data_pointer = #{@data_pointer}" puts "memory@data_pointer = #{@memory[@data_pointer]}" puts "pointer_stack = #{@pointer_stack.inspect}" puts end |
#ended? ⇒ Boolean
187 188 189 190 |
# File 'lib/brain_fuck.rb', line 187 def ended? (@instruction_pointer >= @program_end or @execution_count >= @exec_limit) end |
#execute(op) ⇒ Object
78 79 80 81 82 83 |
# File 'lib/brain_fuck.rb', line 78 def execute(op) return unless OPS.has_key?(op) puts op if @debug send(OPS[op]) @execution_count += 1 end |
#increment ⇒ Object
85 86 87 |
# File 'lib/brain_fuck.rb', line 85 def increment @memory[@data_pointer] += 1 end |
#loop_end ⇒ Object
124 125 126 127 128 129 130 131 132 133 |
# File 'lib/brain_fuck.rb', line 124 def loop_end if @pointer_stack.empty? raise "Bracket mismatch" end if @memory[@data_pointer] == 0 @pointer_stack.pop else @instruction_pointer = @pointer_stack.pop end end |
#loop_start ⇒ Object
116 117 118 119 120 121 122 |
# File 'lib/brain_fuck.rb', line 116 def loop_start if @memory[@data_pointer] > 0 @pointer_stack.push(@instruction_pointer-1) else @instruction_pointer = matching_brace_position(@instruction_pointer) end end |
#move_pointer_left ⇒ Object
101 102 103 104 105 106 |
# File 'lib/brain_fuck.rb', line 101 def move_pointer_left @data_pointer += 1 if @data_pointer == @memory_size @data_pointer = 0 end end |
#move_pointer_right ⇒ Object
108 109 110 111 112 113 114 |
# File 'lib/brain_fuck.rb', line 108 def move_pointer_right if @data_pointer > 0 @data_pointer -= 1 else @data_pointer = @memory_size - 1 end end |
#next_instruction ⇒ Object
182 183 184 185 |
# File 'lib/brain_fuck.rb', line 182 def next_instruction @instruction_pointer += 1 @program[@instruction_pointer] end |
#print_out ⇒ Object
97 98 99 |
# File 'lib/brain_fuck.rb', line 97 def print_out @output_stream.putc @memory[@data_pointer] end |
#read_in ⇒ Object
93 94 95 |
# File 'lib/brain_fuck.rb', line 93 def read_in @memory[@data_pointer] = @input_stream.getc.ord end |
#run ⇒ Object
172 173 174 175 176 177 178 179 180 |
# File 'lib/brain_fuck.rb', line 172 def run while not ended? do dump if @debug op = next_instruction puts "op = #{op}" if @debug execute(op) dump if @debug end end |