|
@@ -13,13 +13,11 @@ type VirtualMachine struct {
|
13
|
13
|
|
14
|
14
|
// NewVirtualMachine creates a new IntCode virtual machine, initialised
|
15
|
15
|
// to the given slice of memory.
|
16
|
|
-func NewVirtualMachine(memory []int) *VirtualMachine {
|
17
|
|
- return &VirtualMachine{
|
|
16
|
+func NewVirtualMachine(memory []int, hasIO bool) *VirtualMachine {
|
|
17
|
+ vm := &VirtualMachine{
|
18
|
18
|
ip: 0,
|
19
|
19
|
Memory: memory,
|
20
|
20
|
Halted: false,
|
21
|
|
- Input: make(chan int, 1),
|
22
|
|
- Output: make(chan int, 1),
|
23
|
21
|
opcodes: [100]interface{}{
|
24
|
22
|
1: AddOpcode,
|
25
|
23
|
2: MulOpcode,
|
|
@@ -32,6 +30,13 @@ func NewVirtualMachine(memory []int) *VirtualMachine {
|
32
|
30
|
99: HaltOpcode,
|
33
|
31
|
},
|
34
|
32
|
}
|
|
33
|
+
|
|
34
|
+ if hasIO {
|
|
35
|
+ vm.Input = make(chan int, 1)
|
|
36
|
+ vm.Output = make(chan int, 1)
|
|
37
|
+ }
|
|
38
|
+
|
|
39
|
+ return vm
|
35
|
40
|
}
|
36
|
41
|
|
37
|
42
|
func (vm *VirtualMachine) arg(pos int) int {
|
|
@@ -60,8 +65,10 @@ func (vm *VirtualMachine) Run() {
|
60
|
65
|
|
61
|
66
|
vm.opcodes[opcode].(OpcodeFunc)(vm)
|
62
|
67
|
}
|
63
|
|
- close(vm.Input)
|
64
|
|
- close(vm.Output)
|
|
68
|
+ if vm.Input != nil {
|
|
69
|
+ close(vm.Input)
|
|
70
|
+ close(vm.Output)
|
|
71
|
+ }
|
65
|
72
|
}
|
66
|
73
|
|
67
|
74
|
// Reset resets the memory to the given slice, and all other state back to its original value.
|
|
@@ -69,6 +76,8 @@ func (vm *VirtualMachine) Reset(memory []int) {
|
69
|
76
|
copy(vm.Memory, memory)
|
70
|
77
|
vm.ip = 0
|
71
|
78
|
vm.Halted = false
|
72
|
|
- vm.Input = make(chan int, 1)
|
73
|
|
- vm.Output = make(chan int, 1)
|
|
79
|
+ if vm.Input != nil {
|
|
80
|
+ vm.Input = make(chan int, 1)
|
|
81
|
+ vm.Output = make(chan int, 1)
|
|
82
|
+ }
|
74
|
83
|
}
|