UNPKG

hammerheadjs

Version:

An array based virtual machine written in Nodejs

899 lines (895 loc) 27.6 kB
/** * Main file for virtual machine */ var HammerHead = (function(){ //private variable to store operations var ASM = { //inp op codes increase the pointer "aaa":function(mach){ mach.pointer += 1; }, "aab":function(mach){ mach.pointer += 2; }, "aac":function(mach){ mach.pointer += 3; }, "aad":function(mach){ mach.pointer += 4; }, "aae":function(mach){ mach.pointer += 5; }, "aaf":function(mach){ mach.pointer += 10; }, "aag":function(mach){ mach.pointer += 20; }, "aah":function(mach){ mach.pointer += 25; }, "aai":function(mach){ mach.pointer += 50; }, "aaj":function(mach){ mach.pointer += 100; }, "aak":function(mach){ mach.pointer += 200; }, "aal":function(mach){ mach.pointer += 500; }, "aam":function(mach){ mach.pointer += 1000; }, //dep opcodes decrease the pointer "aan":function(mach){ mach.pointer -= 1; }, "aao":function(mach){ mach.pointer -= 2; }, "aap":function(mach){ mach.pointer -= 3; }, "aaq":function(mach){ mach.pointer -= 4; }, "aar":function(mach){ mach.pointer -= 5; }, "aas":function(mach){ mach.pointer -= 10; }, "aat":function(mach){ mach.pointer -= 20; }, "aau":function(mach){ mach.pointer -= 25; }, "aav":function(mach){ mach.pointer -= 50; }, "aaw":function(mach){ mach.pointer -= 100; }, "aax":function(mach){ mach.pointer -= 200; }, "aay":function(mach){ mach.pointer -= 500; }, "aaz":function(mach){ mach.pointer -= 1000; }, //sets pointer to specific value "aaA":function(mach){ if(typeof mach.cells[mach.pointer] === 'number') mach.pointer = mach.cells[mach.pointer]; }, "aaB":function(mach){ mach.pointer = 0; }, "aaC":function(mach){ mach.pointer = 1; }, "aaD":function(mach){ mach.pointer = 2; }, "aaE":function(mach){ mach.pointer = 3; }, "aaF":function(mach){ mach.pointer = 5; }, "aaG":function(mach){ mach.pointer = 6; }, "aaH":function(mach){ mach.pointer = 8; }, "aaI":function(mach){ mach.pointer = 10; }, "aaJ":function(mach){ mach.pointer = 20; }, "aaK":function(mach){ mach.pointer = 25; }, "aaL":function(mach){ mach.pointer = 50; }, "aaM":function(mach){ mach.pointer = 100; }, "aaN":function(mach){ mach.pointer = 200; }, "aaO":function(mach){ mach.pointer = 500; }, "aaP":function(mach){ mach.pointer = 1000; }, "aaQ":function(mach){ mach.pointer *= 2; }, "aaR":function(mach){ mach.pointer *= 3; }, "aaS":function(mach){ mach.pointer *= 4; }, "aaT":function(mach){ mach.pointer *= 5; }, "aaU":function(mach){ mach.pointer *= 10; }, "aaV":function(mach){ mach.pointer *= 100; }, "aaW":function(mach){ mach.pointer = Math.floor(mach.pointer / 2); }, "aaX":function(mach){ mach.pointer = Math.floor(mach.pointer / 3); }, "aaY":function(mach){ mach.pointer = Math.floor(mach.pointer / 5); }, "aaZ":function(mach){ mach.pointer = Math.floor(mach.pointer / 10); }, //opcodes load an integer value to the cell "aba":function(mach){ mach.cells[mach.pointer] = 0; }, "abb":function(mach){ mach.cells[mach.pointer] = 1; }, "abc":function(mach){ mach.cells[mach.pointer] = 2; }, "abd":function(mach){ mach.cells[mach.pointer] = 3; }, "abe":function(mach){ mach.cells[mach.pointer] = 4; }, "abf":function(mach){ mach.cells[mach.pointer] = 5; }, "abg":function(mach){ mach.cells[mach.pointer] = 10; }, "abh":function(mach){ mach.cells[mach.pointer] = 20; }, "abi":function(mach){ mach.cells[mach.pointer] = 25; }, "abj":function(mach){ mach.cells[mach.pointer] = 50; }, "abk":function(mach){ mach.cells[mach.pointer] = 100; }, "abl":function(mach){ mach.cells[mach.pointer] = 200; }, "abm":function(mach){ mach.cells[mach.pointer] = 500; }, "abn":function(mach){ mach.cells[mach.pointer] = 1000; }, "abo":function(mach){ mach.cells[mach.pointer] = 2000; }, "abp":function(mach){ mach.cells[mach.pointer] = 5000; }, "abq":function(mach){ mach.cells[mach.pointer] = 10000; }, "abr":function(mach){ mach.cells[mach.pointer] = 100000; }, //loads decimal value "abs":function(mach){ mach.cells[mach.pointer] = 0.1; }, "abt":function(mach){ mach.cells[mach.pointer] = 0.2; }, "abu":function(mach){ mach.cells[mach.pointer] = 0.25; }, "abv":function(mach){ mach.cells[mach.pointer] = 0.5; }, "abw":function(mach){ mach.cells[mach.pointer] = 0.6; }, "abx":function(mach){ mach.cells[mach.pointer] = 0.75; }, //load boolean "aby":function(mach){ mach.cells[mach.pointer] = true; }, "abz":function(mach){ mach.cells[mach.pointer] = false; }, //lds opcodes load a string to the current cell "abA":function(mach){ mach.cells[mach.pointer] = ""; }, //lda opcodes load arrays to the current cell "abB":function(mach){ mach.cells[mach.pointer] = []; }, //opcodes load empty objects to the current cell "abC":function(mach){ mach.cells[mach.pointer] = {}; }, //opcodes load null to the current cell. "abD":function(mach){ mach.cells[mach.pointer] = null; }, //opcodes load an undefined in the current cell "abE":function(mach){ mach.cells[mach.pointer] = undefined; }, //sets return value to current cell "abF":function(mach){ mach.returnval = mach.cells[mach.pointer]; }, "abG":function(mach){ mach.returnval = mach.cells[mach.pointer+1]; }, "abH":function(mach){ mach.returnval = mach.cells[mach.pointer-1]; }, //adding integers "abI":function(mach){ mach.cells[mach.pointer] += 1; }, "abJ":function(mach){ mach.cells[mach.pointer] += 2; }, "abK":function(mach){ mach.cells[mach.pointer] += 3; }, "abL":function(mach){ mach.cells[mach.pointer] += 5; }, "abM":function(mach){ mach.cells[mach.pointer] += 10; }, "abO":function(mach){ mach.cells[mach.pointer] += 20; }, "abP":function(mach){ mach.cells[mach.pointer] += 25; }, "abQ":function(mach){ mach.cells[mach.pointer] += 50; }, "abR":function(mach){ mach.cells[mach.pointer] += 100; }, "abS":function(mach){ mach.cells[mach.pointer] += 200; }, "abT":function(mach){ mach.cells[mach.pointer] += 500; }, "abU":function(mach){ mach.cells[mach.pointer] += 1000; }, "abV":function(mach){ mach.cells[mach.pointer] += 2000; }, "abW":function(mach){ mach.cells[mach.pointer] += 5000; }, "abX":function(mach){ mach.cells[mach.pointer] += 10000; }, "abY":function(mach){ mach.cells[mach.pointer] += 25000; }, "abZ":function(mach){ mach.cells[mach.pointer] += 50000; }, //subtract integers "aca":function(mach){ mach.cells[mach.pointer] -= 1; }, "acb":function(mach){ mach.cells[mach.pointer] -= 2; }, "acc":function(mach){ mach.cells[mach.pointer] -= 3; }, "acd":function(mach){ mach.cells[mach.pointer] -= 5; }, "ace":function(mach){ mach.cells[mach.pointer] -= 10; }, "acf":function(mach){ mach.cells[mach.pointer] -= 20; }, "acg":function(mach){ mach.cells[mach.pointer] -= 25; }, "ach":function(mach){ mach.cells[mach.pointer] -= 50; }, "aci":function(mach){ mach.cells[mach.pointer] -= 100; }, "acj":function(mach){ mach.cells[mach.pointer] -= 200; }, "ack":function(mach){ mach.cells[mach.pointer] -= 500; }, "acl":function(mach){ mach.cells[mach.pointer] -= 1000; }, "acm":function(mach){ mach.cells[mach.pointer] -= 2000; }, "acn":function(mach){ mach.cells[mach.pointer] -= 5000; }, "aco":function(mach){ mach.cells[mach.pointer] -= 10000; }, "acp":function(mach){ mach.cells[mach.pointer] -= 25000; }, "acq":function(mach){ mach.cells[mach.pointer] -= 50000; }, //multiply integer in current cell "acr":function(mach){ mach.cells[mach.pointer] *= 1; }, "acs":function(mach){ mach.cells[mach.pointer] *= 2; }, "act":function(mach){ mach.cells[mach.pointer] *= 3; }, "acu":function(mach){ mach.cells[mach.pointer] *= 5; }, "acv":function(mach){ mach.cells[mach.pointer] *= 10; }, "acw":function(mach){ mach.cells[mach.pointer] *= 20; }, "acx":function(mach){ mach.cells[mach.pointer] *= 25; }, "acy":function(mach){ mach.cells[mach.pointer] *= 50; }, "acz":function(mach){ mach.cells[mach.pointer] *= 100; }, "acA":function(mach){ mach.cells[mach.pointer] *= 200; }, "acB":function(mach){ mach.cells[mach.pointer] *= 500; }, "acC":function(mach){ mach.cells[mach.pointer] *= 1000; }, "acD":function(mach){ mach.cells[mach.pointer] *= 2000; }, "acE":function(mach){ mach.cells[mach.pointer] *= 5000; }, //divide integer in cell "acF":function(mach){ mach.cells[mach.pointer] /= 2; }, "acG":function(mach){ mach.cells[mach.pointer] /= 3; }, "acH":function(mach){ mach.cells[mach.pointer] /= 4; }, "acI":function(mach){ mach.cells[mach.pointer] /= 5; }, "acJ":function(mach){ mach.cells[mach.pointer] /= 10; }, "acK":function(mach){ mach.cells[mach.pointer] /= 25; }, "acL":function(mach){ mach.cells[mach.pointer] /= 100; }, "acM":function(mach){ mach.cells[mach.pointer] /= 1000; }, //floor division of current cell "acN":function(mach){ mach.cells[mach.pointer] = Math.floor(mach.cells[mach.pointer]/2) }, "acO":function(mach){ mach.cells[mach.pointer] = Math.floor(mach.cells[mach.pointer]/3) }, "acP":function(mach){ mach.cells[mach.pointer] = Math.floor(mach.cells[mach.pointer]/5) }, "acQ":function(mach){ mach.cells[mach.pointer] = Math.floor(mach.cells[mach.pointer]/10) }, "acR":function(mach){ mach.cells[mach.pointer] = Math.floor(mach.cells[mach.pointer]/20) }, "acS":function(mach){ mach.cells[mach.pointer] = Math.floor(mach.cells[mach.pointer]/25) }, "acT":function(mach){ mach.cells[mach.pointer] = Math.floor(mach.cells[mach.pointer]/100) }, "acU":function(mach){ mach.cells[mach.pointer] = Math.floor(mach.cells[mach.pointer]/250) }, "acV":function(mach){ mach.cells[mach.pointer] = Math.floor(mach.cells[mach.pointer]/500) }, "acW":function(mach){ mach.cells[mach.pointer] = Math.floor(mach.cells[mach.pointer]/1000) }, "acX":function(mach){ mach.cells[mach.pointer] = Math.floor(mach.cells[mach.pointer]/2000) }, "acY":function(mach){ mach.cells[mach.pointer] = Math.floor(mach.cells[mach.pointer]/5000) }, "acZ":function(mach){ mach.cells[mach.pointer] = Math.floor(mach.cells[mach.pointer]/1000) }, //rp opcodes repeat the previous opcode some number of times. Utilizes repeatcount tracker of the machine "ada":function(mach){ if(mach.repeatcount === false) { mach.repeatcount = 0; mach.index -= 2; } else if(mach.repeatcount === 0){ mach.repeatcount = false; } else { mach.repeatcount -= 1; mach.index -= 2; } }, "adb":function(mach){ if(mach.repeatcount === false) { mach.repeatcount = 1; mach.index -= 2; } else if(mach.repeatcount === 0){ mach.repeatcount = false; } else { mach.repeatcount -= 1; mach.index -= 2; } }, "adc":function(mach){ if(mach.repeatcount === false) { mach.repeatcount = 4; mach.index -= 2; } else if(mach.repeatcount === 0){ mach.repeatcount = false; } else { mach.repeatcount -= 1; mach.index -= 2; } }, "add":function(mach){ if(mach.repeatcount === false) { mach.repeatcount = 9; mach.index -= 2; } else if(mach.repeatcount === 0){ mach.repeatcount = false; } else { mach.repeatcount -= 1; mach.index -= 2; } }, "ade":function(mach){ if(mach.repeatcount === false) { mach.repeatcount = 14; mach.index -= 2; } else if(mach.repeatcount === 0){ mach.repeatcount = false; } else { mach.repeatcount -= 1; mach.index -= 2; } }, "adf":function(mach){ if(mach.repeatcount === false) { mach.repeatcount = 19; mach.index -= 2; } else if(mach.repeatcount === 0){ mach.repeatcount = false; } else { mach.repeatcount -= 1; mach.index -= 2; } }, "adg":function(mach){ if(mach.repeatcount === false) { mach.repeatcount = 29; mach.index -= 2; } else if(mach.repeatcount === 0){ mach.repeatcount = false; } else { mach.repeatcount -= 1; mach.index -= 2; } }, "adh":function(mach){ if(mach.repeatcount === false) { mach.repeatcount = 49; mach.index -= 2; } else if(mach.repeatcount === 0){ mach.repeatcount = false; } else { mach.repeatcount -= 1; mach.index -= 2; } }, "adi":function(mach){ if(mach.repeatcount === false) { mach.repeatcount = 99; mach.index -= 2; } else if(mach.repeatcount === 0){ mach.repeatcount = false; } else { mach.repeatcount -= 1; mach.index -= 2; } }, "adj":function(mach){ if(mach.repeatcount === false) { mach.repeatcount = 199; mach.index -= 2; } else if(mach.repeatcount === 0){ mach.repeatcount = false; } else { mach.repeatcount -= 1; mach.index -= 2; } }, "adk":function(mach){ if(mach.repeatcount === false) { mach.repeatcount = 299; mach.index -= 2; } else if(mach.repeatcount === 0){ mach.repeatcount = false; } else { mach.repeatcount -= 1; mach.index -= 2; } }, "adl":function(mach){ if(mach.repeatcount === false) { mach.repeatcount = 499; mach.index -= 2; } else if(mach.repeatcount === 0){ mach.repeatcount = false; } else { mach.repeatcount -= 1; mach.index -= 2; } }, "adm":function(mach){ if(mach.repeatcount === false) { mach.repeatcount = 999; mach.index -= 2; } else if(mach.repeatcount === 0){ mach.repeatcount = false; } else { mach.repeatcount -= 1; mach.index -= 2; } }, //jump forward some number "adn":function(mach){ mach.index += 1; //prevention of array out of bounds if(mach.index > mach.instrucnum) mach.index = mach.instrucnum; }, "ado":function(mach){ mach.index += 2; if(mach.index > mach.instrucnum) mach.index = mach.instrucnum; }, "adp":function(mach){ mach.index += 3; if(mach.index > mach.instrucnum) mach.index = mach.instrucnum; }, "adq":function(mach){ mach.index += 4; if(mach.index > mach.instrucnum) mach.index = mach.instrucnum; }, "adr":function(mach){ mach.index += 5; if(mach.index > mach.instrucnum) mach.index = mach.instrucnum; }, "ads":function(mach){ mach.index += 6; if(mach.index > mach.instrucnum) mach.index = mach.instrucnum; }, "adt":function(mach){ mach.index += 10; if(mach.index > mach.instrucnum) mach.index = mach.instrucnum; }, "adu":function(mach){ mach.index += 20; if(mach.index > mach.instrucnum) mach.index = mach.instrucnum; }, "adv":function(mach){ mach.index += 50; if(mach.index > mach.instrucnum) mach.index = mach.instrucnum; }, "adw":function(mach){ mach.index += 100; if(mach.index > mach.instrucnum) mach.index = mach.instrucnum; }, "adx":function(mach){ mach.index += 150; if(mach.index > mach.instrucnum) mach.index = mach.instrucnum; }, "ady":function(mach){ mach.index += 250; if(mach.index > mach.instrucnum) mach.index = mach.instrucnum; }, "adz":function(mach){ mach.index += 500; if(mach.index > mach.instrucnum) mach.index = mach.instrucnum; }, //adding cell values from forward cells "adA":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer+1] }, "adB":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer+2] }, "adC":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer+3] }, "adD":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer+4] }, "adE":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer+5] }, "adF":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer+6] }, "adG":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer+7] }, "adH":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer+8] }, "adI":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer+9] }, "adJ":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer+10] }, //adding from previous cells "adK":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer-1] }, "adL":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer-2] }, "adM":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer-3] }, "adN":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer-4] }, "adO":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer-5] }, "adP":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer-6] }, "adQ":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer-7] }, "adR":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer-8] }, "adS":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer-9] }, "adT":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer-10] }, "adU":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer+1] }, "adV":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer+2] }, "adW":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer+3] }, "adX":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer+4] }, "adY":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer+5] }, "adZ":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer+6] }, "aea":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer+7] }, "aeb":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer+8] }, "aec":function(mach){ mach.cells[mach.pointer] += mach.cells[mach.pointer+9] }, "aed":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer+10] }, //subtract from previous cells "aee":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer-1] }, "aef":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer-2] }, "aeg":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer-3] }, "aeh":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer-4] }, "aei":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer-5] }, "aej":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer-6] }, "aek":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer-7] }, "ael":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer-8] }, "aem":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer-9] }, "aen":function(mach){ mach.cells[mach.pointer] -= mach.cells[mach.pointer-10] }, //B instructions "baa":function(mach){ if(mach.cells[mach.pointer] === 0) mach.pointer += 1; }, "bab":function(mach){ if(mach.cells[mach.pointer] === 0) mach.pointer -= 1; }, "bac":function(mach){ if(mach.cells[mach.pointer] !== 0) mach.pointer += 1; }, "bad":function(mach){ if(mach.cells[mach.pointer] !== 0) mach.pointer -= 1; }, "bae":function(mach){ if(mach.cells[mach.pointer] === true) mach.pointer += 1; }, "baf":function(mach){ if(mach.cells[mach.pointer] === true) mach.pointer -= 1; } }; function HammerHead(){ this.cells = new Array(10000); this.pointer = 0; //seperate counter for indexing instructions this.index = 0; //keeps track of repeating instructions this.repeatcount = false; this.funcs = ASM; this.returnval = null; this.instrucnum = 0; } HammerHead.prototype.runcode = function(code){ //splits the code by newline or white space var instrucs = code.split(/ |\n/); this.instrucnum = instrucs.length-1; for(this.index = 0;this.index<instrucs.length;this.index++) { if(instrucs[this.index] in this.funcs) { try { this.funcs[instrucs[this.index]](this); } catch(err){ return "ERROR" } } //external, non-determinstic instruction that loads strings into the current cell else if(/^\$.+/.test(instrucs[this.index])) { this.cells[this.pointer] = instrucs[this.index].slice(1, instrucs[this.index].length); } else { return "ERROR" } } //returns the requested value var response = this.returnval; this.returnval = null; return response }; return HammerHead; })(); exports.HammerHead = HammerHead;