Class: Yarbf::BfInterpreter

Inherits:
Object
  • Object
show all
Includes:
BooleanJudge
Defined in:
lib/yarbf.rb

Overview

BfInterpreter

BfInterpreter is the main class of module #Yarbf.

Options

Options to interpreter can be specified via passing a #Hash object to the constructor or just calling attribute writers. Supported options are:

  • debug

    Debug mode switch. Setting this options to true will print out each Brainfuck instruction when interpreting. Default is false.

  • wrap_around

    Wrap around switch. Setting this options to true will ignore cell value overflow or underflow. Default is false.

  • cell_size

    Size of each cell in bit. Default is 8.

  • input_mode

    Input mode. Available options are :buffered and :raw. In buffered mode, the characters you type will be echoed on screen and will be buffered until you type an enter. In raw mode, there’s no echoing nor buffering. Default is :buffered.

Examples

Following is a brief example.

require 'yarbf'

options = {
  :debug => true,
  :wrap_around => true,
  :cell_size => 16,
  :input_mode => :buffered
}
interpreter = Yarbf::BfInterpreter.new(options)
interpreter.run('/path/to/Brainfuck/source')

Defined Under Namespace

Classes: BfCell, BfProgramUnit

Instance Method Summary collapse

Methods included from BooleanJudge

#is_boolean?, #not_boolean?

Constructor Details

#initialize(options) ⇒ BfInterpreter

Initialize the instance.

options

A Hash containing options to the interpreter.



82
83
84
85
86
87
# File 'lib/yarbf.rb', line 82

def initialize(options)
  unless options.is_a?(Hash) && OPTIONS.all? { |s| options.has_key? s }
    fail 'Missing required options!'
  end
  @options = options.select { |k| OPTIONS.include? k }
end

Instance Method Details

#cell_size=(cell_size) ⇒ Object

Sets the size of each tape cell.

cell_size

An integer.



147
148
149
150
151
152
# File 'lib/yarbf.rb', line 147

def cell_size=(cell_size)
  unless cell_size.is_a? Integer
    fail "'cell_size' should be an integer but is a #{cell_size.class}!"
  end
  @options[:cell_size] = cell_size
end

#cell_size?Boolean

Returns the size of each tape cell.

Returns:

  • (Boolean)


138
139
140
# File 'lib/yarbf.rb', line 138

def cell_size?
  @options[:cell_size]
end

#debug=(debug) ⇒ Object

Sets the interpreter to debug mode

debug

A boolean value.



109
110
111
112
113
114
# File 'lib/yarbf.rb', line 109

def debug=(debug)
  not_boolean?(debug) do
    fail "'debug' switch should be a boolean but is a #{debug.class}!"
  end
  @options[:debug] = debug
end

#debug?Boolean

Returns whether the interpreter is in debug mode.

Returns:

  • (Boolean)


100
101
102
# File 'lib/yarbf.rb', line 100

def debug?
  @options[:debug]
end

#input_mode=(input_mode) ⇒ Object

Sets the input mode.

input_mode

A symbol of :buffered or :raw.



166
167
168
169
170
171
# File 'lib/yarbf.rb', line 166

def input_mode=(input_mode)
  unless INPUT_MODE_OPTIONS.include? input_mode
    fail 'Invalid value of input mode!'
  end
  @options[:input_mode] = input_mode
end

#input_mode?Boolean

Returns the current input mode.

Returns:

  • (Boolean)


157
158
159
# File 'lib/yarbf.rb', line 157

def input_mode?
  @options[:input_mode]
end

#inspectObject Also known as: to_s

Returns a human-readable string describing the interpreter.



92
93
94
# File 'lib/yarbf.rb', line 92

def inspect
  @options.inspect
end

#run(src) ⇒ Object

Interpret a Brainfuck source file.

src

Path of the source.



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/yarbf.rb', line 178

def run(src)
  units = []

  # construct units
  begin
    File.open(src) { |file| units = construct_program_units(file) }
  rescue SystemCallError => e
    fail e.to_s
  end

  # match brackets
  match_brackets(units)

  # do interpret
  tape = Array.new
  position = 0
  unit = units[0]
  until unit.nil?
    tape[position] = BfCell.new(position, cell_size?) if tape[position].nil?
    $stderr.printf('%s', unit.instruction) if debug?
    unit, position = deal_unit(unit, tape, position)
  end
end

#wrap_around=(wrap_around) ⇒ Object

Sets whether the interpreter should accept wrap around.

wrap_around

A boolean value.



128
129
130
131
132
133
# File 'lib/yarbf.rb', line 128

def wrap_around=(wrap_around)
  not_boolean?(wrap_around) do
    fail "'wrap_around' should be a boolean but is a #{wrap_around.class}!"
  end
  @options[:wrap_around] = wrap_around
end

#wrap_around?Boolean

Returns whether the interpreter accepts wrap around.

Returns:

  • (Boolean)


119
120
121
# File 'lib/yarbf.rb', line 119

def wrap_around?
  @options[:wrap_around]
end