class Braingasm::Machine

A Machine keeps the state of a running program, and exposes various operations to modify this state

Attributes

ctrl_stack[RW]
dp[RW]
input[RW]
ip[RW]
last_write[RW]
output[RW]
program[RW]
tape[RW]
tape_limit[RW]

Public Class Methods

new() click to toggle source
# File lib/braingasm/machine.rb, line 12
def initialize
  @tape = Array.new(10) { 0 }
  @dp = 0           # data pointer
  @data_offset = 0
  @ip = 0           # instruction pointer

  @ctrl_stack = []
  @last_write = 0
end

Public Instance Methods

calculate_new_dp(move) click to toggle source
# File lib/braingasm/machine.rb, line 46
def calculate_new_dp(move)
  if @tape_limit
    if @tape_limit >= 0
      (@dp + move) % @tape_limit
    else
      (@dp + move) % -@tape_limit
    end
  else
    @dp + move
  end
end
cell() click to toggle source
# File lib/braingasm/machine.rb, line 33
def cell
  @tape[@dp]
end
cell=(new_value) click to toggle source
# File lib/braingasm/machine.rb, line 37
def cell=(new_value)
  @tape[@dp] = new_value
  trigger_cell_updated
end
inst_compare_cells() click to toggle source
# File lib/braingasm/machine.rb, line 164
def inst_compare_cells
  operand = @dp == 0 ? 0 : @tape[@dp-1]
  @last_write = @tape[@dp] - operand
end
inst_dec(n=1) click to toggle source
# File lib/braingasm/machine.rb, line 92
def inst_dec(n=1)
  self.cell -= n
end
inst_divide(n=2) click to toggle source
# File lib/braingasm/machine.rb, line 100
def inst_divide(n=2)
  self.cell /= n
end
inst_inc(n=1) click to toggle source
# File lib/braingasm/machine.rb, line 88
def inst_inc(n=1)
  self.cell += n
end
inst_jump(to) click to toggle source
# File lib/braingasm/machine.rb, line 104
def inst_jump(to)
  raise JumpSignal.new(to)
end
inst_jump_if_ctrl_zero(to) click to toggle source
# File lib/braingasm/machine.rb, line 112
def inst_jump_if_ctrl_zero(to)
  ctrl = ctrl_stack.pop
  raise JumpSignal.new(to) if ctrl == 0
  ctrl_stack << ctrl - 1
end
inst_jump_if_data_zero(to) click to toggle source
# File lib/braingasm/machine.rb, line 108
def inst_jump_if_data_zero(to)
  raise JumpSignal.new(to) if cell == 0
end
inst_left(n=1) click to toggle source
# File lib/braingasm/machine.rb, line 70
def inst_left(n=1)
  new_dp = calculate_new_dp(-n)

  if new_dp < 0
    new_cells = -new_dp
    new_cells.times { @tape.unshift 0 }
    @data_offset += new_cells

    @dp = 0
  else
    @dp = new_dp
  end
end
inst_multiply(n=2) click to toggle source
# File lib/braingasm/machine.rb, line 96
def inst_multiply(n=2)
  self.cell *= n
end
inst_print(chr) click to toggle source
# File lib/braingasm/machine.rb, line 132
def inst_print(chr)
  case chr
  when Integer
    print_bytes(chr)
  else
    @output.print chr
  end
end
inst_print_cell() click to toggle source
# File lib/braingasm/machine.rb, line 141
def inst_print_cell
  print_bytes(cell)
end
inst_print_cell_int() click to toggle source
# File lib/braingasm/machine.rb, line 149
def inst_print_cell_int
  @output.print cell
end
inst_print_int(n) click to toggle source
# File lib/braingasm/machine.rb, line 145
def inst_print_int(n)
  @output.print n
end
inst_print_tape() click to toggle source
# File lib/braingasm/machine.rb, line 84
def inst_print_tape
  p @tape
end
inst_push_ctrl(x) click to toggle source
# File lib/braingasm/machine.rb, line 118
def inst_push_ctrl(x)
  ctrl_stack << x
end
inst_quit(value, code=0) click to toggle source
# File lib/braingasm/machine.rb, line 169
def inst_quit(value, code=0)
  raise ExitSignal.new(code) unless value == 0
end
inst_read_byte() click to toggle source
# File lib/braingasm/machine.rb, line 153
def inst_read_byte
  self.cell = @input.getbyte || Options[:eof] || @tape[@dp]
end
inst_read_int(radix=10) click to toggle source
# File lib/braingasm/machine.rb, line 157
def inst_read_int(radix=10)
  return unless @input.gets =~ /\d+/

  @input.ungetc($')
  self.cell = $&.to_i(radix)
end
inst_right(n=1) click to toggle source
# File lib/braingasm/machine.rb, line 58
def inst_right(n=1)
  new_dp = calculate_new_dp(n)
  no_cells = @tape.length

  if new_dp >= no_cells
    grow = new_dp * 3 / 2
    @tape.fill(0, no_cells..grow)
  end

  @dp = new_dp
end
limit_tape(cell_number) click to toggle source
# File lib/braingasm/machine.rb, line 173
def limit_tape(cell_number)
  @tape_limit = cell_number
end
pos() click to toggle source
# File lib/braingasm/machine.rb, line 42
def pos
  @dp - @data_offset
end
print_bytes(b) click to toggle source
run() click to toggle source
# File lib/braingasm/machine.rb, line 22
def run
  step while @ip < @program.size
end
step() click to toggle source
# File lib/braingasm/machine.rb, line 26
def step
  @program[@ip].call(self)
  @ip += 1
rescue JumpSignal => jump
  @ip = jump.to
end

Private Instance Methods

trigger_cell_updated() click to toggle source
# File lib/braingasm/machine.rb, line 179
def trigger_cell_updated
  @tape[@dp] %= Options[:cell_limit] if Options[:wrap_cells]
  @last_write = @tape[@dp]
end