summaryrefslogtreecommitdiff
path: root/src/vm/vm.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/vm.js')
-rw-r--r--src/vm/vm.js75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/vm/vm.js b/src/vm/vm.js
index 1ec890b..6add546 100644
--- a/src/vm/vm.js
+++ b/src/vm/vm.js
@@ -31,6 +31,81 @@ class Warrior {
class RedcodeVm {
constructor(coresize, warriors) {
this.core = new Core(coresize);
+ this.warriors = this.core.initialize(warriors)
+ .map(start => new Warrior(start));
+ }
+
+ step() {
+ let running = 0;
+
+ for (let warrior of this.warriors) {
+ if (warrior.isDead()) {
+ continue;
+ } else {
+ running += 1;
+ }
+
+ const pc = warrior.next();
+ const ins = this.core.data[pc];
+ let next;
+ switch(ins.opcode) {
+ case 'DAT':
+ next = DAT(this.core, pc, ins);
+ break;
+ case 'MOV':
+ next = MOV(this.core, pc, ins);
+ break;
+ case 'ADD':
+ next = ADD(this.core, pc, ins);
+ break;
+ case 'SUB':
+ next = SUB(this.core, pc, ins);
+ break;
+ case 'CMP':
+ next = CMP(this.core, pc, ins);
+ break;
+ case 'SLT':
+ next = SLT(this.core, pc, ins);
+ break;
+ case 'JMP':
+ next = JMP(this.core, pc, ins);
+ break;
+ case 'JMZ':
+ next = JMZ(this.core, pc, ins);
+ break;
+ case 'JMN':
+ next = JMN(this.core, pc, ins);
+ break;
+ case 'DJN':
+ next = DJN(this.core, pc, ins);
+ break;
+ case 'SPL':
+ next = SPL(this.core, pc, ins);
+ break;
+ default:
+ throw `core corruption: bad instruction ${ins}`
+ }
+ }
+ return running;
+ }
+
+ run(maxSteps) {
+ let steps = 0;
+ let running = this.warriors.length;
+ while(running > 0 && steps < maxSteps) {
+ running = this.step();
+ steps += 1;
+ }
+
+ if (running !== 0) {
+ console.log("draw, maximum steps exceeded");
+ }
+ for (let i=0; i<this.warriors.length; i++) {
+ console.log(`${i} running: ${!this.warriors[i].isDead()}`);
+ }
}
};
+
+
+exports.RedcodeVm = RedcodeVm;