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
# File lib/braingasm/machine.rb, line 122 def print_bytes(b) d,m = b.divmod(256) if d > 0 print_bytes(d) end @output.putc(m) end
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