Skip to content

Instantly share code, notes, and snippets.

@ReaperUnreal
Last active May 12, 2017 20:48
Show Gist options
  • Save ReaperUnreal/3531331c35032326ab8276ae2091135c to your computer and use it in GitHub Desktop.
Save ReaperUnreal/3531331c35032326ab8276ae2091135c to your computer and use it in GitHub Desktop.
function formatCode(codeStr) {
var arrLines = codeStr.split('\n');
var code = [];
for (var y = 0; y < arrLines.length; y++) {
var line = arrLines[y].split('');
code[y] = [];
for (var x = 0; x < line.length; x++) {
var ins = line[x];
code[y][x] = ins;
}
}
return code;
}
function interpret(inputCode) {
var output = [];
var code = formatCode(inputCode);
var stack = [];
var done = false;
var x = 0;
var y = 0;
var direction = 'r'; // as per Befunge-93 spec
var stringMode = false;
var skip = false;
function doMovement() {
if (direction === 'u') {
y--;
if (y < 0) {
y = code.length - 1;
}
} else if (direction === 'd') {
y++
if (y >= code.length) {
y = 0;
}
} else if (direction === 'r') {
x++;
if (x >= code[y].length) {
x = 0;
}
} else if (direction === 'l') {
x--;
if (x < 0) {
x = code[y].length - 1;
}
}
}
function getFromStorage(x, y) {
if (y >= code.length) {
return ' ';
}
if (x >= code[y].length) {
return ' ';
}
return code[y][x].charCodeAt(0);
}
function putIntoStorage(x, y, val) {
if (y >= code.length) {
for (var i = code.length; i <= y; i++) {
code[i] = [];
}
}
if (x >= code[y].length) {
for (var i = code[y].length; i <= x; i++) {
code[y][i] = ' ';
}
}
code[y][x] = val;
}
// continue until program over
while (! done) {
var instruction = code[y][x];
// string mode enabled, ignore everything except "
if (stringMode) {
if (instruction === '"') {
stringMode = false;
} else {
var val = instruction.charCodeAt(0);
stack.push(val);
}
doMovement();
continue;
}
// skip this instruction
if (skip) {
skip = false;
doMovement();
continue;
}
// process the instructions
switch (instruction) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
// because lazy
var val = parseInt(instruction);
stack.push(val);
break;
case '+':
var a = stack.pop();
var b = stack.pop();
stack.push(a + b);
break;
case '-':
var a = stack.pop();
var b = stack.pop();
stack.push(b - a);
break;
case '*':
var a = stack.pop();
var b = stack.pop();
stack.push(a * b);
break;
case '/':
var a = stack.pop();
var b = stack.pop();
if (a === 0) {
stack.push(0);
} else {
stack.push(~~(b / a));
}
break;
case '%':
var a = stack.pop();
var b = stack.pop();
if (a === 0) {
stack.push(0);
} else {
stack.push(b % a);
}
break;
case '!':
var a = stack.pop();
if (a === 0) {
stack.push(1);
} else {
stack.push(0);
}
break;
case '`':
var a = stack.pop();
var b = stack.pop();
if (b > a) {
stack.push(1);
} else {
stack.push(0);
}
break;
case '>':
direction = 'r';
break;
case '<':
direction = 'l';
break;
case '^':
direction = 'u';
break;
case 'v':
direction = 'd';
break;
case '?':
var options = 'rldu';
var choice = ~~(Math.random() * 4);
direction = options[choice];
break;
case '_':
var a = stack.pop();
direction = (a === 0) ? 'r' : 'l';
break;
case '|':
var a = stack.pop();
direction = (a === 0) ? 'd' : 'u';
break;
case '"':
stringMode = true;
break;
case ':':
if (stack.length === 0) {
stack.push(0);
} else {
stack.push(stack[stack.length - 1]);
}
break;
case '\\':
var a = stack.pop();
var b = 0;
if (stack.length > 0) {
b = stack.pop();
}
stack.push(a);
stack.push(b);
break;
case '$':
stack.pop();
break;
case '.':
var a = stack.pop();
output.push('' + a);
break;
case ',':
var a = stack.pop();
output.push(String.fromCharCode(a));
break;
case '#':
skip = true;
break;
case 'p':
var valY = stack.pop();
var valX = stack.pop();
var v = stack.pop();
putIntoStorage(valX, valY, String.fromCharCode(v));
break;
case 'g':
var valY = stack.pop();
var valX = stack.pop();
var val = getFromStorage(valX, valY);
stack.push(val);
break;
case '@':
done = true;
break;
case ' ':
break;
default:
console.log('unknown instruction: ', instruction);
break;
}
doMovement();
}
return output.join('');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment