#[oOo CODE](http://esolangs.org/wiki/OOo_CODE)
A very simple interpreter for oOo CODE (first time I use javascript). oOo CODE is an esoteric language based on brainfuck that uses uppercase and lowercase to store it's information, the actual text doesn't matter. As oOo CODE is based on brainfuck, I reused one of the brainfuck answers and added a function to translate oOo CODE to brainfuck.
<!-- begin snippet: js hide: false -->
<!-- language: lang-js -->
var NUM_CELLS = 30000
var ITERS_PER_SEC = 100000
var TIMEOUT_MILLISECS = 5000
var ERROR_BRACKET = "Mismatched brackets"
var ERROR_TIMEOUT = "Timeout"
var ERROR_INTERRUPT = "Interrupted by user"
var code, input, wrap, timeout, eof, loop_stack, loop_map
var running, start_time, code_ptr, input_ptr, cell_ptr, cells, iterations
function clear_output() {
document.getElementById("output").value = ""
document.getElementById("stderr").innerHTML = ""
}
function stop() {
running = false
document.getElementById("run").disabled = false
document.getElementById("stop").disabled = true
document.getElementById("clear").disabled = false
document.getElementById("wrap").disabled = false
document.getElementById("timeout").disabled = false
document.getElementById("eof").disabled = false
}
function interrupt() {
error(ERROR_INTERRUPT)
}
function error(msg) {
document.getElementById("stderr").innerHTML = msg
stop()
}
function oOoCODE(code){
code = code.match(/[a-z]/gi).join('');
code = code.match(/.../g);
for (var i = 0; i<code.length; i++) {
code[i] = [/[A-Z]/.test(code[i][0]),/[A-Z]/.test(code[i][1]),/[A-Z]/.test(code[i][2])];
if (code[i][0]) {
if (code[i][1]) {
if (code[i][2]) {
code[i] = ",";
} else {
code[i] = ".";
}
} else {
if (code[i][2]) {
code[i] = "+";
} else {
code[i] = "-";
}
}
} else {
if (code[i][1]) {
if (code[i][2]) {
code[i] = "]";
} else {
code[i] = "[";
}
} else {
if (code[i][2]) {
code[i] = ">";
} else {
code[i] = "<";
}
}
}
}
return code.join('');
}
function run() {
clear_output()
document.getElementById("run").disabled = true
document.getElementById("stop").disabled = false
document.getElementById("clear").disabled = true
document.getElementById("wrap").disabled = true
document.getElementById("timeout").disabled = true
document.getElementById("eof").disabled = true
code = document.getElementById("code").value
input = document.getElementById("input").value
wrap = document.getElementById("wrap").value
timeout = document.getElementById("timeout").checked
eof = document.getElementById("eof").value
code = oOoCODE(code);
loop_stack = []
loop_map = {}
for (var i = 0; i < code.length; ++i) {
if (code[i] == "[") {
loop_stack.push(i)
} else if (code[i] == "]") {
if (loop_stack.length == 0) {
error(ERROR_BRACKET)
return
} else {
var last_bracket = loop_stack.pop()
loop_map[last_bracket] = i
loop_map[i] = last_bracket
}
}
}
if (loop_stack.length > 0) {
error(ERROR_BRACKET)
return
}
running = true
start_time = Date.now()
code_ptr = 0
input_ptr = 0
cell_ptr = Math.floor(NUM_CELLS / 2)
cells = {}
iterations = 0
bf_iter(1)
}
function bf_iter(niters) {
if (code_ptr >= code.length || !running) {
stop()
return
}
var iter_start_time = Date.now()
for (var i = 0; i < niters; ++i) {
if (cells[cell_ptr] == undefined) {
cells[cell_ptr] = 0
}
switch (code[code_ptr]) {
case "+":
if ((wrap == "8" && cells[cell_ptr] == 255) ||
(wrap == "16" && cells[cell_ptr] == 65535) ||
(wrap == "32" && cells[cell_ptr] == 2147483647)) {
cells[cell_ptr] = 0
} else {
cells[cell_ptr]++
}
break
case "-":
if (cells[cell_ptr] == 0){
if (wrap == "8"){ cells[cell_ptr] = 255 }
if (wrap == "16"){ cells[cell_ptr] = 65535 }
if (wrap == "32"){ cells[cell_ptr] = 2147483647 }
} else {
cells[cell_ptr]--
}
break
case "<": cell_ptr--; break
case ">": cell_ptr++; break
case ".":
document.getElementById("output").value += String.fromCharCode(cells[cell_ptr])
break
case ",":
if (input_ptr >= input.length) {
if (eof != "nochange") {
cells[cell_ptr] = parseInt(eof)
}
} else {
cells[cell_ptr] = input.charCodeAt(input_ptr)
input_ptr++
}
break
case "[":
if (cells[cell_ptr] == 0) {
code_ptr = loop_map[code_ptr]
}
break
case "]":
if (cells[cell_ptr] != 0) {
code_ptr = loop_map[code_ptr]
}
break
}
code_ptr++
iterations++
if (timeout && Date.now() - start_time > TIMEOUT_MILLISECS) {
error(ERROR_TIMEOUT)
return
}
}
setTimeout(function() { bf_iter(ITERS_PER_SEC * (Date.now() - iter_start_time)/1000) }, 0)
}
<!-- language: lang-html -->
<div style="font-size:12px;font-family:Verdana, Geneva, sans-serif;">
<div style="float:left; width:50%;">
Code:
<br>
<textarea id="code" rows="4" style="overflow:scroll;overflow-x:hidden;width:90%;">JuLIeT
O rOMeO, RoMEo! WHeREfOrE art tHoU RoMEo?
DEnY ThY FaTHeR AnD ReFuse ThY NaME;
oR, If ThoU wiLT not, BE but SWoRn mY loVe,
aND i'Ll NO lONgER bE A cAPuLEt.
ROMeO
[AsIdE] ShALl I HEar moRE, or sHAlL I sPEaK At THiS?
JuLIeT
'TiS BUt Thy NamE thAt iS my EneMy;
tHou ARt ThYSeLF, tHOUgH noT a mOntAguE.
whAt's MOnTagUe? iT is Nor HanD, noR foOt,
nOR arm (...) </textarea>
<br>Input:
<br>
<textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;"></textarea>
<p>
Wrap:
<select id="wrap">
<option value="8">8-bit</option>
<option value="16">16-bit</option>
<option value="32">32-bit</option>
</select>
Timeout:
<input id="timeout" type="checkbox" checked="true" /> EOF:
<select id="eof">
<option value="nochange">Same</option>
<option value="0">0</option>
<option value="-1">-1</option>
</select>
</p>
</div>
<div style="float:left; width:50%;">
Output:
<br>
<textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>
<p>
<input id="run" type="button" value="Run" onclick="run()" />
<input id="stop" type="button" value="Stop" onclick="interrupt()" disabled="true" />
<input id="clear" type="button" value="Clear" onclick="clear_output()" />
<span id="stderr" style="color:red"></span>
</p>
</div>
</div>
<!-- end snippet -->