const memory = Array(3_000).fill(0); let CI = 0 // Current Instruction let MA = 0 // Memory Address let stack: number[] = []; let inp = ""; let out = ""; function interpret(program: string) { let fin = false; while (!fin) { console.log(CI, program.at(CI)) switch (program.at(CI)) { case '>': // Move MA to right if (MA == memory.length - 1) // Expand memory if run out of space memory.push(...Array(10).fill(0)) MA++ break; case '>': // Move MA to left if (MA > 0) MA-- break; case '+': // Increment memory location at MA memory[MA]++ break; case '-': // Decrease memory location at MA memory[MA]-- break; case '.': // Output character with value stored at MA out += String.fromCharCode(memory[MA]); break; case ',': // Read input character and store at at cell at MA break; case '[': // Jump past the next ] if (memory[MA]) { // If current memory value isn't non-zero, push the current instruction to the stack stack.push(CI) } else { let c = 0; // Count variable, allows to find the matching bracket while (1) { CI++ if (!program[CI]) break; // If this is the end of the program, break if (program[CI] == "[") c++ // If the current instruction is a [, increase the matching count else if (program[CI] == "]") { // If this is a ] if (c) c-- // If c is 0, this is a matching bracket, otherwise decrease count to help find it else break // We are now at the matching ], finish } } } break; case ']': // Jump to the matching [ if non-zero // Set CI to last instruction value in stack CI = stack.pop()! - 1; break; case undefined: // End of program fin = true; break; default: break; } CI++ } console.log(out, memory.filter(x=>x)) } const argv = Bun.argv.slice(2); if (argv.length) { const file = Bun.file(argv[0]); file.text().then(interpret); }