Codon/codon.js
Jump to navigation
Jump to search
This is a function I wrote to execute Codon programs. Given the program as the first parameter and the input as the second parameter, it will return the output. If there is an error compiling, it will log to the console and return no value. If the input is not specified, it will be prompted for every character.
function(program, input) { //compiler program = program.toUpperCase().replace(/#.+/gm, "").match(/\S{3}/gm); //split to groups of 3 characters and remove comments let compiled = "" //the codons compiled into characters 0-J for (codon in program) { let amino = "" switch (program[codon]) { case "GCU": case "GCC": case "GCA": case "GCC": amino = "0"; break; //alaline case "CGU": case "CGC": case "CGA": case "CGG": case "AGA": case "AGG": amino = "1"; break; //arginine case "AAU": case "AAC": amino = "2"; break; //asparagine case "GAU": case "GAC": amino = "3"; break; //aspartic acid case "UGU": case "UGC": amino = "4"; break; //cysteine case "CAA": case "CAG": amino = "5"; break; //glutamine case "GAA": case "GAG": amino = "6"; break; //glutamic acid case "GGU": case "GGC": case "GGA": case "GGG": amino = "7"; break; //glycine case "CAU": case "CAC": amino = "8"; break; //histidine case "AUU": case "AUC": case "AUA": amino = "9"; break; //Isoleucine case "UUA": case "UUG": case "CUU": case "CUC": case "CUA": case "CUG": amino = "A"; break; //Leucine case "AAA": case "AAG": amino = "B"; break; //Lysine case "AUG": amino = "C"; break; //Methionine case "UUU": case "UUC": amino = "D"; break; //phenylalanine case "CCU": case "CCC": case "CCA": case "CCG": amino = "E"; break; //proline case "UCU": case "UCC": case "UCA": case "UCG": case "AGU": case "AGC": amino = "F"; break; //serine case "ACU": case "ACC": case "ACA": case "ACG": amino = "G"; break; //threonine case "UGG": amino = "H"; break; //tryptophan case "UAU": case "UAC": amino = "I"; break; //tyrosine case "GUU": case "GUG": case "GUA": case "GUC": amino = "J"; break; //valine case "UAA": case "UAG": case "UGA": amino = "X"; break; //stop it } if (amino == "") { //if there is no matching amino for the codon console.log("error: invalid codon in index "+codon) return } else { compiled += amino } } let [start, end] = [compiled.indexOf("C"), compiled.indexOf("X")] //get first methionine and stop codons if (start == -1) { //if there's no start console.log("error: there is no start codon (AUG)") return } else if (end == -1) { //if there is no stop codon console.log("error: there is no stop codon") return } compiled = compiled.slice(start, end) //cut out anything before start and after stop //executor let out = "" let in_i = 0 //input indez let a = 0 let b = 0 let terminate = false //if true, terminate the program let flag = false let mem = [] //memory floor = x => Math.floor(x) null0 = x => (x != null || !isNaN(x) ? x : 0) for (let pc = 1; pc < compiled.length; pc++) { //start at 1 because of methionine switch (compiled[pc]) { case "0": //swap registers A and B b = [a, a = b][0] break case "1": //clone A to B b = a break case "2": //clone cell pointed by B to reg B a = null0(mem[floor(a)]) break case "3": //clone reg A to cell pointed by B mem[floor(b)] = a break case "4": //flip flag flag = !flag break case "5": //immediate load 2 codons to A a = parseInt(compiled.slice(pc+1, pc+3), 20) pc+=2 break case "6": //immediade load 4 codons a = parseInt(compiled.slice(pc+1, pc+5), 20) pc+=4 break case "7": //jump if (flag) { pc += floor(a) - 1 //-1 to offset for loop increment pc = (pc < 0 ? 0 : pc > compiled.length ? compiled.length - 1 : pc) //out of bounds fix } break case "8": //input if (input) { a = input.charCodeAt(in_i++) || 0 } else { a = prompt("enter character").charCodeAt(0) || 0 } break case "9": //output out += String.fromCharCode(floor(a)) break case "A": //add a += b break case "B": //sub a -= b break case "C": //terminate terminate = true case "D": //multiply a *= b break case "E": //divide a /= b break case "F": //round a = Math.round(a) break case "G": //negate a *= -1 break case "H": //a > b flag = (a>b?true:false) break case "I": //a < b flag = (a<b?true:false) break case "J": //a == b flag = (a==b?true:false) break } if (terminate) { return out } } return out }