class Brainclusterfuck::Interpreter

Attributes

cycles[R]
finished[R]
instruction_pointer[R]
memory[R]
terminal[R]

Public Class Methods

new(opts) click to toggle source
# File lib/brainclusterfuck/interpreter.rb, line 6
def initialize(opts)
  @terminal = opts.fetch(:terminal)
  @memory = opts.fetch(:memory)
  @bytecode = opts.fetch(:bytecode)

  @cycles = 0
  @instruction_pointer = 0
end

Public Instance Methods

finished?() click to toggle source
# File lib/brainclusterfuck/interpreter.rb, line 33
def finished?
  !!@finished
end
step(cycles_allowed = 1) click to toggle source
# File lib/brainclusterfuck/interpreter.rb, line 15
def step(cycles_allowed = 1)
  raise ArgumentError, "cycles_allowed must be positive" unless cycles_allowed > 0

  while cycles_allowed > 0
    opcode = @bytecode[@instruction_pointer]

    unless opcode
      @finished = true
      return
    end

    cycles_allowed -= opcode.cycles
    @cycles += opcode.cycles

    execute(opcode)
  end
end

Private Instance Methods

execute(opcode) click to toggle source
# File lib/brainclusterfuck/interpreter.rb, line 38
def execute(opcode)
  @op_to_method ||= {
    Opcodes::ModifyValue => :modify_value,
    Opcodes::ModifyPointer => :modify_pointer,
    Opcodes::LoopStart => :loop_start,
    Opcodes::LoopEnd => :loop_end,
    Opcodes::Print => :print
  }

  method = @op_to_method[opcode.class]
  raise ArgumentError, "Don't know how to handle #{opcode}" if method.nil?
  __send__(method, opcode)
  @finished = @instruction_pointer >= @bytecode.size
end
loop_end(opcode) click to toggle source
# File lib/brainclusterfuck/interpreter.rb, line 76
def loop_end(opcode)
  if @memory.current_value.zero?
    @instruction_pointer += 1
  else
    @instruction_pointer -= opcode.num_operations
  end
end
loop_start(opcode) click to toggle source
# File lib/brainclusterfuck/interpreter.rb, line 68
def loop_start(opcode)
  if @memory.current_value.zero?
    @instruction_pointer += (opcode.num_operations + 2)
  else
    @instruction_pointer += 1
  end
end
modify_pointer(opcode) click to toggle source
# File lib/brainclusterfuck/interpreter.rb, line 58
def modify_pointer(opcode)
  @memory.modify_pointer(opcode.modify_by)
  @instruction_pointer += 1
end
modify_value(opcode) click to toggle source
# File lib/brainclusterfuck/interpreter.rb, line 53
def modify_value(opcode)
  @memory.modify_value(opcode.modify_by)
  @instruction_pointer += 1
end
print(_opcode) click to toggle source