# Question
Title: Making Future Posts Runnable Online with Stack Snippets
Stack Snippets were recently added to PPCG! Reminiscent of JSFiddle, Stack Snippets allow HTML, CSS, and JavaScript to be run ***directly in posts***!

Here is a very simple Stack Snippet:

```
alert('This is JavaScript')
```

```
h3 { color: red } /* This is CSS */
```

```
<h3>This is HTML</h3>
```

This feature of Stack Exchange would be very useful for us *if* languages besides JavaScript were supported. (The answers to challenges could be tested on the spot, example inputs could be generated dynamically, etc.) This is where you come in.

# Challenge

The goal of this challenge is to write an interpreter for some programming language using Stack Snippets and JavaScript. The point is to make something that can be easily copied and used in future PPCG questions and answers.

More or less, you need to create a Stack Snippet that has a "run" button and two textboxes, one for code and one for input. Clicking the run button will execute the code (written in the language you're interpreting) on the input and display the result (probably in another textbox). The snippet should be something akin to cjam.aditsu.net or the sample answer.

For most languages it would make sense for the input and output to represent stdin and sdout respectively, and you might have another input box for the command line. But not all languages have have such traditional I/O mechanisms. HQ9+, for example, doesn't even have input, making a textbox for it pointless. So feel free to take some liberties, design around the language, not this spec. The main requirement is that your language be "runnable" in a Stack Snippet in the accepted sense of the term.

### Notes

* Implementing every single feature of your language, though ideal, is **not** required. Some things like reading and writing files or importing libraries may be unwieldy or impossible. Focus on making an interpreter that maximizes utility for use on this site.
* Posting a "language X to JavaScript" interpreter that you didn't write is ok (with attribution).
* Stack Exchange limits answers to 30,000 characters, so plan accordingly if your interpreter is likely to be long.
* It is best that you make a version of your interpreter as easy as possible to include in future posts. For example, in the sample answer, the raw Markdown for the entire snippet is provided, with obvious places to put code and input.

Although this question is intended to be more a compendium of interpreters than a proper challenge, it is still a , so the highest voted answer wins.

# List of Current Interpreters

(sorted alphabetically by language name)

> 1. Beam
> 2. Befunge-93
> 3. Brainfuck
> 4. Brainfuck
> 5. CHIQRSX9+
> 6. Deadfish
> 7. Deadfish (only runs preset code)
> 8. Fourier
> 9. FRACTRAN
> 10. Hello++
> 11. HQ9+
> 12. Insomnia
> 13. Japt
> 14. JavaScript (sample answer)
> 15. JavaScript ES2015
> 16. Marbelous
> 17. Neoscript
> 18. oOo CODE
> 19. Ouroboros
> 20. Prelude
> 21. Python 2
> 22. STATA
> 23. TI-Basic
> 24. Unary (translates to BF)

*(This question might be better suited for Meta but it will be more visible here. People might actually produce very useful interpreters, I think they deserve the rep for it.)*

# Answer
# Python 2 (No STDIN)

Thanks to Skulpt, it has become very easy to write a Python interpreter.

```
function out(text) {
  var output = document.getElementById("output");
  output.innerHTML = output.innerHTML + text;
}

function builtinRead(x) {
  if(Sk.builtinFiles === undefined || Sk.builtinFiles["files"][x] === undefined)
    throw "File not found: '" + x + "'";
  return Sk.builtinFiles["files"][x];
}

function run() {
  var program = document.getElementById("python-in").value;
  var output = document.getElementById("output");

  output.innerHTML = "";

  Sk.canvas = "canvas";
  Sk.pre = "output";

  Sk.configure({
    output: out,
    read: builtinRead
  });

  try {
    Sk.importMainWithBody("<stdin>", false, program);
  }
  catch(e) {
    throw new Error(e.toString());
  }
}
```

```
#python-in {
  border-radius: 3px;
  background: rgb(250, 250, 250);
  width: 95%;
  height: 200px;
}

#output {
  border-radius: 3px;
  background: lightgray;
  width: 95%;
  height: 200px;
  overflow: auto;
}

#canvas {
  border: 1px solid gray;
  border-radius: 3px;
  height: 400px;
  width: 400px;
}
```

```
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://www.skulpt.org/static/skulpt.min.js"></script>
<script src="http://www.skulpt.org/static/skulpt-stdlib.js"></script>

Python code:<br/>
<textarea id="python-in" name="python-in" rows="10" cols="80"></textarea><br/>
<button id="run-code" onclick="run()">Run</button><br/>
<br/>

Output:<br/>
<pre id="output" name="output" rows="10" cols="10" disabled></pre><br/>

Canvas for turtles:<br/>
<canvas height="400" width="400" id="canvas">Your browser does not support HTML5 Canvas!</canvas>
```

No STDIN, but it's a pretty complete implementation of Python in JS. I would load the libraries from somewhere else but I can't find a host of them.
> 49 votes

# Answer
# Befunge-93

*Edit:* I reworked the entire GUI now. I'm much happier with it. Some kind of breakpoint feature would be cool, but it's probably too much for this. Open Points I will probably revisit:

* Allow an infinite board
* Displaying the stack when stepping through the program would be neat

Since I just implemented this interpreter for this challenge it's not really extensively tested. However, I tried it with a variety of different programs now and it seems to work fine.

The latest version can be found at the latest revision of this fiddle.

```
function BefungeBoard(source, constraints) {
    constraints = constraints || {
        width: 80,
        height: 25
    };

    this.constraints = constraints;
    this.grid = source.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/).map(function (line) {
        return (line + String.repeat(' ', constraints.width - line.length)).split('');
    });
    for (var i = this.grid.length; i < constraints.height; i++) {
        this.grid[i] = String.repeat(' ', constraints.width).split('');
    }

    this.pointer = {
        x: 0,
        y: 0
    };

    this.direction = Direction.RIGHT;
}

BefungeBoard.prototype.nextPosition = function () {
    var vector = this.direction.toVector(),
        nextPosition = {
            x: this.pointer.x + vector[0],
            y: this.pointer.y + vector[1]
        };

    nextPosition.x = nextPosition.x < 0 ? this.constraints.width - 1 : nextPosition.x;
    nextPosition.y = nextPosition.y < 0 ? this.constraints.height - 1 : nextPosition.y;

    nextPosition.x = nextPosition.x >= this.constraints.width ? 0 : nextPosition.x;
    nextPosition.y = nextPosition.y >= this.constraints.height ? 0 : nextPosition.y;

    return nextPosition;
};

BefungeBoard.prototype.advance = function () {
    this.pointer = this.nextPosition();
    if (this.onAdvance) {
        this.onAdvance.call(null, this.pointer);
    }
};

BefungeBoard.prototype.currentToken = function () {
    return this.grid[this.pointer.y][this.pointer.x];
};

BefungeBoard.prototype.nextToken = function () {
    var nextPosition = this.nextPosition();
    return this.grid[nextPosition.y][nextPosition.x];
};

var Direction = (function () {
    var vectors = [
        [1, 0],
        [-1, 0],
        [0, -1],
        [0, 1]
    ];

    function Direction(value) {
        this.value = value;
    }

    Direction.prototype.toVector = function () {
        return vectors[this.value];
    };

    return {
        UP: new Direction(2),
        DOWN: new Direction(3),
        RIGHT: new Direction(0),
        LEFT: new Direction(1)
    };
})();

function BefungeStack() {
    this.stack = [];
}

BefungeStack.prototype.pushAscii = function (item) {
    this.pushNumber(item.charCodeAt());
};

BefungeStack.prototype.pushNumber = function (item) {
    if (isNaN(+item)) {
        throw new Error(typeof item + " | " + item + " is not a number");
    }

    this.stack.push(+item);
};

BefungeStack.prototype.popAscii = function () {
    return String.fromCharCode(this.popNumber());
};

BefungeStack.prototype.popNumber = function () {
    return this.stack.length === 0 ? 0 : this.stack.pop();
};

function Befunge(source, constraints) {
    this.board = new BefungeBoard(source, constraints);
    this.stack = new BefungeStack();
    this.stringMode = false;
    this.terminated = false;

    this.digits = "0123456789".split('');
}

Befunge.prototype.run = function () {
    for (var i = 1; i <= (this.stepsPerTick || 10); i++) {
        this.step();
        if (this.terminated) {
            return;
        }
    }

    requestAnimationFrame(this.run.bind(this));
};

Befunge.prototype.step = function () {
    this.processCurrentToken();
    this.board.advance();
};

Befunge.prototype.processCurrentToken = function () {
    var token = this.board.currentToken();
    if (this.stringMode && token !== '"') {
        return this.stack.pushAscii(token);
    }

    if (this.digits.indexOf(token) !== -1) {
        return this.stack.pushNumber(token);
    }

    switch (token) {
        case ' ':
            while ((token = this.board.nextToken()) == ' ') {
                this.board.advance();
            }
            return;
        case '+':
            return this.stack.pushNumber(this.stack.popNumber() + this.stack.popNumber());
        case '-':
            return this.stack.pushNumber(-this.stack.popNumber() + this.stack.popNumber());
        case '*':
            return this.stack.pushNumber(this.stack.popNumber() * this.stack.popNumber());
        case '/':
            var denominator = this.stack.popNumber(),
                numerator = this.stack.popNumber(),
                result;
            if (denominator === 0) {
                result = +prompt("Illegal division by zero. Please enter the result to use:");
            } else {
                result = Math.floor(numerator / denominator);
            }

            return this.stack.pushNumber(result);
        case '%':
            var modulus = this.stack.popNumber(),
                numerator = this.stack.popNumber(),
                result;
            if (modulus === 0) {
                result = +prompt("Illegal division by zero. Please enter the result to use:");
            } else {
                result = Math.floor(numerator / modulus);
            }

            return this.stack.pushNumber(result);
        case '!':
            return this.stack.pushNumber(this.stack.popNumber() === 0 ? 1 : 0);
        case '`':
            return this.stack.pushNumber(this.stack.popNumber() < this.stack.popNumber() ? 1 : 0);
        case '>':
            this.board.direction = Direction.RIGHT;
            return;
        case '<':
            this.board.direction = Direction.LEFT;
            return;
        case '^':
            this.board.direction = Direction.UP;
            return;
        case 'v':
            this.board.direction = Direction.DOWN;
            return;
        case '?':
            this.board.direction = [Direction.RIGHT, Direction.UP, Direction.LEFT, Direction.DOWN][Math.floor(4 * Math.random())];
            return;
        case '_':
            this.board.direction = this.stack.popNumber() === 0 ? Direction.RIGHT : Direction.LEFT;
            return;
        case '|':
            this.board.direction = this.stack.popNumber() === 0 ? Direction.DOWN : Direction.UP;
            return;
        case '"':
            this.stringMode = !this.stringMode;
            return;
        case ':':
            var top = this.stack.popNumber();
            this.stack.pushNumber(top);
            return this.stack.pushNumber(top);
        case '\\':
            var first = this.stack.popNumber(),
                second = this.stack.popNumber();
            this.stack.pushNumber(first);
            return this.stack.pushNumber(second);
        case '$':
            return this.stack.popNumber();
        case '#':
            return this.board.advance();
        case 'p':
            return this.board.grid[this.stack.popNumber()][this.stack.popNumber()] = this.stack.popAscii();
        case 'g':
            return this.stack.pushAscii(this.board.grid[this.stack.popNumber()][this.stack.popNumber()]);
        case '&':
            return this.stack.pushNumber(+prompt("Please enter a number:"));
        case '~':
            return this.stack.pushAscii(prompt("Please enter a character:")[0]);
        case '.':
            return this.print(this.stack.popNumber());
        case ',':
            return this.print(this.stack.popAscii());
        case '@':
            this.terminated = true;
            return;
    }
};

Befunge.prototype.withStdout = function (printer) {
    this.print = printer;
    return this;
};

Befunge.prototype.withOnAdvance = function (onAdvance) {
    this.board.onAdvance = onAdvance;
    return this;
};

String.repeat = function (str, count) {
    var repeated = "";
    for (var i = 1; i <= count; i++) {
        repeated += str;
    }

    return repeated;
};

window['requestAnimationFrame'] = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) {
    window.setTimeout(callback, 1000 / 60);
};

