diff options
Diffstat (limited to 'src/vm/instruction.js')
-rw-r--r-- | src/vm/instruction.js | 146 |
1 files changed, 82 insertions, 64 deletions
diff --git a/src/vm/instruction.js b/src/vm/instruction.js index dcf9a51..2b8ce84 100644 --- a/src/vm/instruction.js +++ b/src/vm/instruction.js @@ -3,68 +3,86 @@ const { AddrMode } = require('./enum.js'); -exports.DAT = function(core, pc, ins) { +function getOp(core, pc, op) { + switch(op.mode) { + case AddrMode.Immediate: + return { mode: AddrMode.Immediate, value: op.value }; + default: + return { mode: 'precomp', value: core.getLocation(pc, op) }; + } +} + + +function Instruction(f) { + return function(core, pc, ins) { + const a = getOp(core, pc, ins.a); + const b = getOp(core, pc, ins.b); + return f(core, pc, a, b); + } +} + + +exports.DAT = Instruction((core, pc, a, b) => { // do nothing and die return []; -} +}); -exports.MOV = function(core, pc, ins) { - if (ins.a.mode === AddrMode.Immediate) { - const dst = core.getValue(pc, ins.b); - dst.b.value = ins.a.value; +exports.MOV = Instruction((core, pc, a, b) => { + if (a.mode === AddrMode.Immediate) { + const dst = core.data[b.value]; + dst.b.value = a.value; } else { - const src = core.getValue(pc, ins.a); - const dstLocation = core.getLocation(pc, ins.b); + const src = core.data[a.value]; // hacky deep copy - core.data[dstLocation] = JSON.parse(JSON.stringify(src)); + core.data[b.value] = JSON.parse(JSON.stringify(src)); } return [core.normalize(pc, 1)]; -} +}); -exports.ADD = function(core, pc, ins) { - if (ins.a.mode === AddrMode.Immediate) { - const dst = core.getValue(pc, ins.b); - dst.b.value += ins.a.value; +exports.ADD = Instruction((core, pc, a, b) => { + if (a.mode === AddrMode.Immediate) { + const dst = core.data[b.value]; + dst.b.value += a.value; } else { - const src = core.getValue(pc, ins.a); - const dst = core.getValue(pc, ins.b); + const src = core.data[a.value]; + const dst = core.data[b.value]; dst.a.value += src.a.value; dst.b.value += src.b.value; } return [core.normalize(pc, 1)]; -} +}); -exports.SUB = function(core, pc, ins) { - if (ins.a.mode === AddrMode.Immediate) { - const dst = core.getValue(pc, ins.b); - dst.b.value -= ins.a.value; +exports.SUB = Instruction((core, pc, a, b) => { + if (a.mode === AddrMode.Immediate) { + const dst = core.data[b.value]; + dst.b.value -= a.value; } else { - const src = core.getValue(pc, ins.a); - const dst = core.getValue(pc, ins.b); + const src = core.data[a.value]; + const dst = core.data[b.value]; dst.a.value -= src.a.value; dst.b.value -= src.b.value; } return [core.normalize(pc, 1)]; -} +}); -exports.CMP = function(core, pc, ins) { - if (ins.a.mode === AddrMode.Immediate) { - const test = core.getValue(pc, ins.b); - if (test.b.value === ins.a.value) { +exports.CMP = Instruction((core, pc, a, b) => { + if (a.mode === AddrMode.Immediate) { + const test = core.data[b.value]; + if (test.b.value === a.value) { return [core.normalize(pc, 2)]; } else { return [core.normalize(pc, 1)]; } } else { - const left = core.getValue(pc, ins.a); - const right = core.getValue(pc, ins.b); + const left = core.data[a.value]; + const right = core.data[b.value]; if ( // compare opcode left.opcode === right.opcode && @@ -80,93 +98,93 @@ exports.CMP = function(core, pc, ins) { return [core.normalize(pc, 1)]; } } -} +}); -exports.SLT = function(core, pc, ins) { - if (ins.a.mode === AddrMode.Immediate) { - const test = core.getValue(pc, ins.b); - if (ins.a.value < test.b.value) { +exports.SLT = Instruction((core, pc, a, b) => { + if (a.mode === AddrMode.Immediate) { + const test = core.data[b.value]; + if (a.value < test.b.value) { return [core.normalize(pc, 2)]; } else { return [core.normalize(pc, 1)]; } } else { - const left = core.getValue(pc, ins.a); - const right = core.getValue(pc, ins.b); + const left = core.data[a.value]; + const right = core.data[b.value]; if (left.b.value < right.b.value) { return [core.normalize(pc, 2)]; } else { return [core.normalize(pc, 1)]; } } -} +}); -exports.JMP = function(core, pc, ins) { - const dstLoc = core.getLocation(pc, ins.a); - return [dstLoc]; -} +exports.JMP = Instruction((core, pc, a, b) => { + return [a.value]; +}); -exports.JMZ = function(core, pc, ins) { +exports.JMZ = Instruction((core, pc, a, b) => { let test - if (ins.b.mode === AddrMode.Immediate) { - test = (ins.b.value === 0); + if (b.mode === AddrMode.Immediate) { + test = (b.value === 0); } else { - const src = core.getValue(pc, ins.b); + const src = core.data[b.value]; test = (src.b.value === 0); } if (test) { - return [core.getLocation(pc, ins.a)]; + return [a.value]; } else { return [core.normalize(pc, 1)]; } -} +}); -exports.JMN = function(core, pc, ins) { +exports.JMN = Instruction((core, pc, a, b) => { let test; - if (ins.b.mode === AddrMode.Immediate) { - test = (ins.b.value !== 0); + if (b.mode === AddrMode.Immediate) { + test = (b.value !== 0); } else { - const src = core.getValue(pc, ins.b); + const src = core.data[b.value]; test = (src.b.value !== 0); } if (test) { - return [core.getLocation(pc, ins.a)]; + return [a.value]; } else { return [core.normalize(pc, 1)]; } -} +}); -exports.DJN = function(core, pc, ins) { +exports.DJN = Instruction((core, pc, a, b) => { let test; - if (ins.b.mode === AddrMode.Immediate) { - ins.b.value -= 1; - test = (ins.b.value !== 0); + if (b.mode === AddrMode.Immediate) { + core.data[pc].b.value -= 1; + b.value -= 1; + test = (b.value !== 0); } else { - const src = core.getValue(pc, ins.b); + const src = core.data[b.value]; src.b.value -= 1; test = (src.b.value !== 0); } if (test) { - return [core.getLocation(pc, ins.a)]; + return [a.value]; } else { return [core.normalize(pc, 1)]; } -} +}); -exports.SPL = function(core, pc, ins) { +exports.SPL = Instruction((core, pc, a, b) => { return [ core.normalize(pc, 1), - core.getLocation(pc, ins.a), + a.value, ]; -} +}); |