Class: Braingasm::Machine
- Inherits:
-
Object
- Object
- Braingasm::Machine
- Defined in:
- lib/braingasm/machine.rb
Overview
A Machine keeps the state of a running program, and exposes various operations to modify this state
Instance Attribute Summary collapse
-
#ctrl_stack ⇒ Object
Returns the value of attribute ctrl_stack.
-
#dp ⇒ Object
Returns the value of attribute dp.
-
#input ⇒ Object
Returns the value of attribute input.
-
#ip ⇒ Object
Returns the value of attribute ip.
-
#last_write ⇒ Object
Returns the value of attribute last_write.
-
#output ⇒ Object
Returns the value of attribute output.
-
#program ⇒ Object
Returns the value of attribute program.
-
#tape ⇒ Object
Returns the value of attribute tape.
-
#tape_limit ⇒ Object
Returns the value of attribute tape_limit.
Instance Method Summary collapse
- #calculate_new_dp(move) ⇒ Object
- #cell ⇒ Object
- #cell=(new_value) ⇒ Object
-
#initialize ⇒ Machine
constructor
A new instance of Machine.
- #inst_compare_cells ⇒ Object
- #inst_dec(n = 1) ⇒ Object
- #inst_divide(n = 2) ⇒ Object
- #inst_inc(n = 1) ⇒ Object
- #inst_jump(to) ⇒ Object
- #inst_jump_if_ctrl_zero(to) ⇒ Object
- #inst_jump_if_data_zero(to) ⇒ Object
- #inst_left(n = 1) ⇒ Object
- #inst_multiply(n = 2) ⇒ Object
- #inst_print(chr) ⇒ Object
- #inst_print_cell ⇒ Object
- #inst_print_cell_int ⇒ Object
- #inst_print_int(n) ⇒ Object
- #inst_print_tape ⇒ Object
- #inst_push_ctrl(x) ⇒ Object
- #inst_quit(value, code = 0) ⇒ Object
- #inst_read_byte ⇒ Object
- #inst_read_int(radix = 10) ⇒ Object
- #inst_right(n = 1) ⇒ Object
- #limit_tape(cell_number) ⇒ Object
- #pos ⇒ Object
- #print_bytes(b) ⇒ Object
- #run ⇒ Object
- #step ⇒ Object
Constructor Details
#initialize ⇒ Machine
Returns a new instance of Machine.
12 13 14 15 16 17 18 19 20 |
# 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 |
Instance Attribute Details
#ctrl_stack ⇒ Object
Returns the value of attribute ctrl_stack.
9 10 11 |
# File 'lib/braingasm/machine.rb', line 9 def ctrl_stack @ctrl_stack end |
#dp ⇒ Object
Returns the value of attribute dp.
9 10 11 |
# File 'lib/braingasm/machine.rb', line 9 def dp @dp end |
#input ⇒ Object
Returns the value of attribute input.
9 10 11 |
# File 'lib/braingasm/machine.rb', line 9 def input @input end |
#ip ⇒ Object
Returns the value of attribute ip.
9 10 11 |
# File 'lib/braingasm/machine.rb', line 9 def ip @ip end |
#last_write ⇒ Object
Returns the value of attribute last_write.
9 10 11 |
# File 'lib/braingasm/machine.rb', line 9 def last_write @last_write end |
#output ⇒ Object
Returns the value of attribute output.
9 10 11 |
# File 'lib/braingasm/machine.rb', line 9 def output @output end |
#program ⇒ Object
Returns the value of attribute program.
9 10 11 |
# File 'lib/braingasm/machine.rb', line 9 def program @program end |
#tape ⇒ Object
Returns the value of attribute tape.
9 10 11 |
# File 'lib/braingasm/machine.rb', line 9 def tape @tape end |
#tape_limit ⇒ Object
Returns the value of attribute tape_limit.
9 10 11 |
# File 'lib/braingasm/machine.rb', line 9 def tape_limit @tape_limit end |
Instance Method Details
#calculate_new_dp(move) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 |
# 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 ⇒ Object
33 34 35 |
# File 'lib/braingasm/machine.rb', line 33 def cell @tape[@dp] end |
#cell=(new_value) ⇒ Object
37 38 39 40 |
# File 'lib/braingasm/machine.rb', line 37 def cell=(new_value) @tape[@dp] = new_value trigger_cell_updated end |
#inst_compare_cells ⇒ Object
164 165 166 167 |
# 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) ⇒ Object
92 93 94 |
# File 'lib/braingasm/machine.rb', line 92 def inst_dec(n=1) self.cell -= n end |
#inst_divide(n = 2) ⇒ Object
100 101 102 |
# File 'lib/braingasm/machine.rb', line 100 def inst_divide(n=2) self.cell /= n end |
#inst_inc(n = 1) ⇒ Object
88 89 90 |
# File 'lib/braingasm/machine.rb', line 88 def inst_inc(n=1) self.cell += n end |
#inst_jump(to) ⇒ Object
104 105 106 |
# File 'lib/braingasm/machine.rb', line 104 def inst_jump(to) raise JumpSignal.new(to) end |
#inst_jump_if_ctrl_zero(to) ⇒ Object
112 113 114 115 116 |
# 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) ⇒ Object
108 109 110 |
# 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) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 |
# 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) ⇒ Object
96 97 98 |
# File 'lib/braingasm/machine.rb', line 96 def inst_multiply(n=2) self.cell *= n end |
#inst_print(chr) ⇒ Object
132 133 134 135 136 137 138 139 |
# 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 ⇒ Object
141 142 143 |
# File 'lib/braingasm/machine.rb', line 141 def inst_print_cell print_bytes(cell) end |
#inst_print_cell_int ⇒ Object
149 150 151 |
# File 'lib/braingasm/machine.rb', line 149 def inst_print_cell_int @output.print cell end |
#inst_print_int(n) ⇒ Object
145 146 147 |
# File 'lib/braingasm/machine.rb', line 145 def inst_print_int(n) @output.print n end |
#inst_print_tape ⇒ Object
84 85 86 |
# File 'lib/braingasm/machine.rb', line 84 def inst_print_tape p @tape end |
#inst_push_ctrl(x) ⇒ Object
118 119 120 |
# File 'lib/braingasm/machine.rb', line 118 def inst_push_ctrl(x) ctrl_stack << x end |
#inst_quit(value, code = 0) ⇒ Object
169 170 171 |
# File 'lib/braingasm/machine.rb', line 169 def inst_quit(value, code=0) raise ExitSignal.new(code) unless value == 0 end |
#inst_read_byte ⇒ Object
153 154 155 |
# 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) ⇒ Object
157 158 159 160 161 162 |
# 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) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 |
# 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) ⇒ Object
173 174 175 |
# File 'lib/braingasm/machine.rb', line 173 def limit_tape(cell_number) @tape_limit = cell_number end |
#pos ⇒ Object
42 43 44 |
# File 'lib/braingasm/machine.rb', line 42 def pos @dp - @data_offset end |
#print_bytes(b) ⇒ Object
122 123 124 125 126 127 128 129 130 |
# 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 ⇒ Object
22 23 24 |
# File 'lib/braingasm/machine.rb', line 22 def run step while @ip < @program.size end |
#step ⇒ Object
26 27 28 29 30 31 |
# File 'lib/braingasm/machine.rb', line 26 def step @program[@ip].call(self) @ip += 1 rescue JumpSignal => jump @ip = jump.to end |