Class: BrainLove::VM

Inherits:
Object
  • Object
show all
Defined in:
lib/brain_love/vm.rb

Constant Summary collapse

NOOP =
0
INC_DP =
1
DEC_DP =
2
INC_BYTE =
3
DEC_BYTE =
4
PUTC =
5
GETC =
6
JMPFZ =
7
JMPBNZ =
8

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(code, input, output) ⇒ VM

Returns a new instance of VM.



16
17
18
19
20
21
# File 'lib/brain_love/vm.rb', line 16

def initialize(code, input, output)
  @code, @input, @output = code, input, output
  @ip = 0
  @dp = 0
  @data = [0] * 30_000
end

Instance Attribute Details

#codeObject (readonly)

Returns the value of attribute code.



14
15
16
# File 'lib/brain_love/vm.rb', line 14

def code
  @code
end

#dataObject (readonly)

Returns the value of attribute data.



14
15
16
# File 'lib/brain_love/vm.rb', line 14

def data
  @data
end

#dpObject (readonly)

Returns the value of attribute dp.



14
15
16
# File 'lib/brain_love/vm.rb', line 14

def dp
  @dp
end

#ipObject (readonly)

Returns the value of attribute ip.



14
15
16
# File 'lib/brain_love/vm.rb', line 14

def ip
  @ip
end

Instance Method Details

#code_dumpObject



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/brain_love/vm.rb', line 23

def code_dump
  index = 0
  @code.each_byte do |b|
    print "#{index} "
    index += 1
    case b
    when NOOP
      puts "NOOP"
    when INC_DP
      puts "INC_DP"
    when DEC_DP
      puts "DEC_DP"
    when INC_BYTE
      puts "INC_BYTE"
    when DEC_BYTE
      puts "DEC_BYTE"
    when PUTC
      puts "PUTC"
    when GETC
      puts "GETC"
    when JMPFZ
      puts "JMPFZ"
      @jmp = true
    when JMPBNZ
      puts "JMPBNZ"
      @jmp = true
    else
      if @jmp
        @jmp = false
        puts " offset #{b}"
      else
        puts "UNKNOWN BYTECODE"
      end
    end
  end
end

#executeObject



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/brain_love/vm.rb', line 60

def execute
  while @ip < @code.bytesize do
    case @code[@ip].ord
    when NOOP
    when INC_DP
      @dp += 1
    when DEC_DP
      @dp -= 1
    when INC_BYTE
      @data[@dp] = 0 if @data[@dp] == 255
      @data[@dp] += 1
    when DEC_BYTE
      @data[@dp] = 256 if @data[@dp] == 0
      @data[@dp] -= 1
    when PUTC
      @output.putc(@data[@dp].chr)
    when GETC
      @data[@dp] = (@input.getc || 0).ord
    when JMPFZ
      @ip += @code[@ip + 1].ord - 1 if @data[@dp] == 0
    when JMPBNZ
      unless @data[@dp] == 0
        @ip -= @code[@ip + 1].ord
      else
        @ip += 1
      end
    end

    @ip += 1
  end
end