Class: Braingasm::Machine

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

Constructor Details

#initializeMachine

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_stackObject

Returns the value of attribute ctrl_stack.



9
10
11
# File 'lib/braingasm/machine.rb', line 9

def ctrl_stack
  @ctrl_stack
end

#dpObject

Returns the value of attribute dp.



9
10
11
# File 'lib/braingasm/machine.rb', line 9

def dp
  @dp
end

#inputObject

Returns the value of attribute input.



9
10
11
# File 'lib/braingasm/machine.rb', line 9

def input
  @input
end

#ipObject

Returns the value of attribute ip.



9
10
11
# File 'lib/braingasm/machine.rb', line 9

def ip
  @ip
end

#last_writeObject

Returns the value of attribute last_write.



9
10
11
# File 'lib/braingasm/machine.rb', line 9

def last_write
  @last_write
end

#outputObject

Returns the value of attribute output.



9
10
11
# File 'lib/braingasm/machine.rb', line 9

def output
  @output
end

#programObject

Returns the value of attribute program.



9
10
11
# File 'lib/braingasm/machine.rb', line 9

def program
  @program
end

#tapeObject

Returns the value of attribute tape.



9
10
11
# File 'lib/braingasm/machine.rb', line 9

def tape
  @tape
end

#tape_limitObject

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

#cellObject



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_cellsObject



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

Raises:



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

Raises:



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

Raises:



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_cellObject



141
142
143
# File 'lib/braingasm/machine.rb', line 141

def inst_print_cell
  print_bytes(cell)
end

#inst_print_cell_intObject



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_tapeObject



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

Raises:



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_byteObject



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

#posObject



42
43
44
# File 'lib/braingasm/machine.rb', line 42

def pos
  @dp - @data_offset
end


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

#runObject



22
23
24
# File 'lib/braingasm/machine.rb', line 22

def run
  step while @ip < @program.size
end

#stepObject



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