(function () {
    var currentInstance = null;

    function resetInstance() {
        currentInstance = null;
    }

    function getOrCreateInstance() {
        if (currentInstance !== null && currentInstance.terminated) {
            resetInstance();
        }

        if (currentInstance === null) {
            var boardSize = Editor.getBoardSize();
            currentInstance = new Befunge(Editor.getSource(), {
                width: boardSize.width,
                height: boardSize.height
            });
            currentInstance.stepsPerTick = Editor.getStepsPerTick();

            currentInstance.withStdout(Editor.append);
            currentInstance.withOnAdvance(function (position) {
                Editor.highlight(currentInstance.board.grid, position.x, position.y);
            });
        }

        return currentInstance;
    }

    var Editor = (function (onExecute, onStep, onReset) {
        var source = document.getElementById('source'),
            sourceDisplay = document.getElementById('source-display'),
            sourceDisplayWrapper = document.getElementById('source-display-wrapper'),
            stdout = document.getElementById('stdout');
        var execute = document.getElementById('execute'),
            step = document.getElementById('step'),
            reset = document.getElementById('reset');
        var boardWidth = document.getElementById('board-width'),
            boardHeight = document.getElementById('board-height'),
            stepsPerTick = document.getElementById('steps-per-tick');

        function showEditor() {
            source.style.display = "block";
            sourceDisplayWrapper.style.display = "none";
            source.focus();
        }

        function hideEditor() {
            source.style.display = "none";
            sourceDisplayWrapper.style.display = "block";

            var computedHeight = getComputedStyle(source).height;
            sourceDisplayWrapper.style.minHeight = computedHeight;
            sourceDisplayWrapper.style.maxHeight = computedHeight;

            sourceDisplay.textContent = source.value;
        }

        function resetOutput() {
            stdout.value = null;
        }

        function escapeEntities(input) {
            return input.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
        }

        sourceDisplayWrapper.onclick = function () {
            resetOutput();
            showEditor();
            onReset && onReset.call(null);
        };
        execute.onclick = function () {
            resetOutput();
            hideEditor();
            onExecute && onExecute.call(null);
        };
        step.onclick = function () {
            hideEditor();
            onStep && onStep.call(null);
        };
        reset.onclick = function () {
            resetOutput();
            showEditor();
            onReset && onReset.call(null);
        };

        return {
            getSource: function () {
                return source.value;
            },

            append: function (content) {
                stdout.value = stdout.value + content;
            },

            highlight: function (grid, x, y) {
                var highlighted = [];
                for (var row = 0; row < grid.length; row++) {
                    highlighted[row] = [];
                    for (var column = 0; column < grid[row].length; column++) {
                        highlighted[row][column] = escapeEntities(grid[row][column]);
                    }
                }

                highlighted[y][x] = '<span class="activeToken">' + highlighted[y][x] + '</span>';
                sourceDisplay.innerHTML = highlighted.map(function (lineTokens) {
                    return lineTokens.join('');
                }).join('\n');
            },

            getBoardSize: function () {
                return {
                    width: +boardWidth.innerHTML,
                    height: +boardHeight.innerHTML
                };
            },

            getStepsPerTick: function () {
                return +stepsPerTick.innerHTML;
            }
        };
    })(function () {
        getOrCreateInstance().run();
    }, function () {
        getOrCreateInstance().step();
    }, resetInstance);
})();
```

```
.container {
    width: 100%;
}
.so-box {
    font-family:'Helvetica Neue', Arial, sans-serif;
    font-weight: bold;
    color: #fff;
    text-align: center;
    padding: .3em .7em;
    font-size: 1em;
    line-height: 1.1;
    border: 1px solid #c47b07;
    -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3), 0 2px 0 rgba(255, 255, 255, 0.15) inset;
    text-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
    background: #f88912;
    box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3), 0 2px 0 rgba(255, 255, 255, 0.15) inset;
}
.control {
    display: inline-block;
    border-radius: 6px;
    float: left;
    margin-right: 25px;
    cursor: pointer;
}
.option {
    padding: 10px 20px;
    margin-right: 25px;
    float: left;
}
input, textarea {
    box-sizing: border-box;
}
textarea {
    display: block;
    white-space: pre;
    overflow: auto;
    height: 75px;
    width: 100%;
    max-width: 100%;
    min-height: 25px;
}
span[contenteditable] {
    padding: 2px 6px;
    background: #cc7801;
    color: #fff;
}
#controls-container, #options-container {
    height: auto;
    padding: 6px 0;
}
#stdout {
    height: 50px;
}
#reset {
    float: right;
}
#source-display-wrapper {
    display: none;
    width: 100%;
    height: 100%;
    overflow: auto;
    border: 1px solid black;
    box-sizing: border-box;
}
#source-display {
    font-family: monospace;
    white-space: pre;
    padding: 2px;
}
.activeToken {
    background: #f88912;
}
.clearfix:after {
    content:".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}
.clearfix {
    display: inline-block;
}
* html .clearfix {
    height: 1%;
}
.clearfix {
    display: block;
}
```

```
<div class="container">
    <textarea id="source" placeholder="Enter your Befunge-93 program here" wrap="off">"39-egnufeB">:#,_@</textarea>
    <div id="source-display-wrapper">
        <div id="source-display"></div>
    </div>
</div>
<div id="controls-container" class="container clearfix">
    <input type="button" id="execute" class="control so-box" value="► Execute" />
    <input type="button" id="step" class="control so-box" value="Step" />
    <input type="button" id="reset" class="control so-box" value="Reset" />
</div>
<div id="stdout-container" class="container">
    <textarea id="stdout" placeholder="Output" wrap="off" readonly></textarea>
</div>
<div id="options-container" class="container">
    <div class="option so-box">Steps per Tick: <span id="steps-per-tick" contenteditable>500</span>

    </div>
    <div class="option so-box">Board Size: <span id="board-width" contenteditable>80</span> x <span id="board-height" contenteditable>25</span>

    </div>
</div>
```
> 33 votes

# Answer
# TI-BASIC

'cause who doesn't like TI-Basic?

I wanted to contribute to this, so I picked a language that is (in my humble opinion) *slightly* more complicated than, say, Deadfish, but within my control. I know a lot about my calculator, so I picked this.

I don't however, have any background experience with JavaScript/CSS/HTML. This was my first program. That means...

**Please point out the errors you find in my code!**

That being said, this is a limited version of TI-Basic. I will continue to implement things as I get around to them.

## Features as of right now

* common control keywords (if,then,else,end)
* All available loops (while, repeat, for)
* disp command
* JavaScript arithmetic operators, via eval
* Lists
* Built in auto colon-ator (see for yourself)
* Random values of uninitialized variables, just like your calculator
* limited math - sin,cos,tan,asin,acos,atan,sinh,cosh,tanh,log,ln,int,round,abs.
* constants pi and e as variables
* Prompt, input, pause (Yay!)
* writes to output during execution (thanks to pseudonym117)
* simple pixel-on/off / clear screen capabilities

## Liberties taken

* supports multi-character variable names. Unfortunately, this means `ab` is a variable, not the value `a*b`. This uni-character variable name limit drove me crazy on my calculator.
* ignoring "goto" and "lbl". They were buggy even on the calculator unless you did it a certain way.
* Going to ignore prgm, OpenLib and ExecLib because there are no external/other files

## What still needs to be done

* ~~Some sort of canvas for drawing (coming soon!)~~ More drawing stuff
* ~~Some way for `prompt` and `input` commands in the text window (suggestions, anyone?)~~
* Support for (the rest of) calculator math operations (there's BUCKETS)
* Suppot for `Ans` keyword shenanigans.
* Support for rest of CTL keywords
* Some way to support a form of getkey, though most languages nowadays are event driven... Perhaps it could be the last pressed key.
* ~~I don't know if this is true, but JavaScript seems to think first, then display to a textarea, rather than display as it goes.~~
* There's no CSS/HTML prettiness

I still don't know much about JavaScript. If any of the above are possible/impossible, please let me know.

```
function inputChanged() {
    var codeText = document.getElementById('code-block');
    if (codeText.value.charAt(0) !== ':') {
        codeText.value = ':' + codeText.value;
    }
    var cursor = codeText.selectionEnd;
    if (lastText.length < codeText.value.length) { //adding characters
        if (/(\n)$/.test(codeText.value) === true || /(\n)(\n)/.test(codeText.value) === true) {
            cursor++;
        }
        codeText.value = codeText.value.replace(/(\n)$/, '\n:');
        codeText.value = codeText.value.replace(/(\n)(\n)/, '\n:\n');
    } else { //removing characters
        if (/(\n)$/.test(codeText.value) === true || /(\n)(\n)/.test(codeText.value) === true) {
            cursor--;
        }
        codeText.value = codeText.value.replace(/(\n)$/, '');
        codeText.value = codeText.value.replace(/(\n)(\n)/, '\n');
    }
    codeText.setSelectionRange(cursor, cursor);
    lastText = codeText.value;
}
function onUserInput(e){
    var output = document.getElementById('output');
    //enter has code 13
    if(awaitingInput && e.keyCode===13){
        var lines = output.value.split('\n');
        var input = lines[lines.length-1];
        if(input.indexOf('?')!==-1){
            input = input.substring(input.indexOf('?')+1,input.length);
        }
        if(newInputVarName !== null){
            var iValue = replaceVars(input);
            variables[newInputVarName]= eval(iValue);
        }else{
           output.value = output.value.substring(0,output.value.length-1);
        }
        awaitingInput = false;
    }
}
var lastText = ':';
var L1 = [],
    L2 = [],
    L3 = [],
    L4 = [],
    L5 = [],
    L6 = []; //note - these are special. They're like variables, and are considered in replaceVars.
var tokens = [':', '-->', 'if', 'then',
    'else', 'for', 'while', ',',
    'repeat', 'end', 'disp','prompt','input',
    'pause','pxl-on','pxl-off','clrdraw'];
var variables = [];
var loopStack = []; //holds line numbers
var ifStack = [true]; //holds true or false
var typeStack = ['if'];
var repeatStack = []; //holds current iteration for repeats. NOTE: starts at 1 to accomidate repeat 0
var awaitingInput = false;
var newInputVarName=null;
var pixels = []; //96*64
var running = false;
var lineProcessing;
function run() {
    if(running===false){
        for(var pixelX=0;pixelX<96;pixelX++){
            for(var pixelY=0;pixelY<64;pixelY++){
                pixels[(pixelX,pixelY)]=0;         //doesn't work
            }
        }
        variables = [];
        loopStack = [];
        ifStack = [true];
        typeStack = ['if'];
        repeatStack = [];
        clear();
        var code = document.getElementById('code-block');
        var lines = code.value.split('\n');
        var currentLine = 0;
        variables['e'] = Math.E;
        variables['pi'] = Math.PI;
        L1.push(3);
        L1.push(4);
        lineProcessing = setInterval(function(){
            if(!awaitingInput){
                running = true;
                if(currentLine < lines.length || loopStack.length !== 0){
                    currentLine = processLine(lines,currentLine);
                    currentLine++;
                }
                else{
                    running = false;
                    lineProcessing.clearInterval();
                }
            }
        },10);
    }
}
function processLine(lines, currentLine) {
    var tokens = tokenize(lines[currentLine]);
    if (ifStack[ifStack.length - 1] === true){
        if (tokens.indexOf('-->') !== -1) {
            var index = tokens.indexOf('-->');
            for (var i = 0; i < index; i++) {
                tokens[i] = replaceVars(tokens[i]);
            }
            var value = eval(tokens[index - 1]);
            var name = tokens[index + 1];
            var listElement = false;
            if (name.length > 4) {
                if (/L[1-6]\(/.test(name) === true) {
                    var nextP = matchParenthese(name, 2);
                    var innerStuff = name.substring(3, nextP);
                    var value2 = eval(replaceVars(innerStuff));
                    var listNum = name.substring(0, 2);
                    if (value2 === Math.round(value2)) {
                        if (value2 > 0) {
                            if (listNum === 'L1') {
                                L1[value2] = value;
                            }
                            if (listNum === 'L2') {
                                L2[value2] = value;
                            }
                            if (listNum === 'L3') {
                                L3[value2] = value;
                            }
                            if (listNum === 'L4') {
                                L4[value2] = value;
                            }
                            if (listNum === 'L5') {
                                L5[value2] = value;
                            }
                            if (listNum === 'L6') {
                                L6[value2] = value;
                            }
                        } else {
                            printE('Arrays can only have positive indexes, and by some weird quirk of Texas Instruments, indexes start at 1, not 0.');
                            throw new Error();
                        }
                    } else {
                        printE('Sorry, this is not Javascript. Array indexes must be integers.');
                        throw new Error();
                    }
                }
            }
            variables[name + ""] = value;
        }
        if (tokens.indexOf('disp') !== -1) {
            var index2 = tokens.indexOf('disp');
            for (var g = index2 + 1; g < tokens.length; g++) {
                tokens[g] = replaceVars(tokens[g]);
                if (tokens[g] === ',') {} else {
                    print(eval(tokens[g]));
                }
            }
        }
        if(tokens.indexOf('prompt')!==-1){
            var pIndex = tokens.indexOf('prompt');
            var newVar = tokens[pIndex+1];
            document.getElementById('output').value += newVar+'=?';
            awaitingInput=true;
            newInputVarName = newVar;
        }
        if(tokens.indexOf('input')!==-1){
            var pIndex = tokens.indexOf('input');
            var newVar = tokens[pIndex+1];
            document.getElementById('output').value += '?';
            awaitingInput=true;
            newInputVarName = newVar;
        }
        if(tokens.indexOf('pause')!==-1){
            awaitingInput=true;
            newInputVarName = null;
        }
        if(tokens.indexOf('pxl-on')!==-1){
            var first = tokens[2].substring(1,tokens[2].length);
            var second = tokens[4].substring(0,tokens[4].length-1);
            first = replaceVars(first);
            second = replaceVars(second);
            var valueF = eval(first);
            var valueS = eval(second);
            drawPixel(valueF,valueS,1);
            pixels[(valueF,valueS)] = 1;
        }
        if(tokens.indexOf('pxl-off')!==-1){
            var first2 = tokens[2].substring(1,tokens[2].length);
            var second2 = tokens[4].substring(0,tokens[4].length-1);
            first2 = replaceVars(first2);
            second2 = replaceVars(second2);
            var valueF2 = eval(first2);
            var valueS2 = eval(second2);
            pixels[(valueF2,valueS2)] = 0;
            drawPixel(valueF2,valueS2,0);
        }
        if(tokens.indexOf('clrdraw')!==-1){
            clearPixels();
        }
        if (tokens.indexOf('if') !== -1) {
            var index3 = tokens.indexOf('if');
            tokens[index3 + 1] = replaceVars(tokens[index3 + 1]);
            var value = eval(tokens[index3 + 1]);
            ifStack.push(value);
            typeStack.push('if');
        }
        if (tokens.indexOf('while') !== -1) {
            var index4 = tokens.indexOf('while');
            var expression = tokens[index4 + 1];
            expression = replaceVars(expression);
            var value2 = eval(expression);
            if (value2 === true) {
                typeStack.push('while');
                loopStack.push(currentLine);
            } else {
                currentLine = nextEnd(currentLine, lines);
                return currentLine;
            }
        }
        if (tokens.indexOf('for') !== -1) {
            var index5 = tokens.indexOf('for');
            var varName = tokens[index5 + 1];
            varName = varName.trim();
            varName = varName.substring(1, varName.length);
            var initValue = eval(replaceVars(tokens[index5 + 3]));
            variables[varName] = initValue;
            var endingValue = eval(replaceVars(tokens[index5 + 5]));
            var increaseVal = replaceVars(tokens[index5 + 7]);
            increaseVal = eval(increaseVal.substring(0, increaseVal.length - 1));
            var diff = endingValue - initValue;
            if (sign(diff) !== sign(increaseVal) && sign(diff) !== 0) {
                currentLine = nextEnd(currentLine, lines);
                return currentLine;
            } else {
                loopStack.push(currentLine);
                typeStack.push('for');
            }
        }
        if (tokens.indexOf('repeat') !== -1) {
            var repeatVal = eval(replaceVars(tokens[1]));
            if (repeatVal === true || repeatVal === false) {
                //basically the same as a while loop...so just replace it!
                var newLine = 'while ' + '!(' + tokens[1] + ')';
                lines[currentLine] = newLine;
                currentLine--;
                return currentLine;
            } else {
                repeatStack.push(0);
                typeStack.push('repeat');
                loopStack.push(currentLine);
            }
        }
    }
    if (tokens.indexOf('else') !== -1) {
       ifStack[ifStack.length - 1] = !ifStack[ifStack.length - 1];
    }
    if (tokens.indexOf('end') !== -1) {
        if (typeStack[typeStack.length - 1] === 'if') {
            ifStack.pop();
            typeStack.pop();
        } else if (typeStack[typeStack.length - 1] === 'while') {
            var prevLineNum = loopStack[loopStack.length - 1];
            var prevLine = lines[prevLineNum];
            var prevTokens = tokenize(prevLine);
            var whileIndex = prevTokens.indexOf('while');
            var expression2 = replaceVars(prevTokens[whileIndex + 1]);
            if (eval(expression2) === true) {
                currentLine = prevLineNum - 1;
                return currentLine;
            } else {
                loopStack.pop();
                typeStack.pop();
            }
        } else if (typeStack[typeStack.length - 1] === 'repeat') {
            var line = lines[loopStack[loopStack.length - 1]];
            var tokenized = tokenize(line);
            var numTimes = eval(replaceVars(tokenized[1]));
            var currentIteration = repeatStack[repeatStack.length - 1];
            currentIteration++;
            if (currentIteration !== numTimes) {
                repeatStack[repeatStack.length - 1] = currentIteration;
                currentLine = loopStack[loopStack.length - 1]; //once currentLine++, will be on next line after repeat;
                return currentLine;
            } else {
                repeatStack.pop();
                typeStack.pop();
                loopStack.pop();
            }
        } else if (typeStack[typeStack.length - 1] === 'for') {
            var prevLineNum2 = loopStack[loopStack.length - 1];
            var prevLine2 = lines[prevLineNum2];
            var prevTokens2 = tokenize(prevLine2);
            var forIndex = prevTokens2.indexOf('for');
            var varName2 = prevTokens2[forIndex + 1];
            varName2 = varName2.substring(1, varName2.length);
            var initVal = eval(replaceVars(prevTokens2[forIndex + 3]));
            var endVal = eval(replaceVars(prevTokens2[forIndex + 5]));
            var stepVal = replaceVars(prevTokens2[forIndex + 7]);
            stepVal = eval(stepVal.substring(0, stepVal.length - 1));
            variables[varName2] = parseInt(stepVal, 10) + parseInt(variables[varName2], 10);
            var signDiff = sign(endVal - initVal);
            var condTrue = true;
            if (signDiff === 0) {
                condTrue = false;
            }
            if (signDiff === 1) {
                if (variables[varName2] > endVal) {
                    condTrue = false;
                }
            } else {
                if (variables[varName2] < endVal) {
                    condTrue = false;
                }
            }
            if (condTrue === true) {
                currentLine = prevLineNum2;
                return currentLine;
            } else {
                typeStack.pop();
                loopStack.pop();
            }
        }
    }
    return currentLine;
}

function sign(num) {
    if (num === 0) {
        return 0;
    }
    if (num > 0) {
        return 1;
    }
    return -1;
}
function drawPixel(x,y,color){//color = 0 if off, 1 if on
    var canvas = document.getElementById('canvas');
    var width = canvas.width;
    var height = canvas.height;
    var pxWidth = width/96;
    var pxHeight = height/64;
    var ctx = canvas.getContext('2d');
    if(color===1){
        ctx.fillStyle = '#000';
    }else{
        ctx.fillStyle = '#fff';
    }
    ctx.fillRect((x/96)*width, (y/64)*height,pxWidth,pxHeight);
}
function nextEnd(line, lines) {
    for (var i = line + 1; i < lines.length; i++) {
        if (lines[i].indexOf('end') !== -1) {
            return i;
        }
    }
    return line;
}

function tokenize(line) {
    line = line.trim();
    var split = [];
    var currentSplit = '';
    var cursor = 0;
    var unknown = '';
    var allTokens = tokens;
    while (cursor < line.length) {
        var lengthOfCursor = line.length - cursor;
        while (lengthOfCursor > 0) {
            var index = allTokens.indexOf(line.substring(cursor, cursor + lengthOfCursor));
            if (index !== -1) {
                if (unknown !== '') {
                    split.push(unknown.trim());
                }
                unknown = '';
                split.push(allTokens[index]);
                cursor += lengthOfCursor - 1; //for cursor++ later
                break;
            }
            lengthOfCursor--;
            if (lengthOfCursor === 0) {
                unknown = unknown.concat(line.charAt(cursor));
            }
        }
        cursor++;
    }
    if (unknown !== '') {
        split.push(unknown.trim());
    }
    return split;
}

function replaceVars(token) {
    for (var i = 0; i < tokens.length; i++) {
        if (token === tokens[i]) {
            return token;
        }
    }
    //deals with lists
    for (var cursor = 0; cursor < token.length - 1; cursor++) {
        if (/[^a-zA-Z_]L[1-6]|^L[1-6]/.test(token.substring(cursor, cursor + 3)) === true) {
            var parenthIndex;
            for (var newCurs = cursor; newCurs < token.length; newCurs++) {
                if (token.charAt(newCurs) === '(') {
                    parenthIndex = newCurs;
                    break;
                }
            }
            var nextPIndex = matchParenthese(token, parenthIndex);
            var inner = token.substring(parenthIndex + 1, nextPIndex);
            //note recursiveness, supports L1(L1(L1(5))), for example
            var innerValue = eval(replaceVars(inner));
            var num = parseInt(token.substring(parenthIndex - 1, parenthIndex));
            var realValue;
            if (num === 1) {
                realValue = L1[innerValue];
            }
            if (num === 2) {
                realValue = L2[innerValue];
            }
            if (num === 3) {
                realValue = L3[innerValue];
            }
            if (num === 4) {
                realValue = L4[innerValue];
            }
            if (num === 5) {
                realValue = L5[innerValue];
            }
            if (num === 6) {
                realValue = L6[innerValue];
            }
            if (innerValue !== Math.round(innerValue) || innerValue < 1) {
                printE('array indexes must be integers greater or equal to 1. Why? ask Texas Instruments.');
                throw new Error();
            }
            token = token.substring(0, parenthIndex - 2) + realValue + token.substring(nextPIndex + 1);
        }
    }
    //Math stuff
    var a;
    var sinFunc = function (value) {
        return Math.sin(value);
    };
    while ((a = returnValue('sin', token, sinFunc)) !== null) {
        token = a;
    }

    var cosFunc = function (value) {
        return Math.cos(value);
    };
    while ((a = returnValue('cos', token, cosFunc)) !== null) {
        token = a;
    }

    var tanFunc = function (value) {
        return Math.tan(value);
    };
    while ((a = returnValue('tan', token, tanFunc)) !== null) {
        token = a;
    }

    var asinFunc = function (value) {
        return Math.asin(value);
    };
    while ((a = returnValue('asin', token, asinFunc)) !== null) {
        token = a;
    }

    var acosFunc = function (value) {
        return Math.acos(value);
    };
    while ((a = returnValue('acos', token, acosFunc)) !== null) {
        token = a;
    }

    var atanFunc = function (value) {
        return Math.atan(value);
    };
    while ((a = returnValue('atan', token, atanFunc)) !== null) {
        token = a;
    }
    //note my calculator doesn't have atan2...

    var absFunc = function (value) {
        return Math.abs(value);
    };
    while ((a = returnValue('abs', token, absFunc)) !== null) {
        token = a;
    }

    var roundFunc = function (value) {
        return Math.round(value);
    };
    while ((a = returnValue('round', token, roundFunc)) !== null) {
        token = a;
    }

    var intFunc = function (value) {
        return Math.floor(value);
    };
    while ((a = returnValue('int', token, intFunc)) !== null) {
        token = a;
    }

    var coshFunc = function (value) {
        return (Math.pow(Math.E, value) + Math.pow(Math.E, -1 * value)) / 2;
    };
    while ((a = returnValue('cosh', token, coshFunc)) !== null) {
        token = a;
    }

    var sinhFunc = function (value) {
        return (Math.pow(Math.E, value) - Math.pow(Math.E, -1 * value)) / 2;
    };
    while ((a = returnValue('sinh', token, sinhFunc)) !== null) {
        token = a;
    }

    var tanhFunc = function (value) {
        return (Math.pow(Math.E, value) - Math.pow(Math.E, -1 * value)) / (Math.pow(Math.E, value) + Math.pow(Math.E, -1 * value));
    };
    while ((a = returnValue('tanh', token, tanhFunc)) !== null) {
        token = a;
    }

    //if token contains new variables, then initialize them with random values
    var newReg = new RegExp('([^a-zA-Z_])([a-zA-Z_]+)([^a-zA-Z_])', 'g');
    var newReg2 = new RegExp('^([a-zA-Z_]+)([^a-zA-Z_])', 'g');
    var newReg3 = new RegExp('([^a-zA-Z_])([a-zA-Z_]+)$', 'g');
    var newReg4 = new RegExp('^([a-zA-Z_]+)$', 'g');
    var match1 = token.match(newReg);
    if (match1 !== null) {
        for (var q = 0; q < match1.length; q++) {
            initializeVar(match1[q].substring(1, match1[q].length - 1));
        }
    }

    var match2 = token.match(newReg2);
    if (match2 !== null) {
        for (var w = 0; w < match2.length; w++) {
            initializeVar(match2[w].substring(0, match2[w].length - 1));
        }
    }

    var match3 = token.match(newReg3);
    if (match3 !== null) {
        for (var e = 0; e < match3.length; e++) {
            initializeVar(match3[e].substring(1, match3[e].length));
        }
    }

    var match4 = token.match(newReg4);
    if (match4 !== null) {
        for (var r = 0; r < match4.length; r++) {
            initializeVar(match4[r].substring(0, match4[r].length));
        }
    }

    var varNames = [];
    for (var key in variables) {
        if (token.indexOf(key) !== -1) {
            var regex1 = '([^a-zA-Z_])(' + key + ')([^a-zA-Z_])';
            var reg = new RegExp(regex1, 'g');
            token = token.replace(reg, '$1' + variables[key] + '$3');
            var regex2 = '(^' + key + ')([^a-zA-Z_])';
            var reg2 = new RegExp(regex2, 'g');
            token = token.replace(reg2, variables[key] + '$2');
            var regex3 = '([^a-zA-Z_])(' + key + ')$';
            var reg3 = new RegExp(regex3, 'g');
            token = token.replace(reg3, '$1' + variables[key]);
            var reg4 = new RegExp('^' + key + '$', 'g');
            token = token.replace(reg4, variables[key]);
        }
    }
    return token;
}

function matchParenthese(token, index) {
    var pStack = [];
    for (var cursor = index + 1; cursor < token.length; cursor++) {
        if (token.charAt(cursor) === '(') {
            pStack.push(1);
        }
        if (token.charAt(cursor) === ')') {
            if (pStack.length > 0) {
                pStack.pop();
            } else {
                return cursor;
            }
        }
    }
    return index;
}

function returnValue(identifyer, token, toDoFunction) { //note: do NOT include parentheses in identifyer
    for (var cursor = 0; cursor < token.length; cursor++) {
        if (token.length > cursor + identifyer.length) {
            if (token.substring(cursor, cursor + identifyer.length) === identifyer) {
                if (cursor === 0 || /^[^a-zA-Z_]/.test(token.charAt(cursor - 1)) === true) {
                    if (nextNonWhiteChar(token, cursor + identifyer.length - 1) === '(') {
                        print(identifyer);
                        var nextParen = matchParenthese(token, cursor + identifyer.length + 1);
                        var inner = token.substring(cursor + identifyer.length + 1, nextParen);
                        inner = replaceVars(inner);
                        var value = eval(inner);
                        value = toDoFunction(value);
                        return token.substring(0, cursor) + value + token.substring(nextParen + 1, token.length);
                    }
                }
            }
        }

    }
    return null;
}

function nextNonWhiteChar(token, index) { //give non-white character
    for (var i = index + 1; i < token.length; i++) {
        if (token.charAt(i) !== ' ') {
            return token.charAt(i);
        }
    }
}
function clearPixels(){
    var canvas = document.getElementById('canvas');
    canvas.getContext('2d').fillStyle = '#fff';
    canvas.getContext('2d').fillRect(0,0,canvas.width,canvas.height);
    for(var x=0;x<96;x++){
        for(var y=0;y<64;y++){
            pixels[(x,y)] = 0;
        }
    }
}
function stop(){
    running = false;
    clearInterval(lineProcessing);
}
function initializeVar(name) {
    if (!(name in variables) && name !== 'L1' && name !== 'L2' && name !== 'L3' && name !== 'L4' && name !== 'L5' && name !== 'L6') {
        variables[name] = Math.random() * 100;
    }
}

function clear() {
    document.getElementById('output').value = '';
    document.getElementById('error').value = '';
}

function printE(str) {
    document.getElementById('error').value += str + '\n'
}

function print(str) {
    document.getElementById('output').value += str + '\n';
}
```

```

Ti-Basic Interpreter

Code

<textarea id='code-block' cols='50' rows='7' oninput='inputChanged()'>:clrdraw
:for(a,2,96,2)
:for(b,(a/2)%2,64,2)
:pxl-on(a,b)
:end
:end</textarea>

<button width='20' height='10' onclick='run()'>Run</button>
    <button width='20' height='10' onclick='stop()'>Stop</button>

Output (also input)

    <textarea id='output' cols='50' rows='7' onkeypress='onUserInput(event)'></textarea>

    <canvas id='canvas' width='192' height='128'></canvas>

<textarea id='error' cols='50' rows='7'></textarea>
```
> 33 votes

# Answer
# Brainfuck

Here's a basic BF interpreter. There's no debugger though, but has a couple of customisation options.

```
const NUM_CELLS = 30000;
const ITERS_PER_SEC = 100000;
const TIMEOUT_MILLISECS = 5000;
const ERROR_BRACKET = "Mismatched brackets";
const ERROR_TIMEOUT = "Timeout";
const 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 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;

  loop_stack = [];
  loop_map = {};

  for (var i = 0; i  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 && wrap != "-1"){
          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);
}
```

```

    Code:

    <textarea id="code" rows="4" style="overflow:scroll;overflow-x:hidden;width:90%;">>++++++++[<+++++++++>-]<.>>+>+>++>[-]+<[>[->+<<++++>]<<]>.+++++++..+++.>>+++++++.<<<[[-]<[-]>]<+++++++++++++++.>>.+++.------.--------.>>+.>++++.</textarea>

Input:

    <textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;"></textarea>

      Wrap:
      <select id="wrap">
        <option value="8">8-bit</option>
        <option value="16">16-bit</option>
        <option value="32">32-bit</option>
        <option value="-1">None</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>

    Output:

    <textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>

      <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()" />

```

On my browser everything is contained within the expanded snippet, but I'm no expert on browser compatibility so I can't guarantee that'll be the same for everybody.

## Features

* Cell wrapping and EOF behaviour can be configured
* Timeout can be bypassed
* Program can be halted mid-execution
* A nice little clear button
* All this within the Stack Snippet box (or at least I tried) and clocking in at around 6k chars ungolfed
> 26 votes

# Answer
# Marbelous\*

This interpreter is probably filled with bugs; if you find any, please let me know.

This supports all features of Marbelous except `#include`. There is also an option for using a cylindrical board (marbles shoved off the sides of the board reappear on the other side).

The interpreter also comes with many boards present in the examples in the repo for the python interpreter for Marbelous. These boards are listed below:

```
dec_out.mbl - Dp, Decout
hex_out.mbl - Hp, Hexo
fourwayincrement.mbl - Fwin
threewaysplit.mbl - 3W
bitwise_operations.mbl - Bitx, Bdif, Borr, Band, Bxor, Bnor
logical_operations.mbl - Tf, Nt, Lorr, Land, Lnor, Lxor, Cmpr, Eqal, Gteq, Lteq, Grtr, Less, Sort
replace_input.mbl - Replac
adder.mbl - Plus
arithmetic.mbl - Subt, Subo, Subful, Addo, Addful, Mult
wide_devices.mbl - Wideadditionfunc, Widesubtractfunc, Wbitleft, Wbitrght, Wbitfetchx, Mulx, Doblmult, Widemultiplyfunc

```

No includes should be used. See the python interpreter's repo for details on what each of these boards do.

\*More Information on Marbelous:

Note: Graphical Output (256x256 double buffered with 24-bit RGB color) is available on this interpreter. The following boards may be used for this purpose:

```
{}{}{}{}{} - Set Pixel for Back Buffer (}0 - x, }1 - y, }2 - red, }3 - green, }4 - blue)
>< - Swap Buffers and Clear Back Buffer (}0 - anything)
@f@f@f - Get Pixel from Front Buffer (}0 - x, }1 - y, {0 - red, {1 - green, {2 - blue)
@b@b@b - Get Pixel from Back Buffer (}0 - x, }1 - y, {0 - red, {1 - green, {2 - blue)

```

Please note that having `Use Draw Buffers` checked (required for graphical output) might slow down the interpreter, and that graphical output is slow.

**Update**: changed buffers to use canvas instead of 1x1 pixel divs; drawing should be much faster now.

```
var stdin = "";
var boards = {};
var bnames = [];
var max_tick = 1000;
var space_as_blank = false;
var cylindrical_board = false;
var print_numbers = false;
var libraries = true;
var stopped = false;
var gfx = false;
var front_buffer = null;
var back_buffer = null;
function base36(a){ return a.toString(36).toUpperCase();}
function base16(a){ return ("0"+a.toString(16).toUpperCase()).substr(-2);}
function wto16(arr, i){ return arr[i] << 8 | arr[i+1]; }
function wto32(arr, i){ return arr[i] << 24 | arr[i+1] << 16 | arr[i+2] << 8 | arr[i+3]; }
function getch(){
var p = stdin.substr(0, 1);
stdin = stdin.substr(1);
if(p === '') return -1;
else return p.charCodeAt(0) & 255;
}
function putch(obj, ch){
if(print_numbers)
 obj.stdout += ch + ' ';
else
 obj.stdout += String.fromCharCode(ch);
}
function longestMatch(search, list){
var best = null, blen = 0;
for(var i = 0, len = list.length; i < len; ++i)
 if(list[i].length > blen && search.indexOf(list[i]) === 0)
  best = list[i], blen = best.length;
return best;
}
function swapBuffers(){
front_buffer.ctx.drawImage(back_buffer.canvas, 0, 0);
back_buffer.clear();
}

function jsBoard(name, inc, outc, code){
var f = eval('(function(inp, self){return ' + code + ';})');
boards[name] = new Board(name, true, f, inc, outc);
bnames.push(name);
}
function loadDefaultBoards(){
// implement \\ // /\ \/ ++ -- >> << ~~ ]] +n -n ?? ?n ^n =n >n <n as js boards
jsBoard('\\\\', 1, 0, '{37: inp[0]}');
jsBoard('//', 1, 0, '{36: inp[0]}');
jsBoard('/\\', 1, 0, '{36: inp[0], 37: inp[0]}');
jsBoard('\\/', 1, 0, '{}');
jsBoard('++', 1, 1, '{0: (inp[0]+1)&255}');
jsBoard('--', 1, 1, '{0: (inp[0]+255)&255}');
jsBoard('>>', 1, 1, '{0: inp[0]>>1}');
jsBoard('<<', 1, 1, '{0: (inp[0]<<1)&255}');
jsBoard('~~', 1, 1, '{0: (~inp[0])&255}');
jsBoard(']]', 1, 1, '(c=getch())>-1?{0:c}:{37:inp[0]}');
jsBoard('??', 1, 1, '{0: Math.floor(Math.random()*(inp[0]+1))}');
for(var i = 0; i < 36; ++i){
 j = base36(i);
 jsBoard('+'+j, 1, 1, '{0: (inp[0]+'+i+')&255}');
 jsBoard('-'+j, 1, 1, '{0: (inp[0]-'+i+')&255}');
 jsBoard('?'+j, 1, 1, '{0: Math.floor(Math.random()*'+(i+1)+')}');
 jsBoard('='+j, 1, 1, 'inp[0]=='+i+'?{0: inp[0]}:{37: inp[0]}');
 jsBoard('>'+j, 1, 1, 'inp[0]>'+i+'?{0: inp[0]}:{37: inp[0]}');
 jsBoard('<'+j, 1, 1, 'inp[0]<'+i+'?{0: inp[0]}:{37: inp[0]}');
 if(i < 8){
  jsBoard('^'+j, 1, 1, '{0: !!(inp[0]&(1<<'+i+'))}');
 }
}
if(gfx){
 jsBoard('{}{}{}{}{}', 5, 0, 'back_buffer.set(inp[0], inp[1], inp[2], inp[3], inp[4]),{}');
 jsBoard('@f@f@f', 2, 3, 'front_buffer.get(inp[0], inp[1])');
 jsBoard('@b@b@b', 2, 3, 'back_buffer.get(inp[0], inp[1])');
 jsBoard('><', 1, 0, 'swapBuffers(), {}');
}
if(libraries){
 // dec_out.mbl - Dp, Decout
 jsBoard('Dp', 1, 0, 'putch(self,Math.floor(inp[0]/100)+0x30),putch(self,Math.floor(inp[0]/10)%10+0x30),putch(self,inp[0]%10+0x30),{}');
 jsBoard('Decout', 1, 3, '{0: inp[0]/100, 1: inp[0]/10%10, 2: inp[0]%10}');
 // hex_out.mbl - Hp, Hexo
 jsBoard('Hp', 1, 0, 's=base16(inp[0]),putch(self,s.charCodeAt(0)),putch(self,s.charCodeAt(1)),{}');
 jsBoard('Hexo', 1, 2, 's=base16(inp[0]),{0: s.charCodeAt(0), 1: s.charCodeAt(1)}');
 // fourwayincrement.mbl - Fwin
 jsBoard('Fwin', 1, 2, '{36: inp[0], 0: (inp[0]+1)&255, 1: (inp[0]+1)&255, 37: (inp[0]+2)&255}');
 // threewaysplit.mbl - 3W
 jsBoard('3W', 1, 1, '{0: inp[0], 36: inp[0], 37: inp[0]}');
 // bitwise_operations.mbl - Bitx, Bdif, Borr, Band, Bxor, Bnor
 jsBoard('Bitx', 2, 1, 'inp[1]<8?{0: !!(inp[0] & (1 << inp[1]))}:{}');
 jsBoard('Bdif', 2, 1, 'b=inp[0]^inp[1],{0: !!(b&1)+!!(b&2)+!!(b&4)+!!(b&8)+!!(b&16)+!!(b&32)+!!(b&64)+!!(b&128)}');
 jsBoard('Borr', 2, 1, '{0: inp[0]|inp[1]}');
 jsBoard('Band', 2, 1, '{0: inp[0]&inp[1]}');
 jsBoard('Bxor', 2, 1, '{0: inp[0]^inp[1]}');
 jsBoard('Bnor', 2, 1, '{0: ~(inp[0]|inp[1])}');
 // logical_operations.mbl - Tf, Nt, Lorr, Land, Lnor, Lxor, Cmpr, Eqal, Gteq, Lteq, Grtr, Less, Sort
 jsBoard('Tf', 1, 1, '{0: (inp[0]>0)|0}');
 jsBoard('Nt', 1, 1, '{0: (!inp[0])|0}');
 jsBoard('Lorr', 2, 1, '{0: (inp[0]||inp[1])|0}');
 jsBoard('Land', 2, 1, '{0: (inp[0]&&inp[1])|0}');
 jsBoard('Lnor', 2, 1, '{0: !(inp[0]||inp[1])|0}');
 jsBoard('Lxor', 2, 1, '{0: (!inp[0]!=!inp[1])|0}');
 jsBoard('Cmpr', 2, 1, '{0: inp[0]>inp[1]?1:inp[0]<inp[1]?-1:0}');
 jsBoard('Eqal', 2, 1, '{0: (inp[0] == inp[1])|0}');
 jsBoard('Gteq', 2, 1, '{0: (inp[0] >= inp[1])|0}');
 jsBoard('Lteq', 2, 1, '{0: (inp[0] <= inp[1])|0}');
 jsBoard('Grtr', 2, 1, '{0: (inp[0] > inp[1])|0}');
 jsBoard('Less', 2, 1, '{0: (inp[0] < inp[1])|0}');
 jsBoard('Sort', 2, 2, '{0: Math.min(inp[0],inp[1]), 1: Math.max(inp[0],inp[1])}');
 // replace_input.mbl - Replac
 jsBoard('Replac', 3, 1, '{0: inp[0]==inp[1]?inp[2]:inp[0]}');
 // adder.mbl - Plus
 jsBoard('Plus', 2, 1, '{0: (inp[0] + inp[1])&255}');
 // arithmetic.mbl - Subt, Subo, Subful, Addo, Addful, Mult
 jsBoard('Subt', 2, 1, '{0: (inp[0] - inp[1])&255}');
 jsBoard('Subo', 2, 1, '{0: (inp[0] - inp[1])&255, 36: (inp[0] < inp[1])|0}');
 jsBoard('Subful', 3, 1, 'a=(inp[0] - inp[1])&255,{0: (a + 256 - inp[2])&255, 36: (inp[0]<inp[1])+(a<inp[2])}');
 jsBoard('Addo', 2, 1, 'a=inp[0]+inp[1],{0: a&255, 36: (a>255)|0}');
 jsBoard('Addful', 3, 1, 'a=inp[0]+inp[1]+inp[2],{0: a&255, 36: (a>255)|0}');
 jsBoard('Mult', 2, 1, '{0: (inp[0]*inp[1])&255}');
 // wide_devices.mbl - Wideadditionfunc, Widesubtractfunc, Wbitleft, Wbitrght, Wbitfetchx, Mulx, Doblmult, Widemultiplyfunc
 jsBoard('Wideadditionfunc', 8, 4, 'c=(wto32(inp,0)+wto32(inp,4))&0xFFFFFFFF,{0:  (c&0xFF000000)>>>24, 1: (c&0x00FF0000)>>>16, 2: (c&0x0000FF00)>>>8, 3: (c&0x000000FF)}');
 jsBoard('Widesubtractfunc', 8, 4, 'c=(wto32(inp,0)-wto32(inp,4))&0xFFFFFFFF,{0: (c&0xFF000000)>>>24, 1: (c&0x00FF0000)>>>16, 2: (c&0x0000FF00)>>>8, 3: (c&0x000000FF)}');
 jsBoard('Wbitleft', 4, 4, 'c=(wto32(inp,0)<<1)&0xFFFFFFFF,{0: (c&0xFF000000)>>>24, 1: (c&0x00FF0000)>>>16, 2: (c&0x0000FF00)>>>8, 3: (c&0x000000FF)}');
 jsBoard('Wbitrght', 4, 4, 'c=wto32(inp,0)>>>1,{0: (c&0xFF000000)>>>24, 1: (c&0x00FF0000)>>>16, 2: (c&0x0000FF00)>>>8, 3: (c&0x000000FF)}');
 jsBoard('Wbitfetchx', 5, 1, 'inp[4]<32?{0:!!(wto32(inp,0)&(1<<inp[4]))}:{}');
 jsBoard('Mulx', 2, 2, 'c=(inp[0]*inp[1])&0xFFFF,{0: (c&0xFF00)>>>8, 1: (c&0x00FF)}');
 jsBoard('Doblmult', 4, 4, 'c=(wto16(inp,0)*wto16(inp,2))&0xFFFFFFFF,{0: (c&0xFF000000)>>>24, 1: (c&0x00FF0000)>>>16, 2: (c&0x0000FF00)>>>8, 3: (c&0x000000FF)}');
 jsBoard('Widemultiplyfunc', 8, 4, 'c=(wto32(inp,0)*wto32(inp,4))&0xFFFFFFFF,{0: (c&0xFF000000)>>>24, 1: (c&0x00FF0000)>>>16, 2: (c&0x0000FF00)>>>8, 3: (c&0x000000FF)}');
}
}
// most devices are implemented as js subboards
var CTypes = {
PORTAL:   1,
SYNCHRONISER: 2,
INPUT:   3,
OUTPUT:   4,
TERMINATE:  5,
SUBROUTINE:  6,
LITERAL:  7,
};
function Cell(type,value){
this.type = type;
this.value = value;
}
Cell.prototype.copy = function(other){
this.type = other.type;
this.value = other.value;
};
function Board(name, js, jsref, jsinc, jsoutc){
this.name = name;
this.stdout = "";
if(!js){
 this.cells = [];
 this.marbles = [];
 this.cols = 0;
 this.rows = 0;
 this.inputs = [];
 this.outputs = [];
 this.syncs = [];
 this.portals = [];
 this.terminators = [];
 for(var i = 0; i < 36; ++i){
  this.inputs[i] = [];
  this.outputs[i] = [];
  this.syncs[i] = [];
  this.portals[i] = [];
 }
 this.outputs[36] = []; // {<
 this.outputs[37] = []; // {>
 this.subroutines = []; // [r0,c0,board name,size,inputs,outputs]
 this.type = 0;
 this.inc = 0;
 this.outc = 0;
}else{
 this.func = jsref;
 this.inc = jsinc;
 this.outc = jsoutc;
 this.type = 1;
}
}
Board.prototype.set = function(row,col,cell){
if(row >= this.rows){
 for(var r = this.rows; r <= row; ++r){
  this.cells[r] = [];
  this.marbles[r] = [];
 }
}
this.rows = Math.max(this.rows, row + 1);
this.cols = Math.max(this.cols, col + 1);
if(!cell){
 this.cells[row][col] = null;
 return;
}
if(!this.cells[row][col])
 this.cells[row][col] = new Cell;
this.cells[row][col].copy(cell);
if(cell.type == CTypes.LITERAL){
 this.marbles[row][col] = cell.value;
}else{
 this.marbles[row][col] = null;
}
};
Board.prototype.get = function(r,c){
return this.cells[r][c];
};
Board.prototype.init = function(){
if(this.type == 0){
 var maxin = 0, maxout = 0;
 for(var r = 0; r < this.rows; ++r){
  for(var c = 0; c < this.cols; ++c){
   if(this.cells[r][c] == null) continue;
   switch(this.cells[r][c].type){
    case CTypes.PORTAL:
     this.portals[this.cells[r][c].value].push([r,c]);
    break;
    case CTypes.SYNCHRONISER:
     this.syncs[this.cells[r][c].value].push([r,c]);
    break;
    case CTypes.INPUT:
     this.inputs[this.cells[r][c].value].push([r,c]);
     maxin = Math.max(this.cells[r][c].value + 1, maxin);
    break;
    case CTypes.OUTPUT:
     if(this.cells[r][c].value != '<' && this.cells[r][c].value != '>'){
      this.outputs[this.cells[r][c].value].push([r,c]);
      maxout = Math.max(this.cells[r][c].value + 1, maxout);
     }else{
      this.outputs[this.cells[r][c].value == '<' ? 36 : 37].push([r,c]);
     }
    break;
    case CTypes.TERMINATE:
     this.terminators.push([r,c]);
    break;
   }
  }
 }
 this.inc = maxin;
 this.outc = maxout;
}
var namelen = Math.max(1, this.inc, this.outc) * 2;
this.name = new Array(namelen + 1).join(this.name).substr(0, namelen);
};
Board.prototype.validateSubr = function(names){
if(this.type == 1) return;
for(var r = 0, len = this.cells.length; r < len; ++r){
 var str = "", start = -1;
 for(var c = 0, rlen = this.cells[r].length; c < rlen; ++c){
  if(this.cells[r][c] && this.cells[r][c].type == CTypes.SUBROUTINE){
   if(start == -1) start = c;
   str += this.cells[r][c].value;
  }else if(start != -1){
   var match;
   while(str.length && (match = longestMatch(str, names))){
    var slen = match.length / 2;
    this.subroutines.push([r,start,match,slen,boards[match].inc,boards[match].outc]);
    start += slen;
    str = str.substr(slen * 2);
   }
   if(str.length){
    throw "No subboard could be found near `" + str + "`";
   }
   start = -1;
   str = "";
  }
 }
 var match;
 while(str.length && (match = longestMatch(str, names))){
  var slen = match.length / 2;
  this.subroutines.push([r,start,match,slen,boards[match].inc,boards[match].outc]);
  start += slen;
  str = str.substr(slen * 2);
 }
 if(str.length){
  throw "No subboard could be found near `" + str + "`";
 }
}
};
Board.prototype.runCopy = function(inp){
var b = new Board('');
b.type = 2;
b.ref = this;
b.tickNum = 0;
if(this.type == 0){
 for(var r = 0, rlen = this.marbles.length; r < rlen; ++r){
  b.marbles[r] = [];
  for(var c = 0, clen = this.marbles[r].length; c < clen; ++c){
   b.marbles[r][c] = this.marbles[r][c];
  }
 }
 for(var i = 0; i < this.inc; ++i){
  if(inp[i] != null){
   var k = this.inputs[i];
   for(var j = 0, l = k.length; j < l; ++j){
    b.marbles[k[j][0]][k[j][1]] = ((parseInt(inp[i])&255)+256)&255;
   }
  }
 }
 b.cols = this.cols;
 b.rows = this.rows;
 b.inc = this.inc;
 b.outc = this.outc;
 b.stdout = "";
}else{
 b.inp = inp;
}
return b;
};
Board.prototype.tick = function(){
if(this.type != 2) throw "Calling Board.tick without Board.runCopy";
if(this.tickNum == -1) throw "Copied board has already run to completion";

if(this.ref.type == 1){
 this.tickNum = -1;
 this.outp = this.ref.func(this.inp, this);
 return moved;
}

var moved = false;

var new_marbles = [];
for(var r = 0; r <= this.rows; ++r)
 new_marbles[r] = [];

// subroutines
for(var i = 0, len = this.ref.subroutines.length; i < len; ++i){
 var r = this.ref.subroutines[i][0], c = this.ref.subroutines[i][1],
  name = this.ref.subroutines[i][2], sz = this.ref.subroutines[i][3],
  inc = this.ref.subroutines[i][4], outc = this.ref.subroutines[i][5];
 var all = true, inp = [];
 for(var j = 0; j < inc; ++j){
  if(this.marbles[r][c+j] == null && (boards[name].type == 1 || boards[name].inputs[j].length > 0)){
   all = false; break;
  }else{
   inp[j] = this.marbles[r][c+j];
  }
 }
 if(all){
  var cb = boards[name].runCopy(inp);
  while(cb.tickNum != -1 && cb.tickNum < max_tick) cb.tick();
  if(cb.tickNum != -1) throw "Max tick count exceeded running board `" + name + "`";
  var outp = cb.out();
  if(cb.stdout != "") moved = true;
  for(var j = 0; j < outc; ++j){
   if(outp[j] != null){
    new_marbles[r+1][c+j] = ((new_marbles[r+1][c+j]||0)+(outp[j]))&255;
    moved = true;
   }
  }
  if(outp[36] != null){ // left
   var left = c-1;
   if(left < 0 && cylindrical_board){
    left = this.cols - 1;
   }
   if(left >= 0){
    new_marbles[r][left] = ((new_marbles[r][left]||0)+(outp[36]))&255;
    moved = true;
   }
  }
  if(outp[37] != null){ // right
   var right = c+sz;
   if(right >= this.cols && cylindrical_board){
    right = 0;
   }
   if(right < this.cols){
    new_marbles[r][right] = ((new_marbles[r][right]||0)+(outp[37]))&255;
    moved = true;
   }
  }
  this.stdout += cb.stdout;
 }else{
  for(var j = 0; j < inc; ++j){
   if(this.marbles[r][c+j] != null){
    new_marbles[r][c+j] = ((new_marbles[r][c+j]||0)+(this.marbles[r][c+j]))&255;
   }
  }
 }
}

// synchronisers
for(var i = 0; i < 36; ++i){
 if(this.ref.syncs[i].length){
  var all = true;
  for(var j = 0, len = this.ref.syncs[i].length; j < len; ++j){
   if(this.marbles[this.ref.syncs[i][j][0]][this.ref.syncs[i][j][1]] == null){
    all = false; break;
   }
  }
  if(all){
   for(var j = 0, len = this.ref.syncs[i].length; j < len; ++j){
    var r = this.ref.syncs[i][j][0];
    var c = this.ref.syncs[i][j][1];
    new_marbles[r+1][c] = this.marbles[r][c];
    moved = true;
   }
  }else{
   for(var j = 0, len = this.ref.syncs[i].length; j < len; ++j){
    var r = this.ref.syncs[i][j][0], c = this.ref.syncs[i][j][1];
    if(this.marbles[r][c] != null){
     new_marbles[r][c] = ((new_marbles[r][c]||0)+( this.marbles[r][c]))&255;
    }
   }
  }
 }
}

// input literal null move, output does not
for(var r = 0; r < this.rows; ++r){
 for(var c = 0; c < this.cols; ++c){
  if(this.marbles[r][c] != null){
   var type = this.ref.cells[r][c] && this.ref.cells[r][c].type;
   if(!type || type == CTypes.INPUT || type == CTypes.LITERAL){
    new_marbles[r+1][c] = ((new_marbles[r+1][c]||0)+(this.marbles[r][c]))&255;
    moved = true;
   }else if(type == CTypes.OUTPUT){
    new_marbles[r][c] = ((new_marbles[r][c]||0)+(this.marbles[r][c]))&255;
   }
  }
 }
}

// shift portal
for(var i = 0; i < 36; ++i){
 if(this.ref.portals[i].length){
  var p = this.ref.portals[i];
  if(p.length == 1){
   var r = p[0][0], c = p[0][1];
   if(this.marbles[r][c] != null){
    new_marbles[r+1][c] = ((new_marbles[r+1][c]||0)+( this.marbles[r][c]))&255;
    moved = true;
   }
  }else{
   var q = [];
   for(var j = 0, l = p.length; j < l; ++j){
    if(this.marbles[p[j][0]][p[j][1]] != null){
     // generate output portal - any other portal except the input
     var toWhere = Math.floor(Math.random() * (l-1));
     if(toWhere >= j) ++toWhere;
     var r = p[j][0], c = p[j][1];
     q[toWhere] = ((q[toWhere]||0)+(this.marbles[r][c]))&255;
     moved = true;
    }
   }
   for(var j = 0, l = p.length; j < l; ++j){
    if(q[j] != null){
     var r = p[j][0] + 1, c = p[j][1];
     new_marbles[r][c] = q[j];
    }
   }
  }
 }
}

// check stdout
if(new_marbles[new_marbles.length-1].length){
 var r = this.rows;
 for(var i = 0, l = new_marbles[r].length; i < l; ++i){
  if(new_marbles[r][i] != null){
   putch(this, new_marbles[r][i]);
   moved = true;
  }
 }
}
new_marbles.splice(this.rows);

if(!moved){
 this.tickNum = -1;
 return moved;
}
this.marbles = new_marbles;
// check terminator
for(var i = 0, len = this.ref.terminators.length; i < len; ++i){
 var r = this.ref.terminators[i][0], c = this.ref.terminators[i][1];
 if(new_marbles[r][c] != null){
  this.tickNum = -1;
  return moved;
 }
}
// check output
if(this.outc){
 var allOuts = true;
 for(var i = 0; i < 38; ++i){
  var o = this.ref.outputs[i];
  if(o.length){
   var occupied = false;
   for(var j = 0, len = o.length; j < len; ++j){
    if(new_marbles[o[j][0]][o[j][1]] != null){
     occupied = true;
     break;
    }
   }
   if(!occupied){
    allOuts = false; break;
   }
  }
 }
 if(allOuts){
  this.tickNum = -1;
  return moved;
 }
}
++this.tickNum;
return moved;
};
Board.prototype.out = function(){
if(this.type != 2) throw "Calling Board.out without Board.runCopy";
if(this.tickNum != -1) throw "Copied board hasn't run to completion yet";
if(this.ref.type == 1) return this.outp;
var outp = {};
for(var i = 0; i < 38; ++i){
 if(this.ref.outputs[i].length){
  outp[i] = 0;
  var o = this.ref.outputs[i], isFilled = false;
  for(var j = 0, len = o.length; j < len; ++j){
   var r = o[j][0], c = o[j][1];
   isFilled = isFilled || this.marbles[r][c] != null;
   outp[i] = ((outp[i])+( this.marbles[r][c] || 0))&255;
  }
  if(!isFilled)
   outp[i] = null;
 }
}
return outp;
};

function DrawBuffer(canvas){
this.canvas = canvas;
this.ctx = this.canvas.getContext('2d');
this.ctx.fillStyle = 'rgb(0,0,0)';
this.ctx.fillRect(0, 0, 256, 256);
}

DrawBuffer.prototype.clear = function(){
this.ctx.fillStyle = 'rgb(0,0,0)';
this.ctx.fillRect(0, 0, 256, 256);
};
DrawBuffer.prototype.set = function(x, y, r, g, b){
this.ctx.fillStyle = 'rgb(' + r + ',' + g + ',' + b + ')';
this.ctx.fillRect(x, y, 1, 1);
};
DrawBuffer.prototype.get = function(x, y){
return this.ctx.getImageData(x, y, 1, 1).data.splice(0, 3);
};
// spaces: is an empty cell denoted with whitespace?
function parseMblSrc(src,spaces){
var lines = (':MB\n'+src).split('\n');
var sb = []; // start lines of new mb subboards
for(var i = lines.length; i-- > 0;){
 // strip mid-line spaces if possible
 if(!spaces){
  lines[i] = lines[i].trim();
  lines[i] = lines[i].replace(/\s/g,'');
 }
 // index of comment
 var o = lines[i].indexOf('#');
 // remove comments
 if(o > 0){
  lines[i] = lines[i].substr(0, o).trim();
 }else if(lines[i].length == 0 || o == 0){
  if(lines[i].indexOf('include') == 1){
   throw "#include not supported";
  }
  lines.splice(i, 1);
 }
}
for(var i = lines.length; i-- > 0;){
 // identify subboards
 if(lines[i].charAt(0) == ':'){
  sb.push(i);
 }
}
sb.sort(function(a,b){return a-b;});
var mbname = '';
for(var i = 0, len = sb.length; i < len; ++i){
 var name = lines[sb[i]].substr(1).trim();
 var board;
 board = new Board(name, false);
 var endl;
 if(i == len - 1) endl = lines.length;
 else endl = sb[i+1];
 for(var j = sb[i]+1; j < endl; ++j){
  var r = j - sb[i] - 1;
  if(lines[j].length % 2 != 0){
   throw "Error near `" + lines[j] + "`";
  }
  var cells = lines[j].match(/../g);
  for(var k = 0, clen = cells.length; k < clen; ++k){
   var val;
   if(val = cells[k].match(/^@([0-9A-Z])$/)){
    board.set(r, k, new Cell(CTypes.PORTAL, parseInt(val[1], 36)));
   }else if(val = cells[k].match(/^&([0-9A-Z])$/)){
    board.set(r, k, new Cell(CTypes.SYNCHRONISER, parseInt(val[1], 36)));
   }else if(val = cells[k].match(/^}([0-9A-Z])$/)){
    board.set(r, k, new Cell(CTypes.INPUT, parseInt(val[1], 36)));
   }else if(val = cells[k].match(/^{([0-9A-Z<>])$/)){
    var value;
    if(val[1] == '<' || val[1] == '>') value = val[1];
    else value = parseInt(val[1], 36);
    board.set(r, k, new Cell(CTypes.OUTPUT, value));
   }else if(cells[k] == '!!'){
    board.set(r, k, new Cell(CTypes.TERMINATE, 0));
   }else if(val = cells[k].match(/^[0-9A-F]{2}$/)){
    board.set(r, k, new Cell(CTypes.LITERAL, parseInt(cells[k], 16)));
   }else if(cells[k].match(/^[ \.]{2}$/)){
    board.set(r, k, null);
   }else{
    board.set(r, k, new Cell(CTypes.SUBROUTINE, cells[k]));
   }
  }
 }
 board.init();
 if(name == 'MB')
  mbname = board.name;
 name = board.name;
 bnames.push(name);
 boards[name] = board;
}
// validate and connect subr
for(var p in boards){
 boards[p].validateSubr(bnames);
}
return mbname;
}
function run(){
// normal init
stopped = false;
max_tick = document.getElementById('mb-ticks').value;
space_as_blank = document.getElementById('mb-spaces').checked;
cylindrical_board = document.getElementById('mb-cylinder').checked;
print_numbers = document.getElementById('mb-numprint').checked;
libraries = document.getElementById('mb-lib').checked;
gfx = document.getElementById('mb-gfx').checked;

src = document.getElementById('mb-src').value;
stdin = document.getElementById('mb-in').value;
boards = {};
bnames = [];
loadDefaultBoards();

if(gfx){
 // prepare draw buffers
 front_buffer = new DrawBuffer(document.getElementById('mb-fb'));
 back_buffer = new DrawBuffer(document.getElementById('mb-bb'));
}else{
 if(front_buffer){
  front_buffer.clear();
  back_buffer.clear();
  front_buffer = null;
  back_buffer = null;
 }
}
try{
 var mb = parseMblSrc(src, space_as_blank);
 var rc = boards[mb].runCopy(document.getElementById('mb-args').value.split(' '));
 var tmp = function(){
  try{
   if(stopped) throw "Board execution stopped.";
   else if(rc.tickNum != -1 && rc.tickNum < max_tick){
    rc.tick();
    document.getElementById('mb-out').value = rc.stdout;
    document.getElementById('mb-out').scrollTop = document.getElementById('mb-out').scrollHeight;
    setTimeout(tmp, 0);
   }else if(rc.tickNum == -1){
    document.getElementById('mb-out').value = rc.stdout;
    document.getElementById('mb-out').scrollTop = document.getElementById('mb-out').scrollHeight;
    document.getElementById('mb-return').value = rc.out()[0] || 0;
   }else throw "Max tick count exceeded running main board.";
  }catch(e){
   document.getElementById('mb-out').value = rc.stdout + '\n' + e;
   document.getElementById('mb-out').scrollTop = document.getElementById('mb-out').scrollHeight;
  }
 };
 setTimeout(tmp, 0);
}catch(e){
 document.getElementById('mb-out').value = (rc ? rc.stdout: '') + '\n' + e;
 document.getElementById('mb-out').scrollTop = document.getElementById('mb-out').scrollHeight;
}
}
function stop(){
stopped = true;
}
```

```

 Marbelous Source:

 <textarea id="mb-src" rows="4" cols="35">48 65 6C 6C 6F 20 57 6F 72 6C 64 21</textarea>

 Arguments:

 <input id="mb-args" size="33" />

 STDIN:

 <textarea id="mb-in" rows="2" cols="35"></textarea>

  Max Ticks: <input id="mb-ticks" type="number" min="1" style="width: 60px" value="1000" />

  <input type="button" onclick="run()" value="Run Code" style="" />
  <input type="button" onclick="stop()" value="Stop" style="" />

  <input type="checkbox" id="mb-spaces" />Using spaces for blank cells

  <input type="checkbox" id="mb-cylinder" />Cylindrical Board

  <input type="checkbox" id="mb-numprint" />Display output as decimal numbers

  <input type="checkbox" id="mb-lib" checked="true" />Include Libraries

  <input type="checkbox" id="mb-gfx" />Use Draw Buffers

  STDOUT:

  <textarea id="mb-out" rows="3" cols="35"></textarea>

  Return Code: <input id="mb-return" />

  Front Buffer:
  <canvas style="height: 256px; width: 256px; background: black;" width="256" height="256" id="mb-fb"></canvas>

  Back Buffer:
  <canvas style="height: 256px; width: 256px; background: black;" width="256" height="256" id="mb-bb"></canvas>

```

A few simple programs to try:

### cat (prints stdin to stdout)

```
.. @0 ..
00 ]] \/
@0 /\ ..

```

### rot13 (reads from stdin)

```
.. @0 ..
00 ]] \/
@0 /\ Rt
:Rt
}0 .. @0 .. }0 }0 }0 }0 }0
-W .. -W .. .. +D -D +D -D
-X .. >C &3 &0 &1 &2 &3 &4
>C &1 >P &4 {0 {0 {0 {0 {0
>P &2 &0 \/ .. .. .. .. ..
@0 \/ \/ .. .. .. .. .. ..

```

### Graphical Output Demo (sets a random pixel to a random color and then flips buffer)

```
FF FF FF FF FF 00
?? ?? ?? ?? ?? ..
{} {} {} {} {} ><

```
> 21 votes

# Answer
# JavaScript (sample answer)

Interpreting JavaScript using JavaScript is somewhat useless, but this shows what your interpreter snippets should roughly behave like.

Here is the bare bones version, intended for quick use in other posts:

```
BEGIN_CODE
// Put JavaScript code here
// it may be on multiple lines
END_CODE_BEGIN_INPUT
Put input here
it may be on multiple lines
END_INPUT
JavaScript:
<tt>function(x) {</tt>
<textarea id='c'rows='4'cols='60'></textarea>
<tt>}</tt>

Input string (variable x):
<textarea id='i'rows='4'cols='60'></textarea>
<input type='button'value='Run'onclick='r()'>
Output (return value):
<textarea id='o'rows='4'cols='60'style='background-color:#f0f0f0;'></textarea>
```

The raw Markdown for including this Stack Snippet in another question or answer is:

```

BEGIN_CODE
// Put JavaScript code here
// it may be on multiple lines
END_CODE_BEGIN_INPUT
Put input here
it may be on multiple lines
END_INPUT
JavaScript:
<tt>function(x) {</tt>
<textarea id='c'rows='4'cols='60'></textarea>
<tt>}</tt>

Input string (variable x):
<textarea id='i'rows='4'cols='60'></textarea>
<input type='button'value='Run'onclick='r()'>
Output (return value):
<textarea id='o'rows='4'cols='60'style='background-color:#f0f0f0;'></textarea>

```

To use it simply copy it into a new post and put your code on the lines between `BEGIN_CODE` and `END_CODE_BEGIN_INPUT`, and your input on the lines between `END_CODE_BEGIN_INPUT` and `END_INPUT`. The interpreter will do the rest. **Note that nothing needs to be indented.**

I would argue that this `BEGIN...END` technique is presently the best way we have to write these interpreters in terms of ease of future use because...

* When rendered there is only one code block (the HTML one) and only one line of it is "extra".
* The user writing the snippet can see exactly where to place their code and input. They don't have to search for the appropriate textarea tag.
* Users reading the post can easily distinguish the code without even running the snippet. Of course when the snippet is run the code is obvious.
* It only breaks when the begin/end identifiers appear on their own lines within the code or the input. But this is unlikely, and they can be changed if absolutely necessary.
* It is self contained. All the code is right there. (I know this might be impossible for a larger interpreter but one of the points of Stack Snippets was to combat dead links to JSFiddle and such, so self-containedness is good.)
* It could be expanded to suit any number of (text based) inputs.

---

The snippet below is the non-minimized general version, complete with example and a bit more styling.

```
function example() {
  document.getElementById('code').value = "var lines = x.split('\\n')\nvar sum = 0\nfor (var i = 0; i < lines.length; i++) {\n  var val = parseInt(lines[i])\n  if (!isNaN(val)) {\n    sum += val\n  }\n}\nreturn sum"
  document.getElementById('input').value = '1\n2\n3'
  run()
}

function run() {
  var run = null, example = null; //shadow other globals
  eval('var f=function(x) {' + document.getElementById('code').value + '}')
  document.getElementById('output').value = String(f(document.getElementById('input').value))
}
```

```
#output {
  background-color: #f0f0f0;
}

#run {
  font-size: 120%;
}
```

```
JavaScript:

<tt>function(x) {</tt>

<textarea id='code' rows='12' cols='60'></textarea>

<tt>}</tt>

Input string (variable x):

<textarea id='input' rows='6' cols='60'></textarea>

<input id='run' type='button' value='Run' onclick='run()'>

Output (return value):

<textarea id='output' rows='6' cols='60'></textarea>

Example: Sum Numbers

```
> 16 votes

# Answer
# Brainfuck (with basic debugger)

I saw the brainfuck answer and thought: you know what would be awesome? If I could pretend I understand what brainfuck code is doing. And hence I made a basic brainfuck interpreter and debugger. The debugger is SLOW, but it works pretty well, albeit I havent implemented breakpoints as of now (on the todo list).

Note: the Brainfuck "virtual machine" doesnt auto reset after running the code. Press reset manually or the tape will have the same values on it that existed at the end of the last program run.

The debugger works best in full screen.

```
var mycode = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.";

function Brainfuck()    {
    this.cell_max = 255;
    this.read = function()    {return 0;}
    this.reset();
}

Brainfuck.prototype.reset = function()    {
    this.stack = [0];
    this.stackptr = 0;

    this.printbuffer = "";
}

Brainfuck.prototype.setCode = function(code)    {
    this.code = code;
    this.codeptr = 0;

    this.loop_map = {};
    var loops = [];
    for(var i = 0; i < this.code.length; i++)    {
        if(this.code[i] == '[')    {
            loops.push(i);
        }    else if(this.code[i] == ']')    {
            var last = loops.pop();
            this.loop_map[last] = i;
            this.loop_map[i] = last;
        }
    }
}

Brainfuck.prototype.done = function()    {
    return !(this.codeptr < this.code.length);
}

Brainfuck.prototype.step = function()    {
    switch(this.code.charAt(this.codeptr))    {
        case '>':
            if(++this.stackptr >= this.stack.length)    {
                this.stack.push(0);
            }
            break;
        case '<':
            if(--this.stackptr < 0)    {
                this.stackptr = this.stack.length - 1;
            }
            break;
        case '+':
            if(++this.stack[this.stackptr] > this.cell_max)    {
                this.stack[this.stackptr] = 0;
            }
            break;
        case '-':
            if(--this.stack[this.stackptr] < 0)    {
                this.stack[this.stackptr] = this.cell_max;
            }
            break;
        case '.':
            this.print();
            break;
        case ',':
            this.stack[this.stackptr] = this.read();
            break;
        case '[':
            if(this.stack[this.stackptr] == 0)    {
                this.codeptr = this.loop_map[this.codeptr];
            }
            break;
        case ']':
            if(this.stack[this.stackptr] != 0)    {
                this.codeptr = this.loop_map[this.codeptr];
            }
            break;
        default:

    }
    while(!this.done() && '><+-.,[]'.indexOf(this.code[++this.codeptr]) == -1);
}

Brainfuck.prototype.print = function()    {
    this.printbuffer += String.fromCharCode(this.stack[this.stackptr]);
}

// UI File

var $ = document.getElementById.bind(document);
var $_ = document.createElement.bind(document);

String.prototype.decodeHTML = function() {
    var map = {"gt":">", "lt":"<", "nbsp":""};
    return this.replace(/&(#(?:x[0-9a-f]+|\d+)|[a-z]+);?/gi, function($0, $1) {
        if ($1[0] === "#") {
            return String.fromCharCode($1[1].toLowerCase() === "x" ? parseInt($1.substr(2), 16)  : parseInt($1.substr(1), 10));
        } else {
            return map.hasOwnProperty($1) ? map[$1] : $0;
        }
    });
}

var bf = new Brainfuck();

var setup = function()    {
    bf.setCode($('code').value.decodeHTML());
    bf.read = function()    {
        var stdin = $('stdin').value;
        if(bf.read.index < stdin.length)    {
            return stdin[bf.read.index++].charCodeAt(0);
        }
        return 0;
    }
    bf.read.index = 0;
}

var run = function()    {
    setup();

    var stdout = $('stdout');
    var func = function()    {
        for(var i = 0; i < 500000 && !bf.done(); i++)    {
            bf.step();
        }
        stdout.innerHTML = bf.printbuffer;
        setTimeout(func, 0);
    };
    func();
}

var debug = function()    {
    $('debug-area').style.display = 'block';

    setup();

    var running = $('running-code');
        for(var i = 0; i < bf.code.length; i++)    {
            var s = $_('span');
            s.innerHTML = bf.code[i];
            s.style.fontFamily = "Courier";
            running.appendChild(s);
        }
        running.children[bf.codeptr].setAttribute('class', 'selected');

    genStackTable();
}

var genStackTable = function()    {
    var stable = $('stack-table');
    var head = stable.createTHead();
        var row = head.insertRow(0);
            row.insertCell(0).innerHTML = 'ptr';
            row.insertCell(1).innerHTML = 'addr';
            row.insertCell(2).innerHTML = 'value';
            row.insertCell(3).innerHTML = 'ASCII';
    var setStackVal = function(i, num, ascii, changed)    {
        return changed === num ? function() {
            ascii.value = String.fromCharCode(num.value);
            bf.stack[i] = num.value;
        } : function()    {
            num.value = ascii.value.charCodeAt(0);
            bf.stack[i] = num.value;
        }
    }
    for(var i in bf.stack)    {
        row = stable.insertRow();
        row.insertCell(0).innerHTML = i == bf.stackptr ? '>' : '';
        row.insertCell(1).innerHTML = i;
        var cell = row.insertCell(2);
            var numinput = $_('input');
                numinput.type = 'number';
                numinput.value = bf.stack[i];
            cell.appendChild(numinput);
        cell = row.insertCell(3);
            var asciiinput = $_('input');
                asciiinput.type = 'text';
                asciiinput.value = String.fromCharCode(bf.stack[i]);
                asciiinput.setAttribute('maxlength', 1);
            cell.appendChild(asciiinput);

        numinput.oninput = setStackVal(i, numinput, asciiinput, numinput);
        asciiinput.oninput = setStackVal(i, numinput, asciiinput, asciiinput);
    }
}

var debugRun = function()    {
    debugRun.pause = false;
    var func = function()    {
        step();
        if(!bf.done() && !debugRun.pause)    {
            setTimeout(func, $('step-duration').value);
        }
    }
    func();
}

var debugPause = function()    {
    debugRun.pause = true;
}

var step = function()    {
    var running = $('running-code');
    running.children[bf.codeptr].setAttribute('class', '');
    bf.step();
    $('stack-table').innerHTML = '';
    genStackTable();
    if(!bf.done())    {
        running.children[bf.codeptr].setAttribute('class', 'selected');
    }
    $('stdout').innerHTML = bf.printbuffer;
}

var reset = function()    {
    bf.reset();
    bf.read.index = 0;
    $('stdout').innerHTML = '';
    $('running-code').innerHTML = '';
    $('stack-table').innerHTML = '';
    $('debug-area').style.display = 'none';
}

var setStackSize = function()    {
    var sel = $('stackSize');
    bf.cell_max = parseInt(sel.options[sel.selectedIndex].value);
}

$('code').value = mycode;
```

```
input    {
    box-sizing:border-box;
    -moz-box-sizing:border-box;
}
div.textarea {
    -moz-appearance: textfield-multiline;
    -webkit-appearance: textarea;
    border: 1px solid gray;
    font: -webkit-small-control;
    font-family:Courier;
    height: 28px;
    overflow: auto;
    padding: 2px;
    resize: both;
    width: 200px;
    white-space:pre;
}
#debug-area    {
    display:none;
}
span.selected    {
    background-color:red;
}
```

```

Brainfuck

Code

        <textarea id="code"></textarea>

Stdin

        <textarea id="stdin"></textarea>

Stdout

        Cell Size
        <select id="stackSize" onchange="setStackSize()">
            <option value="255">8-bit</option>
            <option value="65535">16-bit</option>
            <option value="4294967296">32-bit</option>
        </select>

        <button id="run" onclick="run()">Run</button>
        <button id="debug" onclick="debug()">Debug</button>
        <button id="reset" onclick="reset()">Reset</button>

Debug

            <button onclick="debugRun()">Run</button>
            <button onclick="debugPause()">Pause</button>
            Time between instructions
            <input id="step-duration" type="number" value=5 />

            <button onclick="step()">Step</button>

Executing Code

Stack

```

## TODO:

* add breakpoints
* add range check to stack changing
* progress indicator
* make it look better
* add rewind for debugging
* change stdin to some sort of stream?
* golf code a bit
* ?

## Usage:

To use in a snippet somewhere on the site, change the first line of the snippet to include your code as "mycode".

To run code without debugger, simply press run. It buffers output for half a million instructions before updating stdout.

To debug, start by pressing the debug button. The step button will step to the next instruction. The run button will run the entire program, but one step at a time, updating the stack table every step (which is why this is so slow). The time between instructions is determined by the input box with that name. The pause button pauses execution of the code. It can be resumed by pressing Run again.

All the values on the stack can be changed live to whatever you want. Be careful though, it doesnt range check if you change the integer value in the cell, so if you put in 300 with an 8-bit stack size, it doesnt really care and wont correct it until the next time it increments.
> 15 votes

# Answer
# Japt

**Japt** (**Ja**vascri**pt** shortened) is a language I designed in September 2015. Due to being ~~lazy~~ busy, I didn't create an interpreter until early November. You can find the official interpreter and docs here.

**Note:** If you have any questions, suggestions, or bug reports, please post them in the Japt chatroom.

```
* { font-size:12px; font-family: Verdana, Geneva, sans-serif; } textarea { overflow: scroll; overflow-x: hidden; width: 90%; } table { float: left; margin-right: 6px; } table, th, td { border: 1px solid lightgrey; border-collapse: collapse; padding: 3px; } .mono { font-family: Fira Mono, Consolas, DejaVu Sans Mono, Inconsolata, Courier New, monospace; font-size: 10p; } #stderr { color: red; }
```

```

Code:

<textarea id="code" class="mono" rows="6">[U,V*Wg0 ,Wg1]qS</textarea>

Input:

<textarea id="input" class="mono" rows="2">"abc" 13 [9 "zyx"]</textarea>

  <input id="run" type="button" value="Run" onclick="Japt.run(document.getElementById('code').value, document.getElementById('input').value, false, null, function(x){Japt.output(x)}, function(x){Japt.error(x)})">
  <input id="stop" type="button" value="Stop" onclick="Japt.stop()">
  <input id="clear" type="button" value="Clear" onclick="Japt.clear_output()">

Output:

<textarea id="output" class="mono" rows="6" readonly></textarea>

```

Fun fact: this was originally the main interpreter (and in fact the *only* interpreter). You can see this if you look through the revision history.
> 15 votes

# Answer
# FRACTRAN

An semi-optimised interpreter for my favourite esoteric language! Unfortunately I don't have much time this week, so additional features will have to come later.

```
var ITERS_PER_SEC = 100000
var TIMEOUT_MILLISECS = 5000

var ERROR_INPUT = "Invalid input"
var ERROR_PARSE = "Parse error: "
var ERROR_TIMEOUT = "Timeout"
var ERROR_INTERRUPT = "Interrupted by user"

var running, instructions, registers, timeout, start_time, 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
}

function interrupt() {
  error(ERROR_INTERRUPT)
}

function error(msg) {
  document.getElementById("stderr").innerHTML = msg
  stop()
}

function factorise(n) {
  var factorisation = {}
  var divisor = 2

  while (n > 1) {
    if (n % divisor == 0) {
      var power = 0

      while (n % divisor == 0) {
        n /= divisor
        power += 1
      }

      if (power != 0) {
        factorisation[divisor] = power
      }
    }

    divisor += 1
  }

  return factorisation
}

function fact_accumulate(fact1, fact2) {
  for (var reg in fact2) {
    if (reg in fact1) {
      fact1[reg] += fact2[reg]
    } else {
      fact1[reg] = fact2[reg]
    }
  }

  return fact1
}

function exp_to_fact(expression) {
  expression = expression.trim().split(/\s*\*\s*/)
  var factorisation = {}

  for (var i = 0; i < expression.length; ++i) {
    var term = expression[i].trim().split(/\s*\^\s*/)

    if (term.length > 2) {
      throw "error"
    }

    term[0] = parseInt(term[0])

    if (isNaN(term[0])) {
      throw "error"
    }

    if (term.length == 2) {
      term[1] = parseInt(term[1])

      if (isNaN(term[1])) {
        throw "error"
      }
    }

    if (term[0] <= 1) {
      continue
    }

    var fact_term = factorise(term[0])

    if (term.length == 2) {
      for (var reg in fact_term) {
        fact_term[reg] *= term[1]
      }
    }

    factorisation = fact_accumulate(factorisation, fact_term)
  }

  return factorisation
}

function to_instruction(n, d) {
  instruction = []
  divisor = 2

  while (n > 1 || d > 1) {
    if (n % divisor == 0 || d % divisor == 0) {
       reg_offset = 0

       while (n % divisor == 0) {
         reg_offset += 1
         n /= divisor
       }

       while (d % divisor == 0) {
         reg_offset -= 1
         d /= divisor
       }

      if (reg_offset != 0) {
        instruction.push(Array(divisor, reg_offset))
      }
    }

    divisor += 1
  }

  return instruction
}

function run() {
  clear_output()

  document.getElementById("run").disabled = true
  document.getElementById("stop").disabled = false
  document.getElementById("clear").disabled = true

  timeout = document.getElementById("timeout").checked

  var code = document.getElementById("code").value
  var input = document.getElementById("input").value

  instructions = []

  code = code.trim().split(/[\s,]+/)

  for (i = 0; i < code.length; ++i){
    fraction = code[i]

    split_fraction = fraction.split("/")

    if (split_fraction.length != 2){
      error(ERROR_PARSE + fraction)
      return
    }

    numerator = parseInt(split_fraction[0])
    denominator = parseInt(split_fraction[1])

    if (isNaN(numerator) || isNaN(denominator)){
      error(ERROR_PARSE + fraction)
      return
    }

    instructions.push(to_instruction(numerator, denominator))
  }

  try {
    registers = exp_to_fact(input)
  } catch (err) {
    error(ERROR_INPUT)
    return
  }

  running = true
  iterations = 0
  start_time = Date.now()

  fractran_iter(1)
}

function regs_to_string(regs) {
  reg_list = Object.keys(regs)
  reg_list.sort(function(a,b){ return a - b })

  out_str = []

  for (var i = 0; i < reg_list.length; ++i) {
    if (regs[reg_list[i]] != 0) {
      out_str.push(reg_list[i] + "^" + regs[reg_list[i]])
    }
  }

  out_str = out_str.join(" * ")

  if (out_str == "") {
    out_str = "1"
  }

  return out_str
}

function fractran_iter(niters) {
  if (!running) {
    stop()
    return
  }

  var iter_start_time = Date.now()

  for (var i = 0; i < niters; ++i)
  {
    program_complete = true

    for (var instr_ptr = 0; instr_ptr < instructions.length; ++instr_ptr){
      instruction = instructions[instr_ptr]
      perform_instr = true

      for (var j = 0; j < instruction.length; ++j)
      {
        var reg = instruction[j][0]
        var offset = instruction[j][1]

        if (registers[reg] == undefined) {
          registers[reg] = 0
        }

        if (offset < 0 && registers[reg] < -offset) {
          perform_instr = false
          break
        }
      }

      if (perform_instr) {
        for (var j = 0; j < instruction.length; ++j)
        {
           var reg = instruction[j][0]
           var offset = instruction[j][1]

           registers[reg] += offset
        }

        program_complete = false
        break
      }
    }

    if (program_complete) {
      document.getElementById("output").value += regs_to_string(registers)
      stop()
      return
    }

    iterations++

    if (timeout && Date.now() - start_time > TIMEOUT_MILLISECS) {
      error(ERROR_TIMEOUT)
      return
    }
  }

  setTimeout(function() { fractran_iter(ITERS_PER_SEC * (Date.now() - iter_start_time)/1000) }, 0)
}
```

```

    Code:

    <textarea id="code" rows="4" style="overflow:scroll;overflow-x:hidden;width:90%;">37789/221 905293/11063 1961/533 2279/481 57293/16211 2279/611 53/559 1961/403 53/299 13/53 1/13 6557/262727 6059/284321 67/4307 67/4661 6059/3599 59/83 1/59 14279/871933 131/9701 102037079/8633 14017/673819 7729/10057 128886839/8989 13493/757301 7729/11303 89/131 1/89 31133/2603 542249/19043 2483/22879 561731/20413 2483/23701 581213/20687 2483/24523 587707/21509 2483/24797 137/191 1/137 6215941/579 6730777/965 7232447/1351 7947497/2123 193/227 31373/193 23533/37327 5401639/458 229/233 21449/229 55973/24823 55973/25787 6705901/52961 7145447/55973 251/269 24119/251 72217/27913 283/73903 281/283 293/281 293/28997 293/271 9320827/58307 9831643/75301 293/313 28213/293 103459/32651 347/104807 347/88631 337/347 349/337 349/33919 349/317 12566447/68753 13307053/107143 349/367 33197/349 135199/38419 389/137497 389/119113 389/100729 383/389 397/383 397/39911 397/373 1203/140141 2005/142523 2807/123467 4411/104411 802/94883 397/401 193/397 1227/47477 2045/47959 2863/50851 4499/53743 241/409 1/241 1/239
</textarea>

Input:

    <textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;">2^47 * 193</textarea>

      Timeout:
      <input id="timeout" type="checkbox" checked="true"></input>

    Output:

    <textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>

      <input id="run" type="button" value="Run" onclick="run()"></input>
      <input id="stop" type="button" value="Stop" onclick="interrupt()" disabled="true"></input>
      <input id="clear" type="button" value="Clear" onclick="clear_output()"></input>

```

The example program above is my four squares together program \- it takes input 2<sup>n</sup> * 193, and outputs 3<sup>a</sup> * 5<sup>b</sup> * 7<sup>c</sup> * 11<sup>d</sup>, such that a<sup>2</sup> \+ b<sup>2</sup> \+ c<sup>2</sup> \+ d<sup>2</sup> = n.

## To-do

* Snippet generator
* Allow for factorisation notation for fractions too
* Less terrible input validation
* Clean up code to be better
* Allow for printing of registers under special conditions (e.g. only register `2` is set, in the case of Conway's prime generator). Currently only programs which terminate produce any output.
* Performance optimisations?

## Usage

* Fractions in the code are split by `[\s,]+`, allowing you to separate fractions by newlines, spaces or commas (or tabs, or even any combination of the above, if you're insane)
* Input can be in factorisation notation, e.g. `2^5 * 3^7 * 11`
* Snippet generator coming some time later
> 13 votes

# Answer
# Prelude

Maybe I can increase Prelude adoption a bit if people can just play around with it in their browsers, so here is a JavaScript interpreter. It's based on Sp3000's nifty Brainfuck interpreter, whose killer feature is interruptible execution and an optional time out.

```
var ITERS_PER_SEC = 100000;
var TIMEOUT_MILLISECS = 5000;
var ERROR_LOOP_MISMATCH = "Mismatched parentheses";
var ERROR_LOOP_MULTI = "Multiple parentheses in the same column";
var ERROR_TIMEOUT = "Timeout";
var ERROR_INTERRUPT = "Interrupted by user";

var code, input, timeout, num_input, num_output, loop_stack, loop_map;
var running, start_time, code_ptr, width, input_ptr, voices, 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("num_input").disabled = false;
    document.getElementById("num_output").disabled = false;
    document.getElementById("timeout").disabled = false;
}

function interrupt() {
    error(ERROR_INTERRUPT);
}

function error(msg) {
    document.getElementById("stderr").innerHTML = msg;
    stop();
}

function run() {
    clear_output();

    document.getElementById("run").disabled = true;
    document.getElementById("stop").disabled = false;
    document.getElementById("clear").disabled = true;
    document.getElementById("num_input").disabled = false;
    document.getElementById("num_output").disabled = false;
    document.getElementById("timeout").disabled = false;

    code = document.getElementById("code").value;
    input = document.getElementById("input").value;
    num_input = document.getElementById("num_input").checked;
    num_output = document.getElementById("num_output").checked;
    timeout = document.getElementById("timeout").checked;

    loop_stack = [];
    loop_map = {};

    if (num_input) {
        input = input.match(/-?\d+/g).map(function (n) {
            return +n;
        });
    } else {
        input = input.split("").map(function (s) {
            return s.charCodeAt(0);
        });
    }

    code = code.split("\n");
    width = 0;
    for (var i = 0; i  width)
            width = code[i].length;
    console.log(code);
    console.log(width);
    for (var i = 0; i < width; ++i) {
        var hasParens = false;
        for (var j = 0; j < code.length; ++j) {
            var char = code[j][i];
            if (char == "(" || char == ")") {
                if (hasParens) {
                    error(ERROR_LOOP_MULTI);
                    return;
                }

                hasParens = true;
                if (char == "(") loop_stack.push({
                    x: i,
                    y: j
                });
                else {
                    if (loop_stack.length == 0) {
                        error(ERROR_LOOP_MISMATCH);
                        return;
                    } else {
                        var last_parens = loop_stack.pop();
                        loop_map[last_parens.x] = {
                            x: i,
                            y: last_parens.y
                        };
                        loop_map[i] = last_parens;
                    }
                }
            }
        }
        console.log(i);
        console.log(loop_stack);
    }

    if (loop_stack.length > 0) {
        error(ERROR_LOOP_MISMATCH);
        return;
    }

    console.log(loop_map);

    running = true;
    start_time = Date.now();
    code_ptr = 0;
    input_ptr = 0;
    voices = code.map(function () {
        return [];
    });
    iterations = 0;

    prelude_iter(1);
}

function prelude_iter(niters) {
    if (code_ptr >= width || !running) {
        stop();
        return;
    }

    console.log(voices);
    var iter_start_time = Date.now();

    for (var i = 0; i < niters; ++i) {
        var previousTops = voices.map(function(v) { return v[v.length-1] || 0; });

        for (var j = 0; j < code.length; ++j) {
            switch (code[j][code_ptr]) {
                case "0":
                case "1":
                case "2":
                case "3":
                case "4":
                case "5":
                case "6":
                case "7":
                case "8":
                case "9":
                    voices[j].push(+code[j][code_ptr]);
                    break;

                case "+":
                    var x = voices[j].pop() || 0;
                    var y = voices[j].pop() || 0;
                    voices[j].push(x + y);
                    break;

                case "-":
                    var x = voices[j].pop() || 0;
                    var y = voices[j].pop() || 0;
                    voices[j].push(y - x);
                    break;

                case "v":
                    voices[j].push(previousTops[j == code.length-1 ? 0 : j + 1]);
                    break;

                case "^":
                    voices[j].push(previousTops[j == 0 ? code.length-1 : j - 1]);
                    break;

                case "#":
                    voices[j].pop();
                    break;

                case "!":
                    var value = voices[j].pop() || 0;
                    document.getElementById("output").value += num_output ? value+"\n" : String.fromCharCode(value);
                    break;

                case "?":
                    if (input_ptr >= input.length) {
                        voices[j].push(0);
                    } else {
                        voices[j].push(input[input_ptr]);
                        ++input_ptr;
                    }
                    break;
            }
        }

        if (loop_map[code_ptr])
        {
            var other = loop_map[code_ptr];
            code_ptr = previousTops[other.y] ? Math.min(code_ptr, other.x) : Math.max(code_ptr, other.x);
        }

        ++code_ptr;
        ++iterations;

        if (timeout && Date.now() - start_time > TIMEOUT_MILLISECS) {
            error(ERROR_TIMEOUT);
            return;
        }
    }

    setTimeout(function () {
        prelude_iter(ITERS_PER_SEC * (Date.now() - iter_start_time) / 1000)
    }, 0);
}
```

```

Code:

    <textarea id="code" rows="4" style="overflow:scroll;overflow-x:hidden;width:90%;">1(  #^    #^^   (#^+!
6 9+ 05+5+^#^+! #^ ^+!
   (((1- )#^##)^^+   )7-!)1433545514232323344949145353495314235494040404232323013334492349532333344953493435343584233475234501333449530423232349495323232323495323230494)</textarea>

Input:

    <textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;">5a-13 11 2e3</textarea>

Numeric Input:
        <input id="num_input" type="checkbox">  Numeric Output:
        <input id="num_output" type="checkbox">  Timeout:
        <input id="timeout" type="checkbox" checked="checked">

        <input id="run" type="button" value="Run" onclick="run()">
        <input id="stop" type="button" value="Stop" onclick="interrupt()" disabled="disabled">
        <input id="clear" type="button" value="Clear" onclick="clear_output()">

Output:

    <textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>

```

Alternatively, here is a JSFiddle.

The interpreter is prepopulated with my quine, but you can easily find more example programs for to play around with by searching for Prelude answers of mine.

All the features of Prelude are implemented. The only shortcoming is the lack of arbitrary-precision arithmetic, due to JavaScript's number type. I might fix that at some point, since I only need to support addition and subtraction for arbitrary integers.

Input and output are usually the byte values of individual characters, but the interpreter comes with two flags to read and/or write (signed) numbers instead.

## ToDo

* Add minified version for copying.
* Support arbitrary precision arithmetic.
* Add snippet generator.
> 10 votes

# Answer
# Deadfish

```
function run() {
  var code = document.getElementById("code").value
  var unicode = document.getElementById("unicode").checked
  var n = 0
  var output = ""

  for (var i = 0; i < code.length; ++i) {
    switch (code[i]) {
      case "i":
        n++
        break
      case "d":
        n--
        break
      case "s":
        n *= n
        break
      case "o":
        if (unicode) {
          output += String.fromCharCode(n)
        } else {
          output += n
          output += "\n"
        }
        break
      default:
        output += "\n"
    }

    if (n == -1 || n == 256) {
      n = 0
    }
  }

  document.getElementById('output').value = output
}
```

```

    Code:

    <textarea id="code" rows="8" style="overflow:scroll;overflow-x:hidden;width:90%;" wrap="hard">iiisdsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddsdddddodddddodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddddsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiioiiiiiiofdddddddddddddddddddddddddddddddddddddddddddddoiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddsdddddodddddodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddddsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiioiiiiiiofdddddddddddddddddddddddddddddddddddddddddddddoiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiiiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioddddoiiiiiiiiiiiiiiiiioddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiiiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioddddoiiioiioiiioiiiiiiiiiiodddddddddddofddddddddddddddddddddddddddddddddoiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddsdddddodddddodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddddsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiioiiiiiio</textarea>

      <input id="unicode" type="checkbox" checked="true" />Use ASCII/Unicode mode

    Output:

    <textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>

    <input id='run' type='button' value='Run' onclick='run()' />

```

To pre-initialise the code box, just put something in between the textarea tags. Similarly, by adding `checked="true"` in the checkbox tag, you can have ASCII/Unicode mode on by default (as seen above).

Note that Deadfish itself doesn't actually have ASCII output in its original spec, I just put it in for questions which may allow "the next closest thing". If you're concerned that a question's rules may not allow Deadfish because of this, you can always look at something like Deadfish~ which does have ASCII output.

The example shown is from the Happy Birthday topic.
> 9 votes

# Answer
# Deadfish

This does not conform strictly to the requirement, it is my vision on how we could make use of Stack Snippets.

I don't like the amount of boilerplate, especially the need to include custom HTML for another Run button.

In my vision:

* place a single `<script>` tag to include a simple framework and the actual interpreter
* put the script in the CSS area (syntax highlighting may go horrible)
* use the existing Run code snippet button to run the code
* get the output in the snippet frame

For now not decided how would be nicer to specify the input.

```
iiisdsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddsdddddodddddodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddddsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiioiiiiiio
dddddddddddddddddddddddddddddddddddddddddddddoiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddsdddddodddddodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddddsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiioiiiiiio
dddddddddddddddddddddddddddddddddddddddddddddoiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiiiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioddddoiiiiiiiiiiiiiiiiioddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiiiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioddddoiiioiioiiioiiiiiiiiiiodddddddddddo
ddddddddddddddddddddddddddddddddoiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddsdddddodddddodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddddsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiioiiiiiio
```

```

```
> 8 votes

# Answer
# JavaScript ES7

This allows you to run ES6/7 code in any browser.

The browsers I am sure this works 100% on are: IE 11, Chrome 46, and Safari 7.

This does support array comprehensions (`[for(a in b) c]`)

```
function color(n,e){return~[null,void 0].indexOf(n)?'
'+String(n)+"
":"string"==typeof n?'
"'+n+'"
':"number"==typeof n?'
'+n+"
":"function"==typeof n?'
function
':"undefined"!=typeof n.length?'
'+JSON.stringify(n).replace(/(["'])((?:(?=\\*)\\.|.)*?)\1/g,'$1$2$1').replace(/(\d+)/g,'$1')+"
":'
'+JSON.stringify(n,null,2).replace(/(["'])((?:(?=\\*)\\.|.)*?)\1/g,'$1$2$1').replace(/(\d+)/g,'$1').replace(/\n/g,"
")+"
"}document.getElementById("run").onclick=function(){document.getElementById("Console").innerHTML="";var res="",err=!1;try{res=eval(babel.transform(document.getElementById("code").value).code.split("\n").slice(1).join("\n"))}catch(er){res=er.toString(),err=!0}err?document.getElementById("Console").innerHTML+='
'+res+"
":document.getElementById("Console").innerHTML+=color(res,"implicit")},function(n,e){window.console={log:function(){n.log.apply(n,arguments),document.getElementById("Console").innerHTML+=color(arguments.length-1?Array.prototype.slice.call(arguments):arguments[0],"")},warn:function(){n.warn.apply(n,arguments),document.getElementById("Console").innerHTML+=color(arguments.length-1?Array.prototype.slice.call(arguments):arguments[0],"warn")},error:function(){n.error.apply(n,arguments),document.getElementById("Console").innerHTML+=color(arguments.length-1?Array.prototype.slice.call(arguments):arguments[0],"error")}},window.alert=console.log}(window.console,window.alert);
```

```
@import url(http://fonts.googleapis.com/css?family=Open+Sans:400,300,700);@import url(https://fonts.googleapis.com/css?family=Inconsolata);*{font-family:'Open Sans',Arial,sans-serif;font-size:.9rem}.pre,code,pre,pre *{font-family:Inconsolata,monospace}:not(b,bold,strong){font-weight:300}h1,h2,h3,h4,h5,h6{font-weight:600}h1{font-size:1.4rem}h2{font-size:1.38rem}h3{font-size:1.2rem}h4{font-size:1.15rem}h5{font-size:1.11rem}h6{font-size:1.05rem}b,i,p,span{color:#404040}p{line-height:1.3rem}a{color:#605346;text-decoration:none}a:active{color:#523415}a:visited{color:#74513E}hr{border:none;border-top:1px solid #e0d7c1}blockquote{background:#EDE3D3;border-radius:0 .5rem .5rem 0;padding:.5rem .5rem .5rem 4em;margin:.5rem .2rem}code{background:#EBE7DD;border:1px solid #e0d7c1;padding:.3rem .4rem;border-radius:.2rem}.pre,pre{background:rgba(221,221,221,.3);border-radius:.3rem;padding:.5rem;font-size:1.2rem}ol{counter-reset:ol;list-style:none}li{line-height:1.5rem}ol li:before{content:counter(ol) ". ";counter-increment:ol;font-weight:700}table{background:#f2e8d9;border-radius:.75rem;border-collapse:collapse;table-layout:fixed}table.full>tbody{width:100%}thead>tr:first-child>td{border:none;border-bottom:2px solid #e0cbab!important;font-weight:700;z-index:1;text-align:center}td:not(:first-child){border-left:1px solid #eadbc3;z-index:-1}td:only-child{background:#e6dac7;text-align:center;font-weight:600;padding:.25rem;column-span:all}td{padding:.75rem}tr.sub{background:#EDE3D3}input,textarea{border-radius:.5rem;padding:.25rem;border:none;outline:0;transition:box-shadow .3s ease;background-color:#fff!important;margin:.5rem 0}input:focus,textarea:focus{box-shadow:0 0 5px rgba(81,203,238,1)}textarea{resize:vertical}button,input[type=button]{padding:.3rem .5rem;border-radius:.5rem;background-color:#faebd7;cursor:pointer;border:none;border-bottom:1.5px solid #deb887;outline:0}button:active,input[type=button]:active{border:none;border-top:1.5px solid #deb887;color:#000}
#Console{background-color:#fff;border-radius:.5rem;padding:0;height:auto!important;overflow:scroll;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;min-height:1rem}.out,.out *{font-size:1.1rem;font-family:Inconsoleta,monospace}.out *{padding-left:.3rem}.out{border-top:1px solid #F0F0F0;border-bottom:1px solid #F0F0F0;padding:.7rem 1rem}.string,.string *{color:#C41927!important}.number{color:#1D00CF}.out.implicit:before{content:"<\00B7 ";color:#888;letter-spacing:-2px}.out.error:before,.out.warn:before{display:inline-block;background-size:1.1rem;content:"";width:1.1rem;height:1.1rem}.out.warn:before{background-image:url(http://vihan.org/p/esfiddle/icons/Warn.png)}.out.error:before{background-image:url(http://vihan.org/p/esfiddle/icons/Error.png)}.out.warn,.out.warn *{color:#AA5909;background-color:}.out.implicit,.out.log{border-color:#F0F0F0;background-color:#FFF}.out.error{border-color:#FFD7D8;background-color:#FFEBEB}
body,html{width:100%;height:100%;margin:0}body{background:#F4F3F1;display:-ms-flex;display:-webkit-flex;display:flex;align-items:center;justify-content:center}body>div{background:#EAE8E4;border-radius:.4rem;margin:2rem;padding:1rem;overflow:auto;width:50%;max-height:80%;overflow-x:hidden}label{display:block}.full{width:calc(100% - 1rem);display:inline-block;height:7rem}#input{width:100%}.out.warn  { border-color: #FFEFCC; background-color: #FFFAE1; }
```

```

Code
<textarea id="code" class="full pre" placeholder="Code here">f=n=>n+1;
console.log( f(3) );
console.warn( `Foo` )
console.error( `Bar` );
alert( `Output` );
[ f(1), f(2) ]</textarea><button id="run">Run</button><button onclick="prompt('Link:','http://vihan.org/p/esfiddle?code='+encodeURIComponent(document.getElementById('code').value))">Permalink</button>

Console Output

```

For permalinks, use ESFiddle
> 7 votes

# Answer
# Insomnia

The specs is ambiguous about the semantic of instruction 8 and 9, so they are not implemented.

Feel free to improve it to support instruction 0 to 7. There is also some incomplete code to run the program in slow motion, but it was buggy so I remove it from the interface.

```
function toAsciiValue(t) {
    var i = 0;
    var a = "";
    for (i = 0; i < t.length; i++) {
        a += t.charCodeAt(i);
    }
    return a;
}

// http://stackoverflow.com/questions/1219860/html-encoding-in-javascript-jquery
function escapeHTML(str)
{
    var div = document.createElement('div');
    var text = document.createTextNode(str);
    div.appendChild(text);
    return div.innerHTML;
}

var interpreter = (function () {
    var group;
    var ip;
    var gp;
    var bp;
    var code;
    var halted;
    var tid;
    var output = "";

    function flipbit() {
        group[gp] = group[gp] ^ (1 << bp);
    };

    var commands = {
        0: function () {
            flipbit();
            bp = (bp - 1) & 0x7;
        },
        1: function () {
            flipbit();
            bp = (bp + 1) & 0x7;
        },
        2: flipbit,
        3: function () { gp++; bp = 7; },
        4: function () { gp--; bp = 7; },
        5: function () { output += ~~group[gp]; },
        6: function () { output += String.fromCharCode(~~group[gp]); },
        7: function () {}
    };

    var nonprint = {
        "\0": "NUL",
        "\x01": "SOH",
        "\x02": "STX",
        "\x03": "ETX",
        "\x04": "EOT",
        "\x05": "ENQ",
        "\x06": "ACK",
        "\x07": "BEL",
        "\x08": "BS",
        "\x09": "TAB",
        "\x0a": "LF",
        "\x0b": "VT",
        "\x0c": "FF",
        "\x0d": "CR",
        "\x0e": "SO",
        "\x0f": "SI",
        "\x10": "DLE",
        "\x11": "DC1",
        "\x12": "DC2",
        "\x13": "DC3",
        "\x14": "DC4",
        "\x15": "NAK",
        "\x16": "SYN",
        "\x17": "ETB",
        "\x18": "CAN",
        "\x19": "EM",
        "\x1a": "SUB",
        "\x1b": "ESC",
        "\x1c": "FS",
        "\x1d": "GS",
        "\x1e": "RS",
        "\x1f": "US",
        "\x7f": "DEL",
        "\x80": "PAD",
        "\x81": "HOP",
        "\x82": "BPH",
        "\x83": "NBH",
        "\x84": "IND",
        "\x85": "NEL",
        "\x86": "SSA",
        "\x87": "ESA",
        "\x88": "HTS",
        "\x89": "HTJ",
        "\x8a": "LTS",
        "\x8b": "PLD",
        "\x8c": "PLU",
        "\x8d": "RI",
        "\x8e": "SS2",
        "\x8f": "SS3",
        "\x90": "DCS",
        "\x91": "PU1",
        "\x92": "PU2",
        "\x93": "STS",
        "\x94": "CCH",
        "\x95": "MW",
        "\x96": "SPA",
        "\x97": "EPA",
        "\x98": "SOS",
        "\x99": "SGCI",
        "\x9a": "SCI",
        "\x9b": "CSI",
        "\x9c": "ST",
        "\x9d": "OSC",
        "\x9e": "PM",
        "\x9f": "APC"
    }

    function exec(opcode) {
        var instruction = commands[opcode];
        if (typeof instruction === "function") {
            instruction();
        } else {
            halted = true;
            alert("Unsupported operation: " + opcode + ". Execution halted.");
        }
    }

    return {
        init: function (src) {
            group = [];
            ip = 0;
            gp = 0;
            bp = 7;
            halted = false;
            code = toAsciiValue(src);
            output = "";
            tid = void 0;

            this.update();
        },
        output: function () {
            return output;
        },
        update: function () {
            var dispCode = code + " ";
            document.getElementById('execcode').innerHTML =
                dispCode.substring(0, ip) + "" + dispCode[ip] + "" + dispCode.substring(ip + 1);

            document.getElementById('output').innerHTML =
                escapeHTML(output).replace(/[\x00-\x1f\x7f-\x9f]/g, function ($0) {
                    return "" + nonprint[$0] + "";
                });

            document.getElementById('gp').textContent = gp;
            document.getElementById('bp').textContent = bp;

            var dispByte = ("0000000" + (~~group[gp]).toString(2)).substr(-8);
            document.getElementById('currgr').innerHTML =
                dispByte.substring(0, 7 - bp) + "" + dispByte[7 - bp] + "" + dispByte.substring(8 - bp);
        },
        step: function () {
            if (ip >= code.length) {
                alert("The program has terminated. Reload the program to run from the beginning.");
                return;
            }

            if (halted) {
                alert("Execution has been halted and cannot be recovered");
                return;
            }

            exec(code[ip]);
            if (!halted) {
                ip++;
                this.update();
            }
        },
        slow: function () {
            // TODO: Complete this feature. May need to modify run and step.
            if (typeof tid == "number") {
                clearTimeout(tid);
                tid = void 0;
            } else {
                (function auto() {
                    if (!halted && ip = code.length) {
                alert("The program has terminated. Reload the program to run from the beginning.");
                return;
            }

            if (halted) {
                alert("Execution has been halted and cannot be recovered");
                return;
            }

            while (ip < code.length) {
                exec(code[ip]);

                if (!halted) {
                    ip++;
                } else {
                    // Break out of the loop and update the UI
                    break;
                }
            }

            this.update();
        }
    }
})();

document.addEventListener('DOMContentLoaded', function () {

    var $ascii = document.getElementById("ascii");
    var $workspace = document.getElementById("workspace");

    $ascii.textContent = toAsciiValue($workspace.value);

    $workspace.onkeypress = $workspace.onkeyup = function () {
        $ascii.textContent = toAsciiValue(this.value);
    }

    interpreter.init('');

    document.getElementById("load").onclick = function () {
        interpreter.init($workspace.value);
    }

    document.getElementById("run").onclick = function () {
        interpreter.run();
    }

    document.getElementById("step").onclick = function () {
        interpreter.step();
    }

});
```

```
body {
    font-family: 'Franklin Gothic Book', 'Trebuchet MS', 'Arial', sans-serif;
}

.code {
    font-family: monospace;
    word-wrap: break-word;
    white-space: pre-wrap;
}

pre.code, textarea.code {
    width: 100%;
}

table th {
    padding: 0 10px;
}

table .code {
    width: 100px;
    text-align: center;
}

td {
    border: 1px solid;
}

.highlight {
    background: pink;
}

.non-printable {
    background: black;
    color: white;
    border-radius: 4px;
    margin: 0 1px;
    padding: 0 1px;
}

.box {
    border: 2px groove;
    height: 6em;
}
```

```

Insomnia[?]

Currently only supports commands 0-7. Semantics of command 8 and 9 (WHILE loop) is not clearly understood, so it is not implemented.

This interpreter is greatly inspired by Ian's Befunge-93 interpreter.

Source code

<textarea cols="80" rows="5" id="workspace" class="code"></textarea>

ASCII sequence

<input type="button" id="load" value="Load program" />

Execution

<input type="button" id="run" value="Run" />
<input type="button" id="step" value="Step" />

Debug

    Group Pointer

    Bit Pointer

    Current group

Output

```
> 6 votes

# Answer
# HQ9+

Since Calvin's Hobbies even used HQ9+ as an example, I decided to write a quick implementation for it. Well, partial implementation, as I decided to leave out the accumulator (you may hate me for that).

The interpreter is, let's say, partially golfed. I don't know why I sort of golfed it, but not really.

```
(function () {
    var bottles = (function beerMe(amount) {
        return "012, 01.\n3, 412.5".replace(/\d/g, function (c) {
            return [amount || "No more", " bottles of beer", " on the wall", amount ? "Take one down, pass it around" : "Go to the store and buy some more", ((amount || 100) - 1) || "no more", amount ? "\n\n" : ""][c];
        }) + (amount ? beerMe(amount - 1) : "");
    })(99);

    document.getElementById('run').onclick = function () {
        var source = document.getElementById('source').value,
            output = '';
        source.split('').forEach(function (command) {
            var index = ['H', 'Q', '9'].indexOf(command);
            (index + 1 && (output += ['Hello, world!', source, bottles][index], !0)) || alert('illegal command: ' + command);
        });

        document.getElementById('stdout').value = output;
    };
})();
```

```
#source, #stdout {
    display: block;
    width: 100%;
}

#stdout {
    white-space: pre;
    height: 50px;
}

#stdout, #run {
    margin-top: 3px;
}
```

```

    <input type="text" id="source" placeholder="Enter your HQ9+ program here" />
    <textarea id="stdout" wrap="off" readonly></textarea>
    <input type="button" id="run" value="Execute HQ9+" />

```
> 5 votes

# Answer
# Whitespace

```
function interpret() {
    function num(sign, bits) { return sign * parseInt(bits.replace("S", "0").replace("T", "1"), 2); }
    var prog = document.getElementById("prog").value, esc = document.getElementById("esc").checked;
    if (!esc)
        prog = prog.replace(" ", "S").replace("\t", "T").replace("\n", "L");
    prog = prog.replace(/[^STL]/g, "");
    var stack = [], labels = {}, heap = [], input = document.getElementById("in").value, output = document.getElementById("out"), inPos = 0, callStack = [];
    for (var i = 0; i < prog.length; i++) {
        switch (prog[i]) {
            case "S":
                switch (prog[++i]) {
                    case "S":
                        stack.push(num(prog[++i] == "S" ? 1 : -1, prog.slice(++i, prog.indexOf("L", i) - 1)));
                        i = prog.indexOf("L", i);
                        break;
                    case "T":
                        switch (prog[++i]) {
                            case "S":
                                stack.push(stack[stack.length - num(prog[++i] == "S" ? 1 : -1, prog.slice(++i, prog.indexOf("L", i) - 1))]);
                                i = prog.indexOf("L", i);
                                break;
                            case "L":
                                var num = num(prog[++i] == "S" ? 1 : -1, prog.slice(++i, prog.indexOf("L", i) - 1));
                                i = prog.indexOf("L", i);
                                stack.splice(stack.length - num - 1, num);
                                break;
                        }
                        break;
                    case "L":
                        switch (prog[++i]) {
                            case "S":
                                stack.push(stack[stack.length - 1]);
                                break;
                            case "T":
                                stack.push.apply(stack, stack.slice(-2).reverse());
                                break;
                            case "L":
                                stack.pop();
                                break;
                        }
                        break;
                }
                break;
            case "T":
                switch (prog[++i]) {
                    case "S":
                        switch (prog[++i]) {
                            case "S":
                                switch (prog[++i]) {
                                    case "S":
                                        stack.push(stack.pop() + stack.pop());
                                        break;
                                    case "T":
                                        stack.push(stack.pop() - stack.pop());
                                        break;
                                    case "L":
                                        stack.push(stack.pop() * stack.pop());
                                        break;
                                }
                                break;
                            case "T":
                                switch (prog[++i]) {
                                    case "S":
                                        stack.push(Math.floor(stack.pop() / stack.pop()));
                                        break;
                                    case "T":
                                        stack.push(stack.pop() % stack.pop());
                                        break;
                                }
                                break;
                        }
                        break;
                }
                break;
            case "T":
                switch (prog[++i]) {
                    case "S":
                        heap[stack[stack.length - 2]] = stack.pop();
                        stack.pop();
                        break;
                    case "T":
                        stack.push(heap[stack.pop()]);
                        break;
                }
                break;
            case "L":
                switch (prog[++i]) {
                    case "S":
                        switch (prog[++i]) {
                            case "S":
                                output.value += String.fromCharCode(stack.pop());
                                break;
                            case "T":
                                output.value += stack.pop();
                                break;
                        }
                        break;
                    case "T":
                        switch (prog[++i]) {
                            case "S":
                                heap[stack.pop()] = input.charCodeAt(inPos++);
                                break;
                            case "T":
                                heap[stack.pop()] = parseInt(input.slice(inPos, input.indexOf("\n", inPos) - 1));
                                break;
                        }
                }
                break;
            case "L":
                switch (prog[++i]) {
                    case "S":
                        switch (prog[++i]) {
                            case "S":
                                labels[num(1, prog.slice(++i, prog.indexOf("L", i) - 1))] = i = prog.indexOf("L", i);
                                break;
                            case "T":
                                callStack.push(prog.indexOf("L", ++i));
                                i = labels[num(1, prog.slice(i, prog.indexOf("L", i) - 1))];
                                break;
                            case "L":
                                i = labels[num(1, prog.slice(++i, prog.indexOf("L", i) - 1))];
                                break;
                        }
                        break;
                    case "T":
                        switch (prog[++i]) {
                            case "S":
                                if (stack.pop() == 0)
                                    i = labels[num(1, prog.slice(++i, prog.indexOf("L", i) - 1))];
                                else
                                    i = prog.indexOf("L", ++i);
                                break;
                            case "T":
                                if (stack.pop() < 0)
                                    i = labels[num(1, prog.slice(++i, prog.indexOf("L", i) - 1))];
                                else
                                    i = prog.indexOf("L", ++i);
                                break;
                        }
                        break;
                    case "L":
                        i = callStack.pop();
                        break;
                }
                break;
            case "L":
                if (prog[++i] == "L")
                    return JSON.stringify(stack);
                break;
        }
    }
    return JSON.stringify(stack);
}
```

```
Program:

<textarea id="prog" rows="4" cols="60"></textarea>

Input:

<textarea id="in" rows="4" cols="60"></textarea>

<form>
    Is escaped as STL: <input id="esc" type="checkbox"/>

</form>
<button onclick="document.getElementById('stack').innerText = interpret()">Interpret</button>

Output:

<textarea id="out" rows="4" cols="60"></textarea>

Resulting stack:
```
> 5 votes

# Answer
# Beam

I really think this language deserved to have an interpreter and it appeared simple enough for a non programmer like me to have a go at. I hope that I got it right. It appears to work for the examples I have tried. A lot of the code is plagiarized from other answers in this question. My apologies to the real programmers out there if I have committed any cardinal sins in my code:)

I have put the 'Reverse STDIN' example in from the Esolangs page.

```
var ITERS_PER_SEC = 100000;
var TIMEOUT_SECS = 50;
var ERROR_INTERRUPT = "Interrupted by user";
var ERROR_TIMEOUT = "Maximum iterations exceeded";
var ERROR_LOSTINSPACE = "Beam is lost in space";

var code, store, beam, ip_x, ip_y, dir, input_ptr, mem;
var input, timeout, width, iterations, running;

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("timeout").disabled = false;
}

function interrupt() {
error(ERROR_INTERRUPT);
}

function error(msg) {
document.getElementById("stderr").innerHTML = msg;
stop();
}

function run() {
clear_output();
document.getElementById("run").disabled = true;
document.getElementById("stop").disabled = false;
document.getElementById("clear").disabled = true;
document.getElementById("input").disabled = false;
document.getElementById("timeout").disabled = false;

code = document.getElementById("code").value;
input = document.getElementById("input").value;
timeout = document.getElementById("timeout").checked;

code = code.split("\n");
width = 0;
for (var i = 0; i  width){
  width = code[i].length;
 }
}
console.log(code);
console.log(width);

running = true;
dir = 0;
ip_x = 0;
ip_y = 0;
input_ptr = 0;
beam = 0;
store = 0;
mem = [];

input = input.split("").map(function (s) {
  return s.charCodeAt(0);
 });

iterations = 0;

beam_iter();
}

function beam_iter() {
while (running) {
 var inst;
 try {
  inst = code[ip_y][ip_x];
 }
 catch(err) {
  inst = "";
 }
 switch (inst) {
  case ">":
   dir = 0;
   break;
  case "<":
   dir = 1;
   break;
  case "^":
   dir = 2;
   break;
  case "v":
   dir = 3;
   break;
  case "+":
   if(++beam > 255)
    beam = 0;
   break;
  case "-":
   if(--beam < 0)
    beam = 255;
   break;
  case "@":
   document.getElementById("output").value += String.fromCharCode(beam);
   break;
  case ":":
   document.getElementById("output").value += beam;
   break;
  case "/":
   dir ^= 2;
   break;
  case "\\":
   dir ^= 3;
   break;
  case "!":
   if (beam != 0) {
    dir ^= 1;
   }
   break;
  case "?":
   if (beam == 0) {
    dir ^= 1;
   }
   break;
  case "_":
   switch (dir) {
   case 2:
    dir = 3;
    break;
   case 3:
    dir = 2;
    break;
   }
   break;
  case "|":
   switch (dir) {
   case 0:
    dir = 1;
    break;
   case 1:
    dir = 0;
    break;
   }
   break;
  case "H":
   stop();
   break;
  case "S":
   store = beam;
   break;
  case "L":
   beam = store;
   break;
  case "s":
   mem[beam] = store;
   break;
  case "g":
   store = mem[beam];
   break;
  case "P":
   mem[store] = beam;
   break;
  case "p":
   beam = mem[store];
   break;
  case "u":
   if (beam != store) {
    dir = 2;
   }
   break;
  case "n":
   if (beam != store) {
    dir = 3;
   }
   break;
  case "`":
   --store;
   break;
  case "'":
   ++store;
   break;
  case ")":
   if (store != 0) {
    dir = 1;
   }
   break;
  case "(":
   if (store != 0) {
    dir = 0;
   }
   break;
  case "r":
   if (input_ptr >= input.length) {
    beam = 0;
   } else {
    beam = input[input_ptr];
    ++input_ptr;
   }
   break;
  }
 // Move instruction pointer
 switch (dir) {
  case 0:
   ip_x++;
   break;
  case 1:
   ip_x--;
   break;
  case 2:
   ip_y--;
   break;
  case 3:
   ip_y++;
   break;
 }
 if (running && (ip_x < 0 || ip_y < 0 || ip_x >= width || ip_y >= code.length)) {
  error(ERROR_LOSTINSPACE);
 }
 ++iterations;
 if (iterations > ITERS_PER_SEC * TIMEOUT_SECS) {
  error(ERROR_TIMEOUT);
 }
}
}
```

```

Code:

    <textarea id="code" rows="8" style="overflow:scroll;overflow-x:hidden;width:90%;">v
(>``v
!  H(p`@`p)H
P   H
'
r
'
P
!
>^
 </textarea>

Input:

    <textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;">Reverse this string</textarea>

Timeout:
        <input id="timeout" type="checkbox" checked="checked">

        <input id="run" type="button" value="Run" onclick="run()">
        <input id="stop" type="button" value="Stop" onclick="interrupt()" disabled="disabled">
        <input id="clear" type="button" value="Clear" onclick="clear_output()">

Output:

    <textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>

```
> 5 votes

# Answer
# Ouroboros

An esoteric language created by me, DLosc, in October 2015. The execution model is based on each line of code being an ouroboros snake. Control proceeds from the head to the tail and loops back to the head; instructions allow the snake to swallow part of its tail or regurgitate what it has swallowed, thus changing the flow of execution. All snakes execute in parallel. Data is stored on a shared stack as well as an individual stack for each snake. For more information, sample programs, and the most up-to-date interpreter, see the Github repository.

```
// Define Stack class
function Stack() {
  this.stack = [];
  this.length = 0;
}
Stack.prototype.push = function(item) {
  this.stack.push(item);
  this.length++;
}
Stack.prototype.pop = function() {
  var result = 0;
  if (this.length > 0) {
    result = this.stack.pop();
    this.length--;
  }
  return result;
}
Stack.prototype.top = function() {
  var result = 0;
  if (this.length > 0) {
    result = this.stack[this.length - 1];
  }
  return result;
}
Stack.prototype.toString = function() {
  return "" + this.stack;
}

// Define Snake class
function Snake(code) {
  this.code = code;
  this.length = this.code.length;
  this.ip = 0;
  this.ownStack = new Stack();
  this.currStack = this.ownStack;
  this.alive = true;
  this.wait = 0;
  this.partialString = this.partialNumber = null;
}
Snake.prototype.step = function() {
  if (!this.alive) {
    return null;
  }
  if (this.wait > 0) {
    this.wait--;
    return null;
  }
  var instruction = this.code.charAt(this.ip);
  var output = null;
  console.log("Executing instruction " + instruction);
  if (this.partialString !== null) {
    // We're in the middle of a double-quoted string
    if (instruction == '"') {
      // Close the string and push its character codes in reverse order
      for (var i = this.partialString.length - 1; i >= 0; i--) {
        this.currStack.push(this.partialString.charCodeAt(i));
      }
      this.partialString = null;
    } else {
      this.partialString += instruction;
    }
  } else if (instruction == '"') {
    this.partialString = "";
  } else if ("0" <= instruction && instruction <= "9") {
    if (this.partialNumber !== null) {
      this.partialNumber = this.partialNumber + instruction;  // NB: concatenation!
    } else {
      this.partialNumber = instruction;
    }
    next = this.code.charAt((this.ip + 1) % this.length);
    if (next < "0" || "9" < next) {
      // Next instruction is non-numeric, so end number and push it
      this.currStack.push(+this.partialNumber);
      this.partialNumber = null;
    }
  } else if ("a" <= instruction && instruction <= "f") {
    // a-f push numbers 10 through 15
    var value = instruction.charCodeAt(0) - 87;
    this.currStack.push(value);
  } else if (instruction == "$") {
    // Toggle the current stack
    if (this.currStack === this.ownStack) {
      this.currStack = this.program.sharedStack;
    } else {
      this.currStack = this.ownStack;
    }
  } else if (instruction == "s") {
    this.currStack = this.ownStack;
  } else if (instruction == "S") {
    this.currStack = this.program.sharedStack;
  } else if (instruction == "l") {
    this.currStack.push(this.ownStack.length);
  } else if (instruction == "L") {
    this.currStack.push(this.program.sharedStack.length);
  } else if (instruction == ".") {
    var item = this.currStack.pop();
    this.currStack.push(item);
    this.currStack.push(item);
  } else if (instruction == "m") {
    var item = this.ownStack.pop();
    this.program.sharedStack.push(item);
  } else if (instruction == "M") {
    var item = this.program.sharedStack.pop();
    this.ownStack.push(item);
  } else if (instruction == "y") {
    var item = this.ownStack.top();
    this.program.sharedStack.push(item);
  } else if (instruction == "Y") {
    var item = this.program.sharedStack.top();
    this.ownStack.push(item);
  } else if (instruction == "\\") {
    var top = this.currStack.pop();
    var next = this.currStack.pop()
    this.currStack.push(top);
    this.currStack.push(next);
  } else if (instruction == "@") {
    var c = this.currStack.pop();
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(b);
    this.currStack.push(c);
    this.currStack.push(a);
  } else if (instruction == ";") {
    this.currStack.pop();
  } else if (instruction == "+") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a + b);
  } else if (instruction == "-") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a - b);
  } else if (instruction == "*") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a * b);
  } else if (instruction == "/") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a / b);
  } else if (instruction == "%") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a % b);
  } else if (instruction == "_") {
    this.currStack.push(-this.currStack.pop());
  } else if (instruction == "I") {
    var value = this.currStack.pop();
    if (value < 0) {
      this.currStack.push(Math.ceil(value));
    } else {
      this.currStack.push(Math.floor(value));
    }
  } else if (instruction == ">") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(+(a > b));
  } else if (instruction == "<") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(+(a < b));
  } else if (instruction == "=") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(+(a == b));
  } else if (instruction == "!") {
    this.currStack.push(+ !this.currStack.pop());
  } else if (instruction == "?") {
    this.currStack.push(Math.random());
  } else if (instruction == "n") {
    output = "" + this.currStack.pop();
  } else if (instruction == "o") {
    output = String.fromCharCode(this.currStack.pop());
  } else if (instruction == "r") {
    var input = this.program.io.getNumber();
    this.currStack.push(input);
  } else if (instruction == "i") {
    var input = this.program.io.getChar();
    this.currStack.push(input);
  } else if (instruction == "(") {
    this.length -= Math.floor(this.currStack.pop());
    this.length = Math.max(this.length, 0);
  } else if (instruction == ")") {
    this.length += Math.floor(this.currStack.pop());
    this.length = Math.min(this.length, this.code.length);
  } else if (instruction == "w") {
    this.wait = this.currStack.pop();
  }
  // Any unrecognized character is a no-op
  if (this.ip >= this.length) {
    // We've swallowed the IP, so this snake dies
    this.alive = false;
    this.program.snakesLiving--;
  } else {
    // Increment IP and loop if appropriate
    this.ip = (this.ip + 1) % this.length;
  }
  return output;
}
Snake.prototype.getHighlightedCode = function() {
  var result = "";
  for (var i = 0; i < this.code.length; i++) {
    if (i == this.length) {
      result += '';
    }
    if (i == this.ip) {
      if (this.wait > 0) {
        result += '';
      } else {
        result += '';
      }
      result += escapeEntities(this.code.charAt(i)) + '';
    } else {
      result += escapeEntities(this.code.charAt(i));
    }
  }
  if (this.length < this.code.length) {
    result += '';
  }
  return result;
}

// Define Program class
function Program(source, speed, io) {
  this.sharedStack = new Stack();
  this.snakes = source.split(/\r?\n/).map(function(snakeCode) {
    var snake = new Snake(snakeCode);
    snake.program = this;
    snake.sharedStack = this.sharedStack;
    return snake;
  }.bind(this));
  this.snakesLiving = this.snakes.length;
  this.io = io;
  this.speed = speed || 10;
  this.halting = false;
}
Program.prototype.run = function() {
  this.step();
  if (this.snakesLiving) {
    this.timeout = window.setTimeout(this.run.bind(this), 1000 / this.speed);
  }
}
Program.prototype.step = function() {
   for (var s = 0; s < this.snakes.length; s++) {
    var output = this.snakes[s].step();
    if (output) {
      this.io.print(output);
    }
  }
  this.io.displaySource(this.snakes.map(function (snake) {
      return snake.getHighlightedCode();
    }).join("
"));
 }
Program.prototype.halt = function() {
  window.clearTimeout(this.timeout);
}

var ioFunctions = {
  print: function (item) {
    var stdout = document.getElementById('stdout');
    stdout.value += "" + item;
  },
  getChar: function () {
    if (inputData) {
      var inputChar = inputData[0];
      inputData = inputData.slice(1);
      result = inputChar.charCodeAt(0);
    } else {
      result = -1;
    }
    var stdinDisplay = document.getElementById('stdin-display');
    stdinDisplay.innerHTML = escapeEntities(inputData);
    return result;
  },
  getNumber: function () {
    while (inputData && (inputData[0] < "0" || "9" < inputData[0])) {
      inputData = inputData.slice(1);
    }
    if (inputData) {
      var inputNumber = inputData.match(/\d+/)[0];
      inputData = inputData.slice(inputNumber.length);
      result = +inputNumber;
    } else {
      result = -1;
    }
    var stdinDisplay = document.getElementById('stdin-display');
    stdinDisplay.innerHTML = escapeEntities(inputData);
    return result;
  },
  displaySource: function (formattedCode) {
    var sourceDisplay = document.getElementById('source-display');
    sourceDisplay.innerHTML = formattedCode;
  }
};
var program = null;
var inputData = null;
function showEditor() {
  var source = document.getElementById('source'),
    sourceDisplayWrapper = document.getElementById('source-display-wrapper'),
    stdin = document.getElementById('stdin'),
    stdinDisplayWrapper = document.getElementById('stdin-display-wrapper');

  source.style.display = "block";
  stdin.style.display = "block";
  sourceDisplayWrapper.style.display = "none";
  stdinDisplayWrapper.style.display = "none";

  source.focus();
}
function hideEditor() {
  var source = document.getElementById('source'),
    sourceDisplay = document.getElementById('source-display'),
    sourceDisplayWrapper = document.getElementById('source-display-wrapper'),
    stdin = document.getElementById('stdin'),
    stdinDisplay = document.getElementById('stdin-display'),
    stdinDisplayWrapper = document.getElementById('stdin-display-wrapper');

  source.style.display = "none";
  stdin.style.display = "none";
  sourceDisplayWrapper.style.display = "block";
  stdinDisplayWrapper.style.display = "block";

  var sourceHeight = getComputedStyle(source).height,
    stdinHeight = getComputedStyle(stdin).height;
  sourceDisplayWrapper.style.minHeight = sourceHeight;
  sourceDisplayWrapper.style.maxHeight = sourceHeight;
  stdinDisplayWrapper.style.minHeight = stdinHeight;
  stdinDisplayWrapper.style.maxHeight = stdinHeight;
  sourceDisplay.textContent = source.value;
  stdinDisplay.textContent = stdin.value;
}
function escapeEntities(input) {
  return input.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
}
function resetProgram() {
  var stdout = document.getElementById('stdout');
  stdout.value = null;
  if (program !== null) {
    program.halt();
  }
  program = null;
  inputData = null;
  showEditor();
}
function initProgram() {
  var source = document.getElementById('source'),
    stepsPerSecond = document.getElementById('steps-per-second'),
    stdin = document.getElementById('stdin');
  program = new Program(source.value, +stepsPerSecond.innerHTML, ioFunctions);
  hideEditor();
  inputData = stdin.value;
}
function runBtnClick() {
  if (program === null || program.snakesLiving == 0) {
    resetProgram();
    initProgram();
  } else {
    program.halt();
    var stepsPerSecond = document.getElementById('steps-per-second');
    program.speed = +stepsPerSecond.innerHTML;
  }
  program.run();
}
function stepBtnClick() {
  if (program === null) {
    initProgram();
  } else {
    program.halt();
  }
  program.step();
}
function sourceDisplayClick() {
  resetProgram();
}
```

```
.container {
    width: 100%;
}
.so-box {
    font-family:'Helvetica Neue', Arial, sans-serif;
    font-weight: bold;
    color: #fff;
    text-align: center;
    padding: .3em .7em;
    font-size: 1em;
    line-height: 1.1;
    border: 1px solid #c47b07;
    -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3), 0 2px 0 rgba(255, 255, 255, 0.15) inset;
    text-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
    background: #f88912;
    box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3), 0 2px 0 rgba(255, 255, 255, 0.15) inset;
}
.control {
    display: inline-block;
    border-radius: 6px;
    float: left;
    margin-right: 25px;
    cursor: pointer;
}
.option {
    padding: 10px 20px;
    margin-right: 25px;
    float: left;
}
h1 {
    text-align: center;
    font-family: Georgia, 'Times New Roman', serif;
}
a {
    text-decoration: none;
}
input, textarea {
    box-sizing: border-box;
}
textarea {
    display: block;
    white-space: pre;
    overflow: auto;
    height: 100px;
    width: 100%;
    max-width: 100%;
    min-height: 25px;
}
span[contenteditable] {
    padding: 2px 6px;
    background: #cc7801;
    color: #fff;
}
#stdout-container, #stdin-container {
    height: auto;
    padding: 6px 0;
}
#reset {
    float: right;
}
#source-display-wrapper , #stdin-display-wrapper{
    display: none;
    width: 100%;
    height: 100%;
    overflow: auto;
    border: 1px solid black;
    box-sizing: border-box;
}
#source-display , #stdin-display{
    font-family: monospace;
    white-space: pre;
    padding: 2px;
}
.activeToken {
    background: #f93;
}
.nextActiveToken {
    background: #bbb;
}
.swallowedCode{
    color: #999;
}
.clearfix:after {
    content:".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}
.clearfix {
    display: inline-block;
}
* html .clearfix {
    height: 1%;
}
.clearfix {
    display: block;
}
```

```

Ouroboros

    <textarea id="source" placeholder="Enter your program here" wrap="off"></textarea>

    <textarea id="stdin" placeholder="Input" wrap="off"></textarea>

    <input type="button" id="run" class="control so-box" value="Run" onclick="runBtnClick()" />
    <input type="button" id="pause" class="control so-box" value="Pause" onclick="program.halt()" />
    <input type="button" id="step" class="control so-box" value="Step" onclick="stepBtnClick()" />
    <input type="button" id="reset" class="control so-box" value="Reset" onclick="resetProgram()" />

    <textarea id="stdout" placeholder="Output" wrap="off" readonly></textarea>

Steps per Second: 10

```

## Todo

* Debug output: contents of stacks; ~~how much input is left~~ **done**
* ~~During execution, display code with current instructions highlighted and swallowed portions of tails grayed-out~~ **done**
> 5 votes

# Answer
# K5

This is a thin, simple wrapper around my JavaScript based K implementation, oK, and references the github repo. I've already built a much nicer browser-based frontend. oK implements a very substantial portion of K5, aside from IO, and has been used in the past to solve a number of problems here on stack overflow. The code isn't golfed, per se, but is well under 1000 lines including comments, the parser, all the primitive operations, the interpreter and the prettyprinter.

```
* {
  font-size:12px;
  font-family:Verdana, Geneva, sans-serif;
}
textarea {
  overflow:scroll;
  overflow-x:hidden;
  width:90%;
  font-family:Consolas, Courier New, monospace;
  font-size:10p
}
```

```

Code:

<textarea id="code" rows="8">2*!10</textarea>

<input id="run" type="button" value="Run" onclick="runk()">

Output:

<textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>
```
> 5 votes

# Answer
# 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.

```
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  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);
}
```

```

    Code:

    <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>

Input:

    <textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;"></textarea>

      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>

    Output:

    <textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>

      <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()" />

```
> 4 votes

# Answer
## STATA

Edit: added replace and checks for generate.

Has support for some parts of display, forvalues, list, generate, and set obs. In addition, it has some supports for macro (STATA's variables) creation and use. It supports enough operations for some of the simpler answers that have been posted on this site, such as Evolution of "Hello World!", Generate the Stöhr sequence, Make me an alphabet tree (replace single quotes with double quotes and make it 3 lines instead of 1). This is a work in progress, and I hope to continue it soon, but I figured I would at least put something here for now.

```

Input
<textarea id="input"></textarea>

Code
<textarea id="code"></textarea>

<button>Run</button>

Output:
<textarea id="output"></textarea>

```
> 4 votes

# Answer
# Fourier

This is now a complete version of Fourier, translated directly from the Python. This should stay up to date.

```
<!DOCTYPE html>   <title>FourIDE - Editor</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
Fourier Interpreter

Code:
 <textarea id="code" rows="4" oninput="javascript:chars()" cols="40"></textarea>
 Function: <select id="funcSelect"> <option value="exec">Execute code</option> <option value="expl">Explode code</option> <option value="debg">Debug code</option> </select>

Input:
 <textarea id="input" rows="4" cols="40"></textarea>

 <button id="run" onclick="javascript:main()">Engage</button> <button id="clear" onclick="javascript:clearText()">Clear</button>
 Character count: 0 characters
Output:
 <textarea id="output" readonly="readonly" rows="4" cols="40" style="cursor: default;"></textarea>
 Get permalink

Character reference

ASCII code reference
 <input id="charRef" cols="40" oninput="javascript:getCharCode()">
 <input id="asciiRef" readonly="readonly" cols="40" style="background-color: #c2c2c2; cursor: default;">
```

### See more:
> 4 votes

# Answer
# Labyrinth

An interpreter for Labyrinth, a totally awesome language! (My interpreter doesn't have big integers...)

```
/*jshint esnext: true */
//Note labyrinth X Y are swapped!
//Syntax highlighting?
//Bigint library?
//Use: https://developers.google.com/web/updates/2014/05/Web-Animations-element.animate-is-now-in-Chrome-36
//Save option
//a => ASCII code (Explanation of the commands)

var p; //pointer
var labyrinth; //code
var main, auxiliary; //stacks, main.length-1=top
var direction; //N=0,E=1,S=2,W=3;
var inpLoc;
var sucide;
var step;
var debug;

var spiders = false;

var pointerIcons = ["▲", "►", "▼", "◄", "X"];

function mod(x, y) {
  return ((x % y) + y) % y;
}

Array.prototype.top = function() {
  if (this.length === 0) {
    return 0;
  }
  return this[this.length - 1];
};

Array.prototype._pop = Array.prototype.pop;
Array.prototype.pop = function(x) {
  var temp = this._pop();
  return temp !== undefined ? temp : 0;
};

function reset() {
  p = [0, 0];
  labyrinth = lab.innerHTML.replace(/\[/g, " ").replace(/\]/g, " ").replace(/</g, "<").replace(/>/g, ">").replace(/\n*$|(
)*$/, "").split(/
|\n/g);
  var maxLength = 0;
  for (var i = 0; i < labyrinth.length; i++) {
    if (maxLength < labyrinth[i].length)
      maxLength = labyrinth[i].length;
  }

  for (i = 0; i < labyrinth.length; i++) {
    labyrinth[i] = (labyrinth[i] + " ".repeat(maxLength - labyrinth[i].length)).split("");
  }

  //Pointer pos
  loop:
    for (i = 0; i < labyrinth.length; i++) {
      for (j = 0; j < labyrinth[i].length; j++) {
        if (labyrinth[i][j] !== " ") {
          p = [j, i];
          break loop;
        }
      }
    }

  main = [];
  auxiliary = [];
  direction = 1;
  sucide = false;
  inpLoc = 0;
  step = 1;
  O.value = "";
}

function run() {
  reset();
  if (debug) {
    spiderContainer.innerHTML = "";
    debugButton.disabled = false;
    lab.contentEditable = false;
    stepButton.disabled = false;
  }
  //Start if
  if (lab.innerHTML.replace(/\[/g, "").replace(/\]/g, "").replace(/
|\n/g, "") !== "") {
    if (!debug) {
      while (!sucide) {
        updatePointer();
      }
    } else {
      updatePointer();
    }
  } else {
    stepButton.disabled = "disabled";
    lab.contentEditable = "true";
  }
}

