jsPerf.app is an online JavaScript performance benchmark test runner & jsperf.com mirror. It is a complete rewrite in homage to the once excellent jsperf.com now with hopefully a more modern & maintainable codebase.
jsperf.com URLs are mirrored at the same path, e.g:
https://jsperf.com/negative-modulo/2
Can be accessed at:
https://jsperf.app/negative-modulo/2
code = '91+:*:*:*:>1-# _@'
var constablebrew = (function(sourceCode) {
var instructions = {}, compiledIPs = {},
a = 0,
b = 0,
data = [], // Registers and stack for the program
ip = {
x: 0,
y: 0,
dx: 1,
dy: 0
}, // Instruction pointer position and direction
output = '',
code;
function copyIP(ip) {
return {
'x': ip.x,
'y': ip.y,
'dx': ip.dx,
'dy': ip.dy
};
}
function moveIP(ip) {
ip.x += ip.dx;
ip.y += ip.dy;
if (ip.y >= code.length) {
ip.y = 0;
} else
if (ip.y < 0) {
ip.y = code.length - 1;
}
if (ip.x >= code[ip.y].length) {
ip.x = 0;
} else
if (ip.x < 0) {
ip.x = code[ip.y].length - 1;
}
return ip;
}
function getIPKey(ip) {
return 'x' + ip.x + '_' + (ip.dx + 2) + '_y' + ip.y + '_' + (ip.dy + 2);
}
function compileCode(ipp) {
var js = {
'0': 'data.push(0);\n',
'1': 'data.push(1);\n',
'2': 'data.push(2);\n',
'3': 'data.push(3);\n',
'4': 'data.push(4);\n',
'5': 'data.push(5);\n',
'6': 'data.push(6);\n',
'7': 'data.push(7);\n',
'8': 'data.push(8);\n',
'9': 'data.push(9);\n',
'+': 'a=data.pop()||0;b=data.pop()||0;data.push(b+a);\n',
'-': 'a=data.pop()||0;b=data.pop()||0;data.push(b-a);\n',
'*': 'a=data.pop()||0;b=data.pop()||0;data.push(b*a);\n',
'/': 'a=data.pop()||0;b=data.pop()||0;data.push((a)?~~(b/a):0);\n',
'!': 'a=data.pop()||0;data.push(!a);\n',
'`': 'a=data.pop()||0;b=data.pop()||0;data.push((b>a)?1:0);\n',
':': 'if(data.length){a=data.pop()||0;data.push(a);data.push(a);}else{data.push(0);}\n',
'\\': 'a=data.pop()||0;b=data.pop()||0;data.push(a);data.push(b);\n',
'$': 'data.pop();\n',
'.': 'output += data.pop();\n',
',': 'output += String.fromCharCode(data.pop());\n',
'g': 'a=data.pop()||0;b=data.pop()||0;data.push(code[a][b].charCodeAt(0));\n',
' ': ''
},
startingIP = getIPKey(ipp),
ipx, chr, funcBody = '',
stringifying = false;
compiledIPs[getIPKey(ipp)] = compiledIPs[getIPKey(ipp)] || {};
while (!compiledIPs[getIPKey(ipp)][startingIP]) {
// Mark location as visited
compiledIPs[getIPKey(ipp)] = compiledIPs[getIPKey(ipp)] || {};
compiledIPs[getIPKey(ipp)][startingIP] = true;
chr = code[ipp.y][ipp.x];
if (stringifying && chr !== '"') {
funcBody += 'data.push(' + chr.charCodeAt(0) + ');\n';
} else {
switch (chr) {
case '"':
stringifying = !stringifying;
break;
case '#':
moveIP(ipp);
break;
case '>':
ipp.dx = 1;
ipp.dy = 0;
break;
case '<':
ipp.dx = -1;
ipp.dy = 0;
break;
case '^':
ipp.dx = 0;
ipp.dy = -1;
break;
case 'v':
ipp.dx = 0;
ipp.dy = 1;
break;
case '_':
funcBody += '\n' +
'ip.x = ' + ipp.x + ';\n' +
'ip.y = ' + ipp.y + ';\n' +
'if(~~(data.pop()||0) ){\n' +
' ip.dx = -1; ip.dy = 0;\n' +
'}else{\n' +
' ip.dx = 1; ip.dy = 0;\n' +
'}\n' +
'return true;';
instructions[startingIP] = eval(startingIP + ' = function(){' + funcBody + '};');
ipx = copyIP(ipp);
ipx.dx = -1;
ipx.dy = 0;
moveIP(ipx);
compileCode(ipx);
ipx = copyIP(ipp);
ipx.dx = 1;
ipx.dy = 0;
moveIP(ipx);
compileCode(ipx);
return;
case '|':
funcBody += '\n' +
'ip.x = ' + ipp.x + ';\n' +
'ip.y = ' + ipp.y + ';\n' +
'if(~~(data.pop()||0) ){\n' +
' ip.dx = 0; ip.dy = -1;\n' +
'}else{\n' +
' ip.dx = 0; ip.dy = 1;\n' +
'}\n' +
'return true;';
instructions[startingIP] = eval(startingIP + ' = function(){' + funcBody + '};');
ipx = copyIP(ipp);
ipx.dx = 0;
ipx.dy = -1;
moveIP(ipx);
compileCode(ipx);
ipx = copyIP(ipp);
ipx.dx = 0;
ipx.dy = 1;
moveIP(ipx);
compileCode(ipx);
return;
case '?':
funcBody += '\n' +
'ip.x = ' + ipp.x + ';\n' +
'ip.y = ' + ipp.y + ';\n' +
'switch( ~~(Math.random() * 4) ){\n' +
' case 0: ip.dx = 0; ip.dy = -1; break;\n' +
' case 1: ip.dx = 0; ip.dy = 1; break;\n' +
' case 2: ip.dx = 1; ip.dy = 0; break;\n' +
' case 3: ip.dx = -1; ip.dy = 0;\n' +
'}\n' +
'return true;';
instructions[startingIP] = eval(startingIP + ' = function(){' + funcBody + '};');
ipx = copyIP(ipp);
ipx.dx = 0;
ipx.dy = -1;
moveIP(ipx);
compileCode(ipx);
ipx = copyIP(ipp);
ipx.dx = 0;
ipx.dy = 1;
moveIP(ipx);
compileCode(ipx);
ipx = copyIP(ipp);
ipx.dx = -1;
ipx.dy = 0;
moveIP(ipx);
compileCode(ipx);
ipx = copyIP(ipp);
ipx.dx = 1;
ipx.dy = 0;
moveIP(ipx);
compileCode(ipx);
return;
case 'p':
funcBody += '\n' +
'a=data.pop()||0;\n' +
'b=data.pop()||0;\n' +
'code[a][b]=String.fromCharCode(data.pop());\n' +
'compileCode(' + JSON.stringify(moveIP(copyIP(ipp))) + ');\n' +
'ip.x = ' + ipp.x + ';\n' +
'ip.y = ' + ipp.y + ';\n' +
'ip.dx = ' + ipp.dx + ';\n' +
'ip.dy = ' + ipp.dy + ';\n' +
'return true;';
instructions[startingIP] = eval(startingIP + ' = function(){' + funcBody + '};');
return;
case '@':
funcBody = 'if (new Date().getTime() - t > 2000) return false;\n' + funcBody;
funcBody += '\n' +
'return false;';
instructions[startingIP] = eval(startingIP + ' = function(){' + funcBody + '};');
return;
default:
funcBody += js[chr];
} // switch
} // if stringifying
moveIP(ipp);
compiledIPs[getIPKey(ipp)] = compiledIPs[getIPKey(ipp)] || {};
}
if (funcBody !== '') {
instructions[startingIP] = eval(startingIP + ' = function(){' + funcBody + '};');
}
}
function run() {
try {
while (instructions[getIPKey(ip)]()) {
moveIP(ip);
//if(printCounter++ < 100) print('<pre>ip:'+getIPKey(ip)+'\n a:'+a+'\n b:'+b+'\n data:'+JSON.stringify(data)+'\n out:'+output+'</pre>');
}
} catch (e) {
//print('ERROR! ' + e.message);
}
}
code = sourceCode.split('\n').map(function(e) {
return e.split('');
});
compileCode({
x: 0,
y: 0,
dx: 1,
dy: 0
});
//for(var o in instructions) print('function ' + o + '<pre>' + instructions[o] + '</pre>');
return function() {
a = 0;
b = 0;
data = [];
ip = {x:0, y:0, dx:1, dy:0};
output = '';
run();
return output;
}
})(code);
function xDranik(code) {
code = code.split('\n').map(function(e) {
return e.split("")
});
var output = '';
var stack = [];
var rPointer = 0;
var cPointer = 0;
var a, b, c;
var command;
var right = true;
var up = down = left = false;
var trampoline = false;
while (code[rPointer][cPointer] != '@') {
command = code[rPointer][cPointer];
if (command === ' ');
else if (command >= '0' && command <= '9') {
stack.push(parseInt(command));
} else if (command === '+') {
a = stack.pop();
b = stack.pop();
c = a + b;
stack.push(c);
} else if (command === '-') {
a = stack.pop();
b = stack.pop();
c = b - a;
stack.push(c);
} else if (command === '*') {
a = stack.pop();
b = stack.pop();
c = a * b;
stack.push(c);
} else if (command === '/') {
a = stack.pop();
b = stack.pop();
if (a == 0) stack.push(0);
else {
c = Math.floor(b / a);
stack.push(c);
}
} else if (command === '%') {
a = stack.pop();
b = stack.pop();
if (a == 0) stack.push(0);
else {
c = b % a;
stack.push(c);
}
} else if (command === '!') {
a = stack.pop();
if (a == 0) stack.push(1);
else stack.push(0);
} else if (command === '`') {
a = stack.pop();
b = stack.pop();
if (b > a) stack.push(1);
else stack.push(0);
} else if (command === '>') {
right = true;
up = down = left = false;
} else if (command === '<') {
left = true;
up = down = right = false;
} else if (command === '^') {
up = true;
down = left = right = false;
} else if (command === 'v') {
down = true;
up = left = right = false;
} else if (command === '?') {
var ran = Math.floor(Math.random() * 4) + 1;
if (ran === 1) {
up = true;
down = left = right = false;
} else if (ran === 2) {
down = true;
up = left = right = false;
} else if (ran === 3) {
left = true;
up = down = right = false;
} else {
right = true;
up = down = left = false;
}
} else if (command === "_") {
a = stack.pop();
if (a == 0) {
right = true;
up = down = left = false;
} else {
left = true;
up = down = right = false;
}
} else if (command === '|') {
a = stack.pop();
if (a == 0) {
down = true;
up = left = right = false;
} else {
up = true;
down = left = right = false;
}
} else if (command === '"') {
//TODO
if (up) rPointer--;
if (down) rPointer++;
if (left) cPointer--;
if (right) cPointer++;
command = code[rPointer][cPointer];
while (command != '"') {
stack.push(command.charCodeAt(0));
if (up) rPointer--;
if (down) rPointer++;
if (left) cPointer--;
if (right) cPointer++;
command = code[rPointer][cPointer];
}
} else if (command === ':') {
if (stack.length == 0) stack.push(0);
else {
a = stack.pop();
stack.push(a);
stack.push(a);
}
} else if (command === '\\') {
a = stack.pop();
b = stack.pop();
stack.push(a);
stack.push(b);
} else if (command === '$') {
stack.pop();
} else if (command === '.') {
a = stack.pop();
output += a.toString();
} else if (command === ',') {
a = stack.pop();
output += String.fromCharCode(a);
} else if (command === '#') {
trampoline = true;
} else if (command === 'p') {
a = stack.pop(); //y
b = stack.pop(); //x
c = stack.pop(); //v
//console.log(a + ":" + b + ":" + c);
//todo
code[a][b] = String.fromCharCode(c);
} else if (command === 'g') {
a = stack.pop(); //y
b = stack.pop(); //x
stack.push(code[a][b].charCodeAt(0));
}
if (up) rPointer--;
if (down) rPointer++;
if (left) cPointer--;
if (right) cPointer++;
if (trampoline) {
if (up) rPointer--;
if (down) rPointer++;
if (left) cPointer--;
if (right) cPointer++;
trampoline = false;
}
}
return output;
}
function untrue(code) {
// Break code string into array
code = code.split('\n');
for (var i = 0; i < code.length; i++) {
code[i] = code[i].split('');
}
//console.log(code);
var stack = [];
var op = null;
var ptr = new Pointer();
var output = '';
var put = [];
var capture = false;
var runCommand = function() {
if (!code[ptr.y][ptr.x]) op = ' ';
else op = code[ptr.y][ptr.x];
if (op === '"') {
if (capture == false) {
capture = true;
ptr.moveNext();
return;
} else {
capture = false;
}
}
if (capture) {
stack.push(op.charCodeAt(0));
ptr.moveNext();
return;
}
if (op === ' ') {
op = 'nop';
}
if (op === '<') {
ptr.moveLeft();
}
if (op === '>') {
ptr.moveRight();
}
if (op === '^') {
ptr.moveUp();
}
if (op === 'v') {
ptr.moveDown();
}
if (op === '?') {
ptr.moveRandom();
}
if (op === '#') {
ptr.moveNext();
}
if (op === '+') {
var a = ~~stack.pop();
var b = ~~stack.pop();
stack.push(a + b);
}
if (op === '-') {
var a = ~~stack.pop();
var b = ~~stack.pop();
stack.push(b - a);
}
if (op === '*') {
var a = ~~stack.pop();
var b = ~~stack.pop();
stack.push(a * b);
}
if (op === '/') {
var a = ~~stack.pop();
var b = ~~stack.pop();
stack.push(b / a);
}
if (op === '%') {
var a = ~~stack.pop();
var b = ~~stack.pop();
stack.push(b % a ? b % a : 0);
}
if (op.match(/[0-9]/)) {
stack.push(op);
}
if (op === '!') {
var a = stack.pop();
stack.push(a == 0 ? 1 : 0);
}
if (op === '`') {
var a = stack.pop();
var b = stack.pop();
stack.push(b > a ? 1 : 0);
}
if (op === '_') {
var a = stack.pop();
a == 0 || !a ? ptr.moveRight() : ptr.moveLeft();
}
if (op === '|') {
var a = stack.pop();
a == 0 || !a ? ptr.moveDown() : ptr.moveUp();
}
if (op === ':') {
var a = stack.pop();
if ( !! a) {
stack.push(a);
stack.push(a);
} else {
stack.push(0);
}
}
if (op === '\\') {
if (stack.length == 1) {
var a = stack.pop();
stack.push(0);
stack.push(a);
} else {
var a = stack.pop();
var b = stack.pop();
stack.push(a);
stack.push(b);
}
}
if (op === '$') {
stack.pop();
}
if (op === '.') {
output += ~~stack.pop();
}
if (op === ',') {
var a = stack.pop();
output += String.fromCharCode(a);
}
if (op === 'p') {
var y = stack.pop();
var x = stack.pop();
var v = stack.pop();
v = String.fromCharCode(v);
code[y][x] = v;
}
if (op === 'g') {
var y = stack.pop();
var x = stack.pop();
if (code[y][x]) {
var v = code[y][x].charCodeAt(0);
stack.push(v);
}
}
ptr.moveNext();
//console.log("Ptr: " + ptr.x + "," + ptr.y + "(" + ptr.xv + "," + ptr.yv + ") op: " + op + " Output: \"" + output + "\" Stack size: " + stack.length + " item on top: " + stack[stack.length-1]);
}
var loopCount = 0; // prevent infinite loop
while (op !== '@' && loopCount < 1050) {
//loopCount++;
runCommand();
}
return output;
}
var Pointer = function() {
this.x = 0;
this.y = 0;
this.xv = 0;
this.yv = 0;
this.stop = function() {
this.xv = 0;
this.yv = 0;
}
this.moveUp = function() {
this.xv = 0;
this.yv = -1;
}
this.moveDown = function() {
this.xv = 0;
this.yv = 1;
}
this.moveLeft = function() {
this.xv = -1;
this.yv = 0;
}
this.moveRight = function() {
this.xv = 1;
this.yv = 0;
}
this.moveRandom = function() {
var dir = Math.floor(Math.random() * 4);
if (dir == 0) {
this.moveLeft();
}
if (dir == 1) {
this.moveRight();
}
if (dir == 2) {
this.moveUp();
}
if (dir == 3) {
this.moveDown();
}
}
this.moveNext = function() {
if (this.yv + this.xv == 0) {
this.moveRight();
}
this.x += this.xv;
this.y += this.yv;
}
}
function ProgramCounter() {
this.x = 0;
this.y = 0;
this.directions = {
'up': function() {
this.y -= 1;
},
'down': function() {
this.y += 1
},
'left': function() {
this.x -= 1
},
'right': function() {
this.x += 1
},
};
this.goRight();
}
ProgramCounter.prototype.goRight = function() {
this.direction = 'right'
};
ProgramCounter.prototype.goLeft = function() {
this.direction = 'left'
};
ProgramCounter.prototype.goUp = function() {
this.direction = 'up'
};
ProgramCounter.prototype.goDown = function() {
this.direction = 'down'
};
ProgramCounter.prototype.goRandom = function() {
this.direction = Object.keys(this.directions)[Math.floor(Math.random() * 4)]
};
ProgramCounter.prototype.tick = function() {
this.directions[this.direction].call(this);
};
function Machine(s) {
var code = s.split("\n").map(function(row) {
return row.split("")
});
this.code = code;
this.pc = new ProgramCounter();
this.stack = [];
this.output_buffer = []
}
Machine.prototype.output = function(value) {
if (value === undefined) {
return this.output_buffer;
} else {
this.output_buffer.push(value);
}
}
Machine.prototype.nextInstruction = function() {
return this.getProgramCell(this.pc.x, this.pc.y);
};
Machine.prototype.isEmpty = function() {
return (this.stack.length === 0);
};
Machine.prototype.push = function(value) {
this.stack.push(value);
};
Machine.prototype.pop = function() {
return this.stack.pop();
};
Machine.prototype.setProgramCell = function(x, y, v) {
this.code[y][x] = v;
};
Machine.prototype.getProgramCell = function(x, y) {
return this.code[y][x];
};
Machine.prototype.run = function() {
var digits = "0123456789";
while (true) {
var instruction = this.nextInstruction();
if (digits.indexOf(instruction) >= 0) {
this.push(digits.indexOf(instruction));
} else if (instruction === '+') {
this.push(this.pop() + this.pop());
} else if (instruction === '-') {
var a = this.pop();
var b = this.pop();
this.push(b - a);
} else if (instruction === '*') {
this.push(this.pop() * this.pop());
} else if (instruction === '/') {
var a = this.pop();
var b = this.pop();
this.push((a === 0) ? 0 : (b / a));
} else if (instruction === '%') {
var a = this.pop();
var b = this.pop();
this.push((a === 0) ? 0 : (b % a));
} else if (instruction === '!') {
this.push(this.pop() === 0 ? 1 : 0);
} else if (instruction === '`') {
var a = this.pop();
var b = this.pop();
this.push((b > a) ? 1 : 0);
} else if (instruction === '>') {
this.pc.goRight();
} else if (instruction === '<') {
this.pc.goLeft();
} else if (instruction === '^') {
this.pc.goUp();
} else if (instruction === 'v') {
this.pc.goDown();
} else if (instruction === '?') {
this.pc.goRandom();
} else if (instruction === '_') {
if (this.pop() === 0) {
this.pc.goRight();
} else {
this.pc.goLeft();
}
} else if (instruction === '|') {
if (this.pop() === 0) {
this.pc.goDown();
} else {
this.pc.goUp();
}
} else if (instruction === '"') {
while (true) {
this.pc.tick();
var next = this.nextInstruction();
if (next === '"') {
break;
}
this.push(next.charCodeAt(0));
}
} else if (instruction === ':') {
if (this.isEmpty()) {
this.push(0);
} else {
var value = this.pop();
this.push(value);
this.push(value);
}
} else if (instruction === '\\') {
var a = this.pop();
var b = this.pop();
if (b === undefined) {
b = 0;
}
this.push(a);
this.push(b);
} else if (instruction === '$') {
this.pop();
} else if (instruction === '.') {
this.output(this.pop());
} else if (instruction === ',') {
this.output(String.fromCharCode(this.pop()));
} else if (instruction === '#') {
this.pc.tick();
} else if (instruction === 'p') {
var y = this.pop();
var x = this.pop();
var v = this.pop();
this.setProgramCell(x, y, String.fromCharCode(v));
} else if (instruction === 'g') {
var y = this.pop();
var x = this.pop();
this.push(this.getProgramCell(x, y).charCodeAt(0));
} else if (instruction === '@') {
break;
} else if (instruction === ' ') {} else {
//console.log("Unknown instruction: " + instruction);
break;
}
this.pc.tick();
}
};
function marktriggs(code_string) {
//console.log(code_string);
var machine = new Machine(code_string);
machine.run();
return machine.output().join("");
}
function eugenebulkin(code) {
var a, addDir, b, c, dir, dirs, getValue, l, output, ptr, stack, string_mode, v;
output = "";
code = (function() {
var _i, _len, _ref, _results;
_ref = code.split("\n");
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
l = _ref[_i];
_results.push((l + new Array(81 - l.length).join(' ')).split(''));
}
return _results;
})();
ptr = [0, 0];
dir = [1, 0];
stack = [];
getValue = function(ptr) {
return code[ptr[1]][ptr[0]];
};
addDir = function(ptr) {
ptr[0] = dir[0] + ptr[0] % 79;
ptr[1] = code.length === 1 ? ptr[1] : dir[1] + ptr[1] % code.length;
if (ptr[0] < 0) {
ptr[0] = ptr[0] + 80;
}
if (ptr[1] < 0) {
ptr[1] = ptr[1] + code.length;
}
return ptr;
};
v = null;
a = 0;
b = 0;
c = 0;
string_mode = false;
dirs = [
[0, 1],
[0, -1],
[-1, 0],
[1, 0]
];
while (getValue(ptr) !== '@') {
v = getValue(ptr);
if (string_mode && v !== '"') {
stack.push(v.charCodeAt(0));
ptr = addDir(ptr);
continue;
}
switch (false) {
case v !== '"':
string_mode = !string_mode;
break;
case !v.match(/\d/):
stack.push(parseInt(v, 10));
break;
case !v.match(/[v\^<>\?]/):
a = (function() {
switch (v) {
case "v":
return 0;
case "^":
return 1;
case "<":
return 2;
case ">":
return 3;
case "?":
return~~ (Math.random() * 4);
}
})();
dir = dirs[a];
break;
case v !== ":":
stack.push(stack.length > 0 ? stack[stack.length - 1] : 0);
break;
case v !== "p":
a = stack.pop();
b = stack.pop();
c = stack.pop();
code[a][b] = String.fromCharCode(c);
break;
case !v.match(/[\+\-\*\/\%\`\\g]/):
a = stack.pop();
b = stack.pop();
switch (v) {
case "+":
stack.push(!b ? a : b + a);
break;
case "-":
stack.push(!b ? -a : b - a);
break;
case "*":
stack.push(!b ? 0 : b * a);
break;
case "%":
stack.push(a === 0 || !a ? 0 : b % a);
break;
case "/":
stack.push(a === 0 || !a ? 0 : ~~(b / a));
break;
case "`":
stack.push(~~(b > a));
break;
case "\\":
stack.push(a);
stack.push(b || 0);
break;
case "g":
stack.push(getValue([b, a]).charCodeAt(0));
break;
}
break;
case !v.match(/[\_\!\$\.\,\|]/):
a = stack.pop();
switch (v) {
case "_":
dir = (a === 0 || stack.length === 0 ? [1, 0] : [-1, 0]);
break;
case "|":
dir = (a === 0 || stack.length === 0 ? [0, 1] : [0, -1]);
break;
case "!":
stack.push(a === 0 ? 1 : 0);
break;
case ".":
output += a;
break;
case ",":
output += String.fromCharCode(a);
break;
}
break;
case v !== "#":
ptr = addDir(ptr);
break;
}
ptr = addDir(ptr);
}
return output;
};
function OverZealous(code) {
var output = "",
stack = [],
pop = function() {
return stack.length ? stack.pop() : 0;
},
push = function() {
stack.push.apply(stack, arguments);
},
dir = {
x: 1,
y: 0
},
pos = {
x: 0,
y: 0
},
move = function(d) {
d = d || dir;
pos.x = (pos.x + dir.x) % w;
pos.y = (pos.y + dir.y) % h;
},
getIns = function() {
return code[pos.y][pos.x];
},
// direction changes
cDir = {
'>': {
x: 1,
y: 0
},
'<': {
x: -1,
y: 0
},
'^': {
x: 0,
y: -1
},
'v': {
x: 0,
y: 1
}
},
// stack operations
op = {
'+': function() {
return pop() + pop();
},
'-': function() {
return -(pop()) + pop();
},
'*': function() {
return pop() * pop();
},
'/': function() {
var a = pop(),
b = pop();
return a === 0 ? 0 : Math.floor(b / a);
},
'%': function() {
var a = pop(),
b = pop();
return a === 0 ? 0 : (b % a);
},
'!': function() {
return pop() === 0 ? 1 : 0;
},
'`': function() {
return (pop() <= pop()) ? 1 : 0;
}
},
cont = true,
ins, w, h, a, b, x, y, v;
code = code.split(/\n/);
h = code.length;
w = code.reduce(function(max, row) {
return Math.max(max, row.length);
}, 0);
code = code.map(function(line) {
line = line.split('');
while (line.length < w) line.push(' ');
return line;
});
while (cont) {
ins = getIns();
if (/\d/.test(ins)) {
// decimal 0-9
stack.push(ins | 0);
} else if (cDir[ins]) {
// change direction
dir = cDir[ins];
} else if (op[ins]) {
// perform stack operation
push(op[ins]());
} else switch (ins) {
// miscellaneous instructions
case '?':
if (Math.random() < 0.5) {
dir = {
x: Math.floor(Math.random() * 3) - 1,
y: 0
};
} else {
dir = {
x: 0,
y: Math.floor(Math.random() * 3) - 1
};
}
break;
case '_':
dir = {
x: (pop() === 0 ? 1 : -1),
y: 0
};
break;
case '|':
dir = {
x: 0,
y: (pop() === 0 ? 1 : -1)
};
break;
case '"':
while (true) {
move();
a = getIns();
if (a === '"') {
break;
}
push(a.charCodeAt(0));
}
break;
case ':':
v = pop();
push(v, v);
break;
case '\\':
push(pop(), pop());
break;
case '$':
pop();
break;
case '.':
output += pop();
break;
case ',':
output += String.fromCharCode(pop());
break;
case '#':
move();
break;
case 'p':
x = pop();
y = pop();
v = pop();
code[x][y] = String.fromCharCode(v);
break;
case 'g':
x = pop();
y = pop();
push(code[x][y].charCodeAt(0));
break;
case '@':
cont = false;
break;
}
if (cont) {
move();
}
}
return output;
}
function cadetstar(sCode) {
var tCode = sCode.split(/\n/);
var code = [],
iCode;
var i;
for (i = 0; i < tCode.length; i++) {
iCode = tCode[i].split('');
for (j = 0; j < iCode.length; j++) {
if (code[j] === undefined) {
code[j] = [];
}
code[j][i] = iCode[j];
}
}
var output = "";
var continuing = true;
var curX = 0;
var curY = 0;
var dirX = 1;
var dirY = 0;
var stack = [];
var operA, operB, operC;
var directions = {
'>': [1, 0],
'<': [-1, 0],
'^': [0, -1],
'v': [0, 1]
};
var isStringMode = false;
var skipper;
while (continuing) {
skipper = 1;
if (isStringMode) {
if (code[curX][curY] === '"') {
isStringMode = false;
} else {
stack.push(code[curX][curY].charCodeAt(0));
}
} else {
switch (code[curX][curY]) {
case '+':
stack.push(stack.pop() + stack.pop());
break;
case '-':
stack.push(-1 * stack.pop() + stack.pop());
break;
case '*':
stack.push(stack.pop() * stack.pop());
break;
case '/':
operA = stack.pop();
operB = stack.pop();
if (operA === 0) {
stack.push(0);
} else {
stack.push(Math.floor(operB / operA))
}
break;
case '%':
operA = stack.pop();
operB = stack.pop();
if (operA === 0) {
stack.push(0);
} else {
stack.push(operB % operA);
}
break;
case '!':
stack.push(!stack.pop() ? 1 : 0)
break;
case '`':
stack.push(stack.pop() < stack.pop() ? 1 : 0);
break;
case '<':
case '>':
case '^':
case 'v':
var tester = directions[code[curX][curY]];
// console.log(tester);
dirX = directions[code[curX][curY]][0];
dirY = directions[code[curX][curY]][1];
break;
case '?':
var dir = ['<', '>', '^', 'v'][Math.floor(Math.random() * 4)];
dirX = directions[dir][0];
dirY = directions[dir][1];
break;
case '_':
dirX = ((stack.pop() === 0) ? 1 : -1);
dirY = 0;
break;
case '|':
dirY = ((stack.pop() === 0) ? 1 : -1);
dirX = 0;
break;
case '"':
isStringMode = true;
break;
case ':':
if ( !! stack[stack.length - 1]) {
stack.push(stack[stack.length - 1])
} else {
stack.push(0);
}
break;
case '\\':
operA = stack.pop();
operB = stack.pop() || 0;
stack.push(operA);
stack.push(operB);
break;
case '$':
stack.pop();
break;
case '.':
output += stack.pop();
break;
case ',':
output += String.fromCharCode(stack.pop());
break;
case '#':
skipper = 2;
break;
case 'p':
operA = stack.pop();
operB = stack.pop();
operC = stack.pop();
code[operB][operA] = String.fromCharCode(operC);
break;
case 'g':
operA = stack.pop();
operB = stack.pop();
stack.push(code[operB][operA].charCodeAt(0));
break;
case '@':
continuing = false;
break;
case ' ':
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '0':
stack.push(parseInt(code[curX][curY], 10));
break;
}
}
curX += dirX * skipper;
curY += dirY * skipper;
}
return output;
}
var mholtfoo = function(input) {
var getDir = function(d) {
switch (d) {
case 0:
case 'north':
return [0, -1];
case 1:
case 'east':
return [1, 0];
case 2:
case 'south':
return [0, 1];
case 3:
case 'west':
return [-1, 0];
}
}
var getPos = function(pos, dir) {
return [pos[0] + dir[0], pos[1] + dir[1]];
}
var output = "";
var pos = [0, 0];
var dir = [1, 0];
var stack = [];
var doBreak = false;
var ascii = false;
var code = input.split("\n").map(function(e) {
return e.split("")
});
do {
if (pos[1] >= code.length || pos[0] >= code[pos[1]].length) throw "Index out of bounds (" + pos[0] + ", " + pos[1] + ")";
cCode = code[pos[1]][pos[0]];
if (ascii && cCode == '"') ascii = false;
else if (ascii) stack.unshift(cCode.charCodeAt(0));
else {
switch (cCode = code[pos[1]][pos[0]]) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
stack.unshift(parseInt(cCode, 10));
break;
case '+':
stack.unshift(stack.shift() + stack.shift());
break;
case '-':
var x = stack.shift();
stack.unshift(stack.shift() - x);
break;
case '*':
stack.unshift(stack.shift() * stack.shift());
break;
case '/':
stack.unshift((a = stack.shift()) === 0 ? 0 : Math.floor(stack.shift() / a));
break;
case '%':
stack.unshift((a = stack.shift()) === 0 ? 0 : stack.shift() % a);
break;
case '!':
stack.unshift(stack.shift() === 0 ? 1 : 0);
break;
case '`':
stack.unshift(stack.shift() < stack.shift() ? 1 : 0);
break;
case '>':
dir = getDir('east');
break;
case '<':
dir = getDir('west');
break;
case '^':
dir = getDir('north');
break;
case 'v':
dir = getDir('south');
break;
case '?':
dir = getDir(Math.floor(Math.random() * 4));
break;
case '_':
dir = getDir(stack.shift() == 0 ? 'east' : 'west');
break;
case '|':
dir = getDir(stack.shift() == 0 ? 'south' : 'north');
break;
case '"':
ascii = true;
break;
case ':':
stack.unshift(stack[0] || 0);
break;
case '\\':
var a = stack[0];
stack[0] = stack[1] || 0;
stack[1] = a;
break;
case '$':
stack.shift();
break;
case '.':
output += stack.shift();
break;
case ',':
output += String.fromCharCode(stack.shift());
break;
case '#':
pos = getPos(pos, dir);
break;
case 'p':
code[stack.shift()][stack.shift()] = String.fromCharCode(stack.shift());
break;
case 'g':
stack.unshift(code[stack.shift()][stack.shift()].charCodeAt(0));
break;
case '@':
doBreak = true;
break;
case ' ':
break;
}
}
pos = getPos(pos, dir);
} while (!doBreak);
return output;
}
var pygy = (function() {
var binops, directions, interpret;
binops = {
"+": function(a, b) {
return a + b;
},
"-": function(a, b) {
return b - a;
},
"*": function(a, b) {
return a * b;
},
"/": function(a, b) {
return 0 | b / a;
},
"%": function(a, b) {
return 0 | b % a;
},
"`": function(a, b) {
if (a < b) {
return 1;
} else {
return 0;
}
}
};
directions = {
">": {
dx: 1,
dy: 0
},
"<": {
dx: -1,
dy: 0
},
"^": {
dx: 0,
dy: -1
},
"v": {
dx: 0,
dy: 1
}
};
interpret = function(code) {
var done, dx, dy, len, op, output, stack, x, y, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
code = (code.split("\n")).map(function(s) {
return s.split("");
});
output = "";
stack = [];
_ref = [-1, 0], x = _ref[0], y = _ref[1];
_ref1 = directions[">"], dx = _ref1.dx, dy = _ref1.dy;
done = false;
while (!done) {
op = code[y += dy][x += dx];
switch (op) {
case "0":
case "1":
case "2":
case "3":
case "4":
case "5":
case "6":
case "7":
case "8":
case "9":
stack.push(0 | op);
break;
case "+":
case "-":
case "*":
case "/":
case "%":
case "`":
stack.push(binops[op](stack.pop(), stack.pop()));
break;
case "!":
stack.push(stack.pop() === 0 ? 1 : 0);
break;
case ">":
case "<":
case "^":
case "v":
_ref2 = directions[op], dx = _ref2.dx, dy = _ref2.dy;
break;
case "?":
_ref3 = directions[[">", "<", "^", "v"][0 | Math.random() * 4]], dx = _ref3.dx, dy = _ref3.dy;
break;
case "_":
_ref4 = directions[stack.pop() === 0 ? ">" : "<"], dx = _ref4.dx, dy = _ref4.dy;
break;
case "|":
_ref5 = directions[stack.pop() === 0 ? "v" : "^"], dx = _ref5.dx, dy = _ref5.dy;
break;
case '"':
while ('"' !== (op = code[y += dy][x += dx])) {
stack.push(op.charCodeAt(0));
}
break;
case ":":
stack.push((len = stack.length) ? stack[len - 1] : 0);
break;
case "\\":
if ((len = stack.length) === 1) {
stack.push(0);
} else {
_ref6 = [stack[len - 2], stack[len - 1]], stack[len - 1] = _ref6[0], stack[len - 2] = _ref6[1];
}
break;
case "$":
stack.pop();
break;
case ".":
output += stack.pop();
break;
case ",":
output += String.fromCharCode(stack.pop());
break;
case "#":
_ref7 = [x + dx, y + dy], x = _ref7[0], y = _ref7[1];
break;
case "p":
code[stack.pop()][stack.pop()] = String.fromCharCode(stack.pop());
break;
case "g":
stack.push(code[stack.pop()][stack.pop()].charCodeAt(0));
break;
case " ":
"";
break;
case "@":
done = true;
break;
default:
throw "Invalid operation: " + op;
}
}
return output;
};
return interpret;
})();
Ready to run.
Test | Ops/sec | |
---|---|---|
constablebrew precompiled |
| ready |
xDranik |
| ready |
untrue |
| ready |
marktriggs |
| ready |
eugenebulkin |
| ready |
OverZealous |
| ready |
cadetstar |
| ready |
mholtfoo |
| ready |
pygy |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.