class Brainfsck::VM

Constants

DEBUGGING
MEM_SIZE

Attributes

call_stack[R]
dp[R]
ff[R]
ip[R]
mem[R]
program[R]

Public Class Methods

new(program) click to toggle source
# File lib/brainfsck/vm.rb, line 8
def initialize(program)
  @dp = 0
  @ip = 0
  @mem = Array.new(MEM_SIZE, 0)
  @call_stack = []
  @program = program
  @ff = 0
end

Public Instance Methods

run() click to toggle source
# File lib/brainfsck/vm.rb, line 17
def run
  while ip < program.length
    run_instruction(program[ip])
    @ip += 1
  end
end

Private Instance Methods

cls_while() click to toggle source
# File lib/brainfsck/vm.rb, line 63
def cls_while
  -> do
    if ff.zero?
      @ip = call_stack.last - 1
    else
      @ff -= 1
      @call_stack.pop
    end
  end
end
debugging?() click to toggle source
# File lib/brainfsck/vm.rb, line 47
def debugging?
  DEBUGGING
end
dec_byte() click to toggle source
# File lib/brainfsck/vm.rb, line 98
def dec_byte
  -> { @mem[dp] -= 1 }
end
dec_dp() click to toggle source
# File lib/brainfsck/vm.rb, line 90
def dec_dp
  -> { @dp = [@dp - 1, 0].max }
end
inc_byte() click to toggle source
# File lib/brainfsck/vm.rb, line 94
def inc_byte
  -> { @mem[dp] += 1 }
end
inc_dp() click to toggle source
# File lib/brainfsck/vm.rb, line 86
def inc_dp
  -> { @dp = [@dp + 1, MEM_SIZE - 1].min }
end
noop() click to toggle source

Simple VM OPS - intentionally poorly named

# File lib/brainfsck/vm.rb, line 82
def noop
  -> {  }
end
noop_with_debug() click to toggle source
# File lib/brainfsck/vm.rb, line 74
def noop_with_debug
  puts "noop-ing instruction" if debugging?

  noop.call
end
opn_while() click to toggle source

Complex VM OPS - intentionally poorly named

# File lib/brainfsck/vm.rb, line 53
def opn_while
  -> do
    if mem[dp].zero?
      @ff += 1
    elsif @call_stack.last != ip
      @call_stack.push(ip)
    end
  end
end
p_buf() click to toggle source
# File lib/brainfsck/vm.rb, line 102
def p_buf
  -> { puts @mem[0..dp] }
end
print_program_data() click to toggle source
run_instruction(instruction) click to toggle source
# File lib/brainfsck/vm.rb, line 28
def run_instruction(instruction)
  with_debug do
    return noop_with_debug if ff > 0 && instruction != "]"

    y_lambda = {
      ">" => inc_dp,
      "<" => dec_dp,
      "+" => inc_byte,
      "-" => dec_byte,
      "." => p_buf,
      "," => rw_byte,
      "[" => opn_while,
      "]" => cls_while,
    }[instruction] || noop

    y_lambda.call
  end
end
rw_byte() click to toggle source
# File lib/brainfsck/vm.rb, line 106
def rw_byte
  -> { @mem[dp] = STDIN.getch }
end
with_debug() { || ... } click to toggle source

Debug only

# File lib/brainfsck/vm.rb, line 112
def with_debug
  print_program_data if debugging?

  yield

  if debugging?
    separator = "=" * (program.length + 9)
    puts "#{separator}\n"
  end
end