function updatePointer() {
  if (sucide) {
    stepButton.disabled = "disabled";
    lab.contentEditable = "true";
    pointerOverlay.innerHTML = "";
    return -1; //End
  }
  stepDiv.innerHTML = step;
  step++;
  execChar(labyrinth[p[1]][p[0]]);

  var ret = updateDirection();
  //If there are walls
  if (ret != -1) {
    direction = mod(direction, 4);

    if (direction === 0) {
      p[1] --;
    } else if (direction == 1) {
      p[0] ++;
    } else if (direction == 2) {
      p[1] ++;
    } else if (direction == 3) {
      p[0] --;
    }
  }
  deb.value =
    "Pointer: " + p +
    "\nCommand: " + labyrinth[p[1]][p[0]] +
    "\nMain [" + main + " | " + auxiliary.slice().reverse() + "] Auxiliary";
  if (debug) {
    pointerOverlay.innerHTML = "\n".repeat(p[1]) + " ".repeat(p[0]) + (pointerIcons[ret == -1 ? 4 : direction]);
  }

}

function updateGrid() {
  lab.innerHTML = "";
  labyrinth.forEach(s => lab.innerHTML += s.join("") + "\n");
}

function rotVert(rotWhich) {
  var temp;
  for (var i = 0; i < labyrinth.length; i++) {
    if (i === 0) {
      temp = labyrinth[0][rotWhich];
    }
    if (i == labyrinth.length - 1) {
      labyrinth[i][rotWhich] = temp;
    } else {
      labyrinth[i][rotWhich] = labyrinth[i + 1][rotWhich];
    }
    if (labyrinth[i][rotWhich] === undefined) {
      labyrinth[i].splice(rotWhich, 1);
    }
  }
}

function rotVert2(rotWhich) {
  var temp;
  for (var i = labyrinth.length - 1; i >= 0; i--) {
    if (i == labyrinth.length - 1) {
      temp = labyrinth[i][rotWhich];
    }
    if (i === 0) {
      labyrinth[i][rotWhich] = temp;
    } else {
      labyrinth[i][rotWhich] = labyrinth[i - 1][rotWhich];
    }
    if (labyrinth[i][rotWhich] === undefined) {
      labyrinth[i].splice(rotWhich, 1);
    }
  }
}

function lookAt(d) {
  if (mod(d, 4) === 0) {
    try {
      return labyrinth[p[1] - 1][p[0]];
    } catch (e) {
      return " ";
    }
  } else if (mod(d, 4) == 1) {
    try {
      return labyrinth[p[1]][p[0] + 1];
    } catch (e) {
      return " ";
    }
  } else if (mod(d, 4) == 2) {
    try {
      return labyrinth[p[1] + 1][p[0]];
    } catch (e) {
      return " ";
    }
  } else if (mod(d, 4) == 3) {
    try {
      return labyrinth[p[1]][p[0] - 1];
    } catch (e) {
      return " ";
    }
  }
}

function isWall(d) {
  if (lookAt(d) == " " || lookAt(d) === undefined) {
    return true;
  } else {
    return false;
  }
}

function updateDirection() {
  var numOfWalls = 0;
  if (!isWall(0)) {
    numOfWalls++;
  }
  if (!isWall(1)) {
    numOfWalls++;
  }
  if (!isWall(2)) {
    numOfWalls++;
  }
  if (!isWall(3)) {
    numOfWalls++;
  }

  if (numOfWalls == 4) {
    if (main.top() < 0) {
      direction -= 1;
    } else if (main.top() > 0) {
      direction += 1;
    }
  } else if (numOfWalls == 3) {
    if (main.top() < 0) {
      direction -= 1;
    } else if (main.top() > 0) {
      direction += 1;
    }
    if (isWall(direction)) {
      direction += 2;
    }
  } else if (numOfWalls == 2) {
    if (isWall(direction + 2)) {
      if (isWall(direction)) {
        //Special case
        if (main.top() < 0) {
          direction -= 1;
        } else if (main.top() > 0) {
          direction += 1;
        } else {
          direction += Math.random() < 0.5 ? -1 : 1;
        }
      } else {
        //Keep moving..
      }
    } else {
      for (var i = 0; i <= 3; i++) {
        if (!isWall(i) && i != mod((direction + 2), 4)) {
          direction = i;
          break;
        }
      }
    }
  } else if (numOfWalls == 1) {
    if (!isWall(0)) {
      direction = 0;
    } else
    if (!isWall(1)) {
      direction = 1;
    } else
    if (!isWall(2)) {
      direction = 2;
    } else
    if (!isWall(3)) {
      direction = 3;
    }
  } else {
    return -1;
  }
}

function execChar(char) {
  var a;
  var b;
  if (/\d/.exec(char)) {
    main.push(main.pop() * 10 + (+char));
  } else switch (char) {
    case '!':
      O.value += main.pop();
      break;
    case '"': //Nothing...
      break;
    case '#':
      main.push(main.length);
      break;
    case '$':
      main.push(main.pop() ^ main.pop());
      break;
    case '%':
      a = main.pop();
      b = main.pop();
      main.push(mod(b, a));
      break;
    case '&':
      main.push(main.pop() & main.pop());
      break;
    case "'":
      //Debug-Unimplemented
      break;
    case '(':
      main.push(main.pop() - 1);
      break;
    case ')':
      main.push(main.pop() + 1);
      break;
    case '*':
      main.push(main.pop() * main.pop());
      break;
    case '+':
      main.push(main.pop() + main.pop());
      break;
    case ',':
      a = I.value.charCodeAt(inpLoc);
      if (Number.isNaN(a)) {
        main.push(-1);
      } else {
        main.push(a);
        inpLoc++;
      }
      break;
    case '-':
      a = main.pop();
      b = main.pop();
      main.push(b - a);
      break;
    case '.':
      O.value += String.fromCharCode(mod(main.pop(), 256));
      break;
    case '/':
      a = main.pop();
      b = main.pop();
      if (a === 0) {
        sucide = true;
        throw "Stop that";
      }
      main.push(Math.floor(b / a));
      break;
    case ':':
      main.push(main.top());
      break;
    case ';':
      main.pop();
      break;
    case '<':
      //MOVE IP
      b = main.pop();
      a = mod(p[1] + b, labyrinth.length);
      labyrinth[a].push(labyrinth[a].shift());
      updateGrid();
      if (b === 0) {
        p[0] = mod(p[0] - 1, labyrinth[a].length);
      }
      break;
    case '=':
      a = main.pop();
      b = auxiliary.pop();
      main.push(b);
      auxiliary.push(a);
      break;
    case '>':
      //MOVE IP
      b = main.pop();
      a = mod(p[1] + b, labyrinth.length);
      labyrinth[a].unshift(labyrinth[a].pop());
      updateGrid();
      if (b === 0) {
        p[0] = mod(p[0] + 1, labyrinth[a].length);
      }
      break;
    case '?':
      try {
        a = I.value.substr(inpLoc);
        b = (+(/[\+-]?\d+/.exec(a)[0]));
        main.push(b);
        inpLoc += a.search(/[\+-]?\d+/) + (b + "").length;
      } catch (e) {
        main.push(0);
        inpLoc = I.value.length;
      }
      break;
    case '@':
      sucide = true;
      break;
    case '\\':
      O.value += "\n";
      break;
    case '^': //Fix!
      b = main.pop();
      labyrinth = transpose(labyrinth);
      a = mod(p[0] + b, labyrinth[p[1]].length);
      labyrinth[a].unshift(labyrinth[a].pop());
      if (b === 0) {
        p[1] = mod(p[1] - 1, labyrinth.length);
      }
      labyrinth = transpose(labyrinth);
      updateGrid();
      break;
    case '_':
      main.push(0);
      break;
    case '`':
      main.push(-main.pop());
      break;
    case 'v': //Fix!
      b = main.pop();
      a = mod(p[0] + b, labyrinth[p[1]].length);
      rotVert2(a);
      updateGrid();
      if (b === 0) {
        p[1] = mod(p[1] + 1, labyrinth.length);
      }
      break;
    case '{':
      main.push(auxiliary.pop());
      break;
    case '|':
      main.push(main.pop() | main.pop());
      break;
    case '}':
      auxiliary.push(main.pop());
      break;
    case '~':
      main.push(~main.pop());
      break;
  }
}

function transpose(array) {
  var newArray = array[0].map(function(col, i) {
    return array.map(function(row) {
      return row[i];
    });
  });
  return newArray;
}

//Spiders
function startDebug() {
  if (spiders && document.cookie.split("youWereHere=")[1] === undefined) {
    document.cookie = "youWereHere=yep";
    debugButton.disabled = 'disabled';
    var spiderImg = document.createElement('img');
    spiderImg.src = "http://i.imgur.com/fsYfS9H.png"; //http://i.imgur.com/PRPmqMJ.gif
    spiderImg.className = "spider";

    var svg = document.createElementNS('http://www.w3.org/2000/svg', 'line');
    svg.setAttribute("stroke-width", 2);
    var rn = Math.random() * 10 + 5;
    for (var i = 0; i < rn; i++) {
      var tempSpider = spiderImg.cloneNode(true);

      var left = Math.min(Math.random() * innerWidth, innerWidth - 50);
      var top = -Math.random() * 300;
      tempSpider.style.left = left - 26 + "px";
      tempSpider.style.top = top - 5 + "px";

      var tempSvg = svg.cloneNode(true);
      tempSvg.setAttribute("y1", top - innerHeight - 100);
      tempSvg.setAttribute("y2", top);
      tempSvg.setAttribute("x1", left);
      tempSvg.setAttribute("x2", left);

      spiderContainer.appendChild(tempSpider);
      svgId.appendChild(tempSvg);
      // Make sure the initial state is applied.
      window.getComputedStyle(tempSpider).transform; // jshint ignore:line
      window.getComputedStyle(tempSvg).transform; // jshint ignore:line

      tempSpider.style.transform = "translateY(" + (innerHeight + 48 + top) + "px)";
      tempSvg.style.transform = "translateY(" + (innerHeight + 48 + top) + "px)";
    }
    setTimeout(fallDown, 2500);
    debug = true;
    setTimeout(run, 4000);
  } else {
    debug = true;
    run();
  }
}

function fallDown() {
  svgId.innerHTML = "";
  var spiders = document.getElementsByClassName("spider");
  for (var i = 0; i < spiders.length; i++) {
    spiders[i].style.top = innerHeight + "px";
  }
}

//Maze proper copy
lab.addEventListener("paste", function(e) {
  // cancel paste
  e.preventDefault();

  // get text representation of clipboard
  var text = e.clipboardData.getData("text/plain");

  // insert text manually
  //document.execCommand("insertHTML", false, text);
  lab.innerHTML = text;
});
```

```
body {
  background: #484848;
}
h3{
  font-family: sans-serif;
  color: white;
  font-weight: bolder;
  margin: 6px;
  margin-bottom: 0px;
}
#inputHeader, #outputHeader, #debugHeader{
  flex: 1;
}
#debugHeader{
  display: none;
}
#deb {
  display: none;
}
.container {
  width: 100%;
  position: relative;
  display: flex;
  flex-flow: row wrap;
}
.container pre,textarea {
  flex: 1;
  min-height: 175px;
  background: #202020;
  color: white;
  border: #202020;
  margin: 6px;
  font: monospace;
  resize: vertical;
}
.container pre[contentEditable=false] {
  cursor: not-allowed;
}

#lab {
  width: 100%;
  min-height: 150px;
}

#pointerOverlay{
  width: 100%;
  position: absolute;
  background: rgba(0,0,0,0);
  /*width: 100%;*/
  resize: vertical;
  height: 200px;
  pointer-events: none;
  color: rgba(255,0,0,0.7);
  left: 0px;
}
button:not(.run) {
  vertical-align: top;
  border: #303030;
  color: white;
  font-weight: bold;
  font-size: 1em;
  letter-spacing: 1px;
  background: #303030;
  cursor: pointer;
  min-width: 100px;
  min-height: 45px;
  margin: 5px;
  line-height: 50px;
}
button:not(.run):hover {
  background: #202020;
}

button:not(.run)[disabled] {
  background: #404040;
  cursor: not-allowed;
}
.buttonImg{
  width: 40px;
  vertical-align: middle;
  transform: translateX(-10px);
}
```

```
<!DOCTYPE html>

  <meta charset="utf-8">
  <title>Labyrinth</title>

  <button onclick="debug=false; run(); deb.style.display = 'none'; debugHeader.style.display = 'none';">Run</button>
  <button id="debugButton" onclick="startDebug(); deb.style.display='flex'; debugHeader.style.display = 'flex';">Debug</button>
  <button id="stepButton" onclick="updatePointer();" disabled>Step: 1
  </button>
  <button onclick="sucide = true; updatePointer();">Stop</button>

Maze:

,)@
.(

Input:

Output:

Debugging:

    <textarea id="I">Labyrinth rocks!</textarea>
    <textarea id="O"></textarea>
    <textarea id="deb"></textarea>

  <svg width="100%" id="svgId">
  </svg>

```

Here is the most up-to-date version: http://output.jsbin.com/cuzoxu
> 4 votes

# Answer
## Unary (to Brainfuck)

Simply converts Unary to Brainfuck. This could very easily be coupled with one of the Brainfuck interpreters to run Unary code directly - no need to reinvent the wheel!

```
function interpret() {
  var result = "";
  var table = "><+-.,[]"
  var option = document.getElementById("option").checked
  var code = document.getElementById("code").value
  var number = option ? parseInt(code, 10) : code.length;
  number = number.toString(2)
  if (number.length % 3 == 1) {
    number = number.slice(1)
    for (var i = 0; i < number.length; i += 3) {
      var instruction = number[i] + number[i + 1] + number[i + 2]
      instruction = parseInt(instruction, 2)
      result += table[instruction];
    }
  } else {
    result = "Error: program binary cannot be split into triplets."
  }
  document.getElementById("result").value = result;
}
```

```
Input as Number of 0's
<input id="option" type="checkbox" />

<input id="code" type="text" style="width:90%;" />

<input id="run" type="button" value="Run!" onclick="interpret()" />

<input id="result" type="text" style="width:90%;" />
```
> 3 votes

# Answer
# Hello++

The easiest language to implement AND learn!

```

Hello++ Interpreter

Code

<textarea id=c></textarea>

<button onclick='o.value="",c.value.replace(/[^h]/ig,"").split("").map(function($){$&&(o.value+="Hello World\n")})'>Say hello to the output!</button>

Output

<textarea id=o readonly></textarea>

```
> 3 votes

# Answer
# CHIQRSX9+

HQ9+ with Turing-completeness. I stuck as closely to the specs as possible.

```
function interpret(c,i){
 c.split('').map(function(v,I){
  if(v=='c'||v=='C')out.push(i);
  else if(v=='h'||v=='H')out.push('Hello, world!\n');
  else if(v=='i'||v=='I')interpret(i,"");
  else if(v=='q'||v=='Q')out.push(c);
  else if(v=='r'||v=='R')out.push(i.replace(/[a-zA-Z]/g,function(C){return String.fromCharCode((C<="Z"?90:122)>=(C=C.charCodeAt(0)+13)?C:C-26);}));
  else if(v=='s'||v=='S')out.push(i.split('\n').sort().join('\n'));
  else if(v=='x'||v=='X')eval(c.split().join(0|Math.random()*256));
  else if(v=='9')for(var o,e,n=100,t=" on the wall";n-->-1;)o=e+t+", "+e+".\n"+(n>-1?"Take one down, pass it around, ":"Go to the store and buy some more, ")+(e=(0>n?99:n||"no more")+" bottle"+(1!=n?"s":"")+" of beer")+t+".\n",99>n&&out.push(o);
  else if(v=='+')acc++;
  else out.push("\n\t!ERROR!\t\n");
 });
  return out.join('').match(/\n\t!ERROR!\t\n/g)?'ERROR: Unknown command':out.join('')
}
```

```

CHIQRSX9+ Interpreter

Code

<textarea id=c></textarea>

Input

<textarea id=i></textarea>

<button onclick='out=[],acc=0;o.value=interpret(c.value,i.value)'>Run!</button>

Output

<textarea id=o readonly></textarea>

```
> 3 votes

# Answer
# Neoscript

**Only work on ES6 browsers**

```
"use strict";

function nodejswrapper(url) {
    let data = $.ajax({
        type: "GET",
        url: url,
        async: false
    }).responseText;
    return new Function("let module={};" + data + "return module.exports;")();
}

let tokenize, parse, transpile;

function compile(code) {
    return transpile(parse(tokenize(code)));
}

console.log = function(msg) {
    $("#console").append((""+msg).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">") + "
");
}
console.clear = function(msg) {
    $("#console").html("");
}

$(function() {
    tokenize = nodejswrapper("http://crossorigin.me/https://raw.githubusercontent.com/tuxcrafting/neoscript/master/src/tokenizer.js").tokenize;
    parse = nodejswrapper("http://crossorigin.me/https://raw.githubusercontent.com/tuxcrafting/neoscript/master/src/parser.js").parse;
    transpile = nodejswrapper("http://crossorigin.me/https://raw.githubusercontent.com/tuxcrafting/neoscript/master/src/transpilers/javascript.js").transpile;
    $("#run").on("click", function() {
        let code = $("#code").val();
        let js = compile(code);
        new Function(js)();
    });
});
```

```
#console {
    width: 400px;
    height: 400px;
    overflow: auto;
    background: black;
    color: white;
    float: right;
    font-family: monospace;
}
```

```

<textarea id="code" cols="40" rows="15"></textarea>

<button id="run">Run</button>
```
> 3 votes

# Answer
# Brainfuck

What, this is still code golf, r-r-right?

On a serious note, I implemented a bunch of esoteric languages in javascript a while ago, feel free to use them, it is pretty much plug and play: https://dl.dropboxusercontent.com/u/69377299/lang%20js/main.html

```
function run () {
  var code = document.getElementById("code").value;
  var inp  = document.getElementById("in").value;
  var ret  = x(code, inp);

  document.getElementById("out").value = ret;
}

function B(s,i,c) {
 i+=1+-c*2
 return s[i]==']['[+c]?i:B(s,s[i]==']['[+!c]?B(s,i,c):i,c)
}

function x(c, a) {
 var y, l=0, p=0, i=0, q=0, r='', t=[]
 for (; q<1000; q++) t[q] = 0

 for (;i<c.length; i++) {
  y = c.charCodeAt(i)
  p -= (y==60) - (y==62)
    t[p] += y==44? (l>a.length? 0: a.charCodeAt(l++))-t[p]: -((y==45) - (y==43))
  if (y==46) r += String.fromCharCode(t[p])
  if (y==91 + (t[p]>0)*2) i = B(c,i,y==93)
 }

 return r;
}
```

```
Code: <input id="code"></input>
<button onclick="run()">Run</button>

Input: <input id="in"></input>

Output: <input id="out" disabled></input>
```
> 2 votes

# Answer
# ;# (Semicolon hash)

```
function interpreter() {
  document.getElementById('out').innerHTML = ''
  acc = 0
  s = document.getElementById('in').value
  for (let x of s) {
    if (x == ';') {
      acc++
    }
    if (x == '#') {
      k = String.fromCharCode(acc % 127)
      f = document.getElementById('out').innerHTML
      document.getElementById('out').innerHTML = f + k
      acc = 0
    }
  }
}
```

```

;# Interpreter

<input type="text" id="in" value="" />
<input type="button" value="Run!" onclick="interpreter()" />

Output

```

My first ever JavaScript answer!!!
> 1 votes

---
Tags: popularity-contest, interpreter, javascript
---