JSFiddle - React, Tailwind, and code Playground

HTML

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

CSS

.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;
}

JavaScript

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