93 lines
2.7 KiB
TypeScript
93 lines
2.7 KiB
TypeScript
const memory = Array<number>(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<number>(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);
|
|
} |