-
Notifications
You must be signed in to change notification settings - Fork 17
/
device-instructions.js
149 lines (122 loc) · 4.89 KB
/
device-instructions.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
59
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
class DeviceInstructions {
constructor(program, starting_registers = [0, 0, 0, 0, 0, 0]) {
// Clone the arrays we pass in
this.program = JSON.parse(JSON.stringify(program));
this.registers = JSON.parse(JSON.stringify(starting_registers));
this.input_pointer;
this.instruction;
}
setInputPointer(val) {
this.input_pointer = val;
}
printRegisters() {
console.log(this.registers);
}
run(print_log = false) {
this.instruction = this.registers[this.input_pointer];
let line = this.program[this.instruction];
let log;
if (line) {
let [opcode, a, b, c] = line;
if (print_log) {
log = `ip=${this.instruction} [${this.registers.join(', ')}] ${opcode} ${a} ${b} ${c} `;
}
// Run the opcode
this[opcode](a, b, c);
if (print_log) {
log += `[${this.registers.join(', ')}]`;
console.log(log);
}
// Increment out input pointer
this.registers[this.input_pointer]++;
return true;
} else {
// If we have no line, the program has halted
return false;
}
}
/**
* Opcodes
*/
// Add Register - stores into register C the result of adding register A and register B.
addr(a, b, c) {
this.registers[c] = this.registers[a] + this.registers[b];
return this.registers;
}
// Add Immediate - stores into register C the result of adding register A and value B.
addi(a, b, c) {
this.registers[c] = this.registers[a] + b;
return this.registers;
}
// Multiply Register - stores into register C the result of multiplying register A and register B.
mulr(a, b, c) {
this.registers[c] = this.registers[a] * this.registers[b];
return this.registers;
}
// Multiply Immediate - stores into register C the result of multiplying register A and value B.
muli(a, b, c) {
this.registers[c] = this.registers[a] * b;
return this.registers;
}
// Bitwise AND Register - stores into register C the result of the bitwise AND of register A and register B.
banr(a, b, c) {
this.registers[c] = this.registers[a] & this.registers[b];
return this.registers;
}
// Bitwise AND Immediate - stores into register C the result of the bitwise AND of register A and value B.
bani(a, b, c) {
this.registers[c] = this.registers[a] & b;
return this.registers;
}
// Bitwise OR Register - stores into register C the result of the bitwise OR of register A and register B.
borr(a, b, c) {
this.registers[c] = this.registers[a] | this.registers[b];
return this.registers;
}
// Bitwise OR Immediate - stores into register C the result of the bitwise OR of register A and value B.
bori(a, b, c) {
this.registers[c] = this.registers[a] | b;
return this.registers;
}
// Set Register - copies the contents of register A into register C. (Input B is ignored.)
setr(a, b, c) {
this.registers[c] = this.registers[a];
return this.registers;
}
// Set Immediate - stores value A into register C. (Input B is ignored.)
seti(a, b, c) {
this.registers[c] = a;
return this.registers;
}
// Greater-than Immediate/Register - sets register C to 1 if value A is greater than register B. Otherwise, register C is set to 0.
gtir(a, b, c) {
this.registers[c] = a > this.registers[b] ? 1 : 0;
return this.registers;
}
// Greater-than Register/Immediate - sets register C to 1 if register A is greater than value B. Otherwise, register C is set to 0.
gtri(a, b, c) {
this.registers[c] = this.registers[a] > b ? 1 : 0;
return this.registers;
}
// Greater-than Register/Register - sets register C to 1 if register A is greater than register B. Otherwise, register C is set to 0.
gtrr(a, b, c) {
this.registers[c] = this.registers[a] > this.registers[b] ? 1 : 0;
return this.registers;
}
// Equal Immediate/Register - sets register C to 1 if value A is equal to register B. Otherwise, register C is set to 0.
eqir(a, b, c) {
this.registers[c] = a === this.registers[b] ? 1 : 0;
return this.registers;
}
// Equal Register/Immediate - sets register C to 1 if register A is equal to value B. Otherwise, register C is set to 0.
eqri(a, b, c) {
this.registers[c] = this.registers[a] === b ? 1 : 0;
return this.registers;
}
// Equal Register/Register - sets register C to 1 if register A is equal to register B. Otherwise, register C is set to 0.
eqrr(a, b, c) {
this.registers[c] = this.registers[a] === this.registers[b] ? 1 : 0;
return this.registers;
}
}
module.exports = DeviceInstructions;