Rendre les publications futures exécutables en ligne avec des extraits de pile


134

Des extraits de pile ont récemment été ajoutés à PPCG ! Rappelant JSFiddle , les extraits de pile permettent l’exécution directe de HTML, CSS et JavaScript dans les publications !

Voici un extrait de pile très simple:

alert('This is JavaScript')
h3 { color: red } /* This is CSS */
<h3>This is HTML</h3>

Cette fonctionnalité de Stack Exchange nous serait très utile si des langages autres que JavaScript étaient supportés. (Les réponses aux défis peuvent être testées sur le terrain, des exemples d’intrants peuvent être générés de manière dynamique, etc.) C’est là que vous intervenez.

Défi

Le but de ce défi est d’écrire un interprète pour certains langages de programmation en utilisant Stack Snippets et JavaScript. Le but est de faire quelque chose qui puisse être facilement copié et utilisé dans les futures questions et réponses du PPCG.

Plus ou moins, vous devez créer un extrait de pile comportant un bouton "Exécuter" et deux zones de texte, une pour le code et une pour la saisie. Cliquez sur le bouton Exécuter pour exécuter le code (écrit dans la langue que vous interprétez) sur l'entrée et afficher le résultat (probablement dans une autre zone de texte). L'extrait de code devrait ressembler à cjam.aditsu.net ou à l'exemple de réponse .

Pour la plupart des langues, il serait judicieux que l'entrée et la sortie représentent respectivement stdin et sdout, et vous pourriez avoir une autre zone de saisie pour la ligne de commande. Mais toutes les langues ne disposent pas de tels mécanismes I / O traditionnels. HQ9 + , par exemple, n'a même pas d'entrée, ce qui rend une zone de texte inutile. Alors n'hésitez pas à prendre quelques libertés, à concevoir en fonction de la langue, pas de cette spécification. La principale exigence est que votre langue soit "utilisable" dans un fragment de pile au sens accepté du terme.

Remarques

  • L'implémentation de toutes les fonctionnalités de votre langue, bien qu'idéale, n'est pas requise. Certaines choses telles que la lecture et l'écriture de fichiers ou l'importation de bibliothèques peuvent être difficiles à manier ou impossibles. Concentrez-vous sur la création d'un interprète qui optimise l'utilité de ce site.
  • Publier un interpréteur "language X to JavaScript" que vous n'avez pas écrit est correct (avec attribution).
  • Stack Exchange limite les réponses à 30 000 caractères . Prévoyez donc si votre interprète risque d'être long.
  • Il est préférable de faire une version de votre interprète aussi facile que possible à inclure dans les prochains messages. Par exemple, dans l' exemple de réponse , le Markdown brut pour l'intégralité de l'extrait est fourni, avec des emplacements évidents pour insérer du code et des entrées.

Bien que cette question soit davantage un recueil d’interprètes que un véritable défi, il s’agit toujours d’un , de sorte que la réponse la plus votée l'emporte.

Liste des interprètes actuels

(triés alphabétiquement par nom de langue)

  1. Faisceau
  2. Befunge-93
  3. Brainfuck
  4. Brainfuck
  5. CHIQRSX9 +
  6. Poisson mort
  7. Deadfish (exécute uniquement le code prédéfini)
  8. Fourier
  9. FRACTRAN
  10. Bonjour ++
  11. HQ9 +
  12. Insomnie
  13. Japt
  14. JavaScript (exemple de réponse)
  15. JavaScript ES2015
  16. Marbelous
  17. Neoscript
  18. oOo CODE
  19. Ouroboros
  20. Prélude
  21. Python 2
  22. STATA
  23. TI-Basic
  24. Unaire (traduit en BF)

(Cette question conviendrait peut-être mieux à Meta, mais elle sera plus visible ici. Les gens pourraient en fait produire des interprètes très utiles, je pense qu'ils méritent d'être représentés.)


2
Ce ne serait pas très amusant, mais la solution la plus pratique pour les langages plus difficiles comme Python serait probablement de simplement l'externaliser.
Sp3000

7
Je ne sais pas comment exécuter ces extraits à l'aide de l'application d'échange de pile.
Jerry Jeremiah

1
J'espère que quelqu'un s'attaque à C avec ce défi. Voici une longueur d'avance: stackoverflow.com/questions/6142193/…
Adam Davis


1
@ Sp3000: Ou cherchez des bibliothèques ... comme ci-dessous.
ArtOfCode

Réponses:


48

Python 2 (pas de STDIN)

Grâce à Skulpt , il est devenu très facile d'écrire un interpréteur Python.

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>

Pas de STDIN, mais c'est une implémentation assez complète de Python dans JS. Je chargerais les bibliothèques d'un autre endroit mais je ne peux pas en trouver une foule.


1
Wow, from random import randrangemême fonctionne. Agréable!
Poignée de porte

20
Maintenant, chargez simplement la source Marbelous dans cet interprète et vous aurez un interprète Marbelous!
Ingo Bürk

3
Il semble être python2 depuis print 2fonctionne. Cela vaut la peine de mentionner, je suppose.
ReyCharles

2
Je ne sais pas si c'est plus drôle ou plus cool de penser à Marbelous qui s'exécute dans un interpréteur Python qui s'exécute dans un javascript qui s'exécute dans un navigateur Web
vijrox

1
Cela ne fonctionne plus, probablement parce que les liens dans les <script>balises sont morts :(
oldmud0

33

Befunge-93

Edit: J'ai retravaillé toute l'interface graphique maintenant. Je suis beaucoup plus heureux avec ça. Une fonctionnalité de point d'arrêt serait intéressante, mais c'est probablement trop pour cela. Points ouverts que je reviendrai probablement:

  • Permettre une planche infinie
  • Afficher la pile lors de la progression dans le programme serait soigné

Comme je viens d’implémenter cet interprète pour ce défi, il n’a pas été testé de manière approfondie. Cependant, je l'ai essayé avec une variété de programmes différents maintenant et cela semble bien fonctionner.

La dernière version peut être trouvée à la dernière révision de ce violon .

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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
        }

        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>


Agréable! Devons-nous entrer manuellement la taille du tableau? Il semble que si nous ne le faisons pas, la mise en évidence a tendance à aller partout. (test avec le premier programme ici: en.wikipedia.org/wiki/Befunge#Sample_Befunge-93_code )
Sp3000 Le

@ Sp3000 Vous ne devez le saisir que si vous souhaitez le modifier (la valeur par défaut est le format 80x25 d'origine). Le programme fonctionne bien pour moi. "Partout" est ce que Befunge est tout. Le seul inconvénient, c'est que vous devez parcourir tous les espaces du tableau individuellement, mais je vais régler le problème. C'est techniquement correct, cependant. Si vous pensez que quelque chose est bizarre, vous pouvez peut-être faire un gif / une vidéo de son apparence pour vous?
Ingo Bürk

@ Sp3000 Une chose: si vous cliquez juste sur "Exécuter", la mise en évidence semble étrange car elle va trop vite. Si vous ne l'avez pas encore fait, essayez simplement "Step" pour parcourir la commande du programme pour la commande. Sinon, définissez les étapes par tick sur 1 et appuyez sur Exécuter pour une animation plus fluide.
Ingo Bürk

Ahaha ouais par "partout" j'ai voulu dire le fait que tous les espaces blancs sont traversés. Envisagez-vous de faire en sorte que le programme détecte la taille du tableau à l'avenir? (Si vous en avez le temps)
Sp3000

1
@ Sp3000 La taille du tableau est une propriété de l'interprète et non du programme. À l'origine, les planches Befunge ont une taille fixe. Mais vous pouvez autoriser une taille infinie que je prévois de faire. Je prévois également de sauter des espaces consécutifs en une seule étape.
Ingo Bürk

33

TI-BASIC

Parce que qui n'aime pas TI-Basic?

Je voulais contribuer à cela, alors j’ai choisi une langue qui est (à mon humble avis) un peu plus compliquée que, par exemple, Deadfish, mais sous mon contrôle. Je connais beaucoup de choses sur ma calculatrice, alors j'ai choisi ceci.

Cependant, je n'ai aucune expérience de base avec JavaScript / CSS / HTML. C'était mon premier programme. Cela signifie...

S'il vous plaît signaler les erreurs que vous trouvez dans mon code!

Ceci étant dit, il s’agit d’une version limitée de TI-Basic. Je vais continuer à mettre en œuvre les choses au fur et à mesure que je les aborde.

Caractéristiques dès maintenant

  • Mots-clés de contrôle communs (if, then, else, end)
  • Toutes les boucles disponibles (while, répéter, pour)
  • commande disp
  • Opérateurs arithmétiques JavaScript, via eval
  • Listes
  • Construit en auto colon-ator (voyez par vous-même)
  • Valeurs aléatoires de variables non initialisées, tout comme votre calculatrice
  • mathématiques limitées - sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, log, ln, int, round, abs.
  • les constantes pi et e en tant que variables
  • Invite, entrée, pause (Yay!)
  • écrit en sortie lors de l'exécution (grâce au pseudonyme117)
  • capacités simples d'écran pixel-on / off / clear

Libertés prises

  • supporte les noms de variables multi-caractères. Malheureusement, ce moyen abest une variable, pas la valeur a*b. Cette limite de nom de variable uni-caractère m'a rendu fou avec ma calculatrice.
  • en ignorant "goto" et "lbl". Ils étaient buggés même sur la calculatrice, à moins que vous ne l'ayez fait d'une certaine manière.
  • Va ignorer prgm, OpenLib et ExecLib car il n'y a pas de fichiers externes / autres

Que faut-il encore faire

  • Une sorte de toile pour le dessin (à venir!) Plus de matériel de dessin
  • Une certaine manière pour promptet des inputcommandes dans la fenêtre de texte (des suggestions, n'importe qui?)
  • Support pour (le reste des) opérations mathématiques de la calculatrice (il y a BUCKETS)
  • Suppot pour Ansmot-clé manigances.
  • Prise en charge du reste des mots clés CTL
  • Une façon de supporter une forme de getkey, bien que la plupart des langues de nos jours soient gérées par les événements ... Peut-être que ce serait la dernière touche enfoncée.
  • Je ne sais pas si cela est vrai, mais JavaScript semble penser en premier, puis afficher sur une zone de texte plutôt que de s'afficher comme il se doit.
  • Il n'y a pas de joliesse CSS / HTML

Je ne connais toujours pas beaucoup de JavaScript. Si l’un des cas ci-dessus est possible / impossible, veuillez me le faire savoir.

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';
}
<h1>Ti-Basic Interpreter</h1>


<h3>Code</h3>

<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>
<br>
<button width='20' height='10' onclick='run()'>Run</button>
    <button width='20' height='10' onclick='stop()'>Stop</button>

<h3>Output (also input)</h3>

    <textarea id='output' cols='50' rows='7' onkeypress='onUserInput(event)'></textarea>
<br>
    <canvas id='canvas' width='192' height='128'></canvas>
<br>

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


en ce qui concerne javascript penser d'abord, puis l'affichage, le navigateur s'exécute dans un seul thread. le rendu des objets DOM (la page Web proprement dite) est effectué sur ce même fil. Par conséquent, tant que votre code ne sera pas exécuté, la page ne sera pas mise à jour. Pour résoudre ce problème, utilisez la fonction setTimeout ( w3schools.com/jsref/met_win_settimeout.asp ) afin que le navigateur puisse afficher votre mise à jour, puis poursuivez votre processus
pseudonym117

1
Je fais des choses avec ce code! J'ai trouvé une erreur: sur la ligne ~ 93, vous avez lineProcessing.clearInterval();; cela devrait plutôt être clearInterval(lineProcessing);.
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ N'hésitez pas à l'éditer et à le changer. Cela fait longtemps que je n'ai pas lu ce code. De plus, je suis un peu submergé par le travail scolaire en ce moment, alors il faudra peut-être un peu de temps avant de changer quoi que ce soit.
Stretch Maniac

3
@ StretchManiac Ah, d'accord. Je comprends - tergiverse le guichet automatique ^ _ ^
Conor O'Brien

26

Brainfuck

Voici un interprète de base BF. Il n'y a pas de débogueur cependant, mais dispose de deux options de personnalisation.

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 < code.length; ++i) {
    if (code[i] == "[") {
      loop_stack.push(i);

    } else if (code[i] == "]") {
      if (loop_stack.length == 0) {
        error(ERROR_BRACKET);
        return;

      } else {
        var last_bracket = loop_stack.pop();
        loop_map[last_bracket] = i;
        loop_map[i] = last_bracket;
      }
    }
  }

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

  running = true;
  start_time = Date.now();
  code_ptr = 0;
  input_ptr = 0;
  cell_ptr = Math.floor(NUM_CELLS / 2);
  cells = {};
  iterations = 0;

  bf_iter(1);
}

function bf_iter(niters) {
  if (code_ptr >= code.length || !running) {
    stop();
    return;
  }

  var iter_start_time = Date.now();

  for (var i = 0; i < niters; ++i) {
    if (cells[cell_ptr] == undefined) {
      cells[cell_ptr] = 0;
    }

    switch (code[code_ptr]) {
      case "+":
        if ((wrap == "8" && cells[cell_ptr] == 255) ||
            (wrap == "16" && cells[cell_ptr] == 65535) || 
            (wrap == "32" && cells[cell_ptr] == 2147483647)) {
            cells[cell_ptr] = 0;
        } else {
          cells[cell_ptr]++;
        }
        break;
        
      case "-":
        if (cells[cell_ptr] == 0 && 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);
}
<div style="font-size:12px;font-family:Verdana, Geneva, sans-serif;">
  <div style="float:left; width:50%;">
    Code:
    <br>
    <textarea id="code" rows="4" style="overflow:scroll;overflow-x:hidden;width:90%;">>++++++++[<+++++++++>-]<.>>+>+>++>[-]+<[>[->+<<++++>]<<]>.+++++++..+++.>>+++++++.<<<[[-]<[-]>]<+++++++++++++++.>>.+++.------.--------.>>+.>++++.</textarea>
    <br>Input:
    <br>
    <textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;"></textarea>
    <p>
      Wrap:
      <select id="wrap">
        <option value="8">8-bit</option>
        <option value="16">16-bit</option>
        <option value="32">32-bit</option>
        <option value="-1">None</option>
      </select>
      &nbsp;
      Timeout:
      <input id="timeout" type="checkbox" checked="true" />&nbsp; EOF:
      <select id="eof">
        <option value="nochange">Same</option>
        <option value="0">0</option>
        <option value="-1">-1</option>
      </select>
    </p>
  </div>
  <div style="float:left; width:50%;">
    Output:
    <br>
    <textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>
    <p>
      <input id="run" type="button" value="Run" onclick="run()" />
      <input id="stop" type="button" value="Stop" onclick="interrupt()" disabled="true" />
      <input id="clear" type="button" value="Clear" onclick="clear_output()" />
      &nbsp;
      <span id="stderr" style="color:red"></span>
    </p>
  </div>
</div>

Sur mon navigateur, tout l'extrait est contenu dans l'extrait de code développé, mais je ne suis pas un expert en compatibilité de navigateur, donc je ne peux pas garantir que ce sera la même chose pour tout le monde.

Caractéristiques

  • Le wrapping de cellule et le comportement EOF peuvent être configurés
  • Le délai peut être ignoré
  • Le programme peut être interrompu en cours d'exécution
  • Un joli petit bouton clair
  • Tout cela dans la boîte Stack Snippet (ou du moins, j'ai essayé) et environ 6 000 personnages sans golf

Voici un programme de chat à tester: ,.[>,.]( avertissement : n'essayez pas avec de gros textes!). Mais ce code fonctionne à merveille !.
Ismael Miguel

@IsmaelMiguel Qu'en est- il juste +[,.]:)
seequ

1
@IsmaelMiguel Personnellement, je préfère ne pas déplacer le pointeur dans la boucle afin que personne ne remarque que la bande est délimitée par la taille entière de Javascript: P
Sp3000

1
@ Sp3000 Eh bien, si vous pouvez lire la longueur du texte, vous pouvez être sûr que le code fonctionnera correctement. Si vous parvenez à obtenir un texte dont la taille est de taille 0xFFFFFFFFFFFFFFFF et que mon code "meurt", vous remettez une médaille à Sieg.
Ismael Miguel

1
Je vous suggère d'utiliser un raccourci pour la document.getElementById()fonction.
AL

21

Marbelous *

Cet interprète est probablement rempli de bugs; si vous en trouvez, s'il vous plaît faites le moi savoir.

Ceci supporte toutes les fonctionnalités de Marbelous sauf #include. Il existe également une option pour utiliser une planche cylindrique (les billes repoussées sur les côtés de la planche réapparaissent de l'autre côté).

L'interprète vient également avec de nombreux tableaux présents dans les exemples du repo pour l'interprète python pour Marbelous . Ces conseils sont énumérés ci-dessous:

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

Aucun inclus ne devrait être utilisé. Voir le repo de l'interprète python pour plus de détails sur ce que font chacune de ces planches.

* Plus d'informations sur Marbelous:

Remarque: La sortie graphique (256x256 tampons doubles avec une couleur RVB 24 bits) est disponible sur cet interpréteur. Les tableaux suivants peuvent être utilisés à cette fin:

{}{}{}{}{} - 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)

Veuillez noter qu’avoir Use Draw Bufferscoché (obligatoire pour la sortie graphique) peut ralentir l’interpréteur et que la sortie graphique est lente.

Mise à jour : tampons modifiés pour utiliser canvas à la place de div 1 x 1 pixel; dessiner devrait être beaucoup plus rapide maintenant.

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;
}
<div style="font-size: 12px;font-family: Helvetica, Arial, sans-serif;">
<div style="float: left;">
	Marbelous Source:<br />
	<textarea id="mb-src" rows="4" cols="35">48 65 6C 6C 6F 20 57 6F 72 6C 64 21</textarea><br />
	Arguments: <br />
	<input id="mb-args" size="33" /> <br />
	STDIN: <br />
	<textarea id="mb-in" rows="2" cols="35"></textarea><br />
	<span style="float: left">
		Max Ticks: <input id="mb-ticks" type="number" min="1" style="width: 60px" value="1000" />
	</span>
	<span style="float: right">
		<input type="button" onclick="run()" value="Run Code" style="" />
		<input type="button" onclick="stop()" value="Stop" style="" />
	</span>
</div>
<div style="float: left; margin-left: 15px;">
	<div style="margin-bottom: 10px">
		<input type="checkbox" id="mb-spaces" />Using spaces for blank cells<br />
		<input type="checkbox" id="mb-cylinder" />Cylindrical Board<br />
		<input type="checkbox" id="mb-numprint" />Display output as decimal numbers<br />
		<input type="checkbox" id="mb-lib" checked="true" />Include Libraries<br />
		<input type="checkbox" id="mb-gfx" />Use Draw Buffers<br />
	</div>
	<div>
		STDOUT:<br />
		<textarea id="mb-out" rows="3" cols="35"></textarea><br />
		Return Code: <input id="mb-return" />
	</div>
</div>
<div style="clear: both; text-align: center; width: 550px; padding-top: 10px;" id="mb-draw-buffers">
	<div style="float: left; width: 256px;">
		Front Buffer:
		<canvas style="height: 256px; width: 256px; background: black;" width="256" height="256" id="mb-fb"></canvas>
	</div>
	<div style="float: right; width: 256px;">
		Back Buffer:
		<canvas style="height: 256px; width: 256px; background: black;" width="256" height="256" id="mb-bb"></canvas>
	</div>
</div>
</div>

Quelques programmes simples à essayer:

chat (affiche stdin sur stdout)

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

rot13 (lit à partir de 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 \/ \/ .. .. .. .. .. ..

Démo de sortie graphique (définit un pixel aléatoire sur une couleur aléatoire, puis retourne le tampon)

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

C'est génial, il semble que les conseils avec des noms de lettre simples ne fonctionnent pas bien.
Overactor

@overactor qui devrait être corrigé maintenant
es1024

La dernière démo donne une erreurError near FF FF FF FF FF 00
Khaled.K

17

JavaScript (exemple de réponse)

Interpréter JavaScript à l'aide de JavaScript est quelque peu inutile, mais cela montre à quoi devraient ressembler vos extraits de l'interprète.

Voici la version nue, destinée à une utilisation rapide dans d'autres publications:

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
<!--Interpreter code:--><script>i=document.body.innerHTML;document.body.innerHTML=''</script><script>c=i.match(/BEGIN_CODE\n([\s\S]*)\nEND_CODE_BEGIN_INPUT/);c=c&&c.length>1?c[1]:'// Error reading code. Make sure it is on the lines between BEGIN_CODE and END_CODE_BEGIN_INPUT.';i=i.match(/END_CODE_BEGIN_INPUT\n([\s\S]*)\nEND_INPUT/);i=i&&i.length>1?i[1]:'Error reading input. Make sure it is on the lines between END_CODE_BEGIN_INPUT and END_INPUT.'</script>JavaScript:<br><tt>function(x) {</tt><br><textarea id='c'rows='4'cols='60'></textarea><br><tt>}</tt><br><br>Input string (variable x):<br><textarea id='i'rows='4'cols='60'></textarea><p><input type='button'value='Run'onclick='r()'></p>Output (return value):<br><textarea id='o'rows='4'cols='60'style='background-color:#f0f0f0;'></textarea><script>document.getElementById('c').value=c;document.getElementById('i').value=i;function r(){var r,c,i;r=c=i=null;eval('var f=function(x) {'+document.getElementById('c').value+'}');document.getElementById('o').value=String(f(document.getElementById('i').value))}</script>

Le Markdown brut pour inclure cet extrait de pile dans une autre question ou réponse est:

<!-- begin snippet: js hide: false -->
<!-- language: lang-html -->
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
<!--Interpreter code:--><script>i=document.body.innerHTML;document.body.innerHTML=''</script><script>c=i.match(/BEGIN_CODE\n([\s\S]*)\nEND_CODE_BEGIN_INPUT/);c=c&&c.length>1?c[1]:'// Error reading code. Make sure it is on the lines between BEGIN_CODE and END_CODE_BEGIN_INPUT.';i=i.match(/END_CODE_BEGIN_INPUT\n([\s\S]*)\nEND_INPUT/);i=i&&i.length>1?i[1]:'Error reading input. Make sure it is on the lines between END_CODE_BEGIN_INPUT and END_INPUT.'</script>JavaScript:<br><tt>function(x) {</tt><br><textarea id='c'rows='4'cols='60'></textarea><br><tt>}</tt><br><br>Input string (variable x):<br><textarea id='i'rows='4'cols='60'></textarea><p><input type='button'value='Run'onclick='r()'></p>Output (return value):<br><textarea id='o'rows='4'cols='60'style='background-color:#f0f0f0;'></textarea><script>document.getElementById('c').value=c;document.getElementById('i').value=i;function r(){var r,c,i;r=c=i=null;eval('var f=function(x) {'+document.getElementById('c').value+'}');document.getElementById('o').value=String(f(document.getElementById('i').value))}</script>
<!-- end snippet -->

Pour l'utiliser, copiez-le simplement dans un nouvel article et mettez votre code sur les lignes entre BEGIN_CODEet END_CODE_BEGIN_INPUT, et votre entrée sur les lignes entre END_CODE_BEGIN_INPUTet END_INPUT. L'interprète fera le reste. Notez que rien ne doit être mis en retrait.

Je dirais que cette BEGIN...ENDtechnique est actuellement le meilleur moyen d’écrire ces interprètes en termes de facilité d’utilisation future parce que ...

  • Lors du rendu, il n'y a qu'un seul bloc de code (le code HTML) et une seule ligne est "extra".
  • L'utilisateur qui rédige l'extrait peut voir exactement où placer son code et sa saisie. Ils ne doivent pas rechercher la balise textarea appropriée.
  • Les utilisateurs qui lisent l'article peuvent facilement distinguer le code sans même exécuter l'extrait de code. Bien sûr, lorsque le fragment est exécuté, le code est évident.
  • Il ne s'interrompt que lorsque les identifiants de début / fin apparaissent sur leurs propres lignes dans le code ou l'entrée. Mais cela est peu probable et ils peuvent être modifiés si cela est absolument nécessaire.
  • C'est autonome. Tout le code est juste là. (Je sais que cela pourrait être impossible pour un interprète de plus grande taille, mais l'un des objectifs de Stack Snippets était de lutter contre les liens morts avec JSFiddle et autres, l'autonomie est donc bonne.)
  • Il pourrait être étendu pour convenir à un nombre quelconque d'entrées (basées sur du texte).

L'extrait ci-dessous est la version générale non minimisée, complétée par des exemples et un peu plus de style.


15

Brainfuck (avec le débogueur de base)

J'ai vu le brainfuck répondre et j'ai pensé: tu sais ce qui serait génial? Si je pouvais prétendre, je comprends ce que fait le code. Et par conséquent, j'ai créé un interpréteur et un débogueur de base. Le débogueur est lent, mais cela fonctionne plutôt bien, même si je n'ai pas implémenté de points d'arrêt à ce jour (sur la liste des tâches).

Remarque: la "machine virtuelle" de Brainfuck ne se réinitialise pas automatiquement après l'exécution du code. Appuyez sur reset manuellement ou la bande aura les mêmes valeurs que celles qui existaient à la fin de la dernière exécution du programme.

Le débogueur fonctionne mieux en plein écran.

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;
}
<div>
    <h1>Brainfuck</h1>

    <div>
        <div>Code</div>
        <textarea id="code"></textarea>
    </div>
    <div>
        <div>Stdin</div>
        <textarea id="stdin"></textarea>
    </div>
    <div>
        <div>Stdout</div>
        <div id="stdout" class="textarea"></div>
    </div>
    <div>
        <span>Cell Size</span>
        <select id="stackSize" onchange="setStackSize()">
            <option value="255">8-bit</option>
            <option value="65535">16-bit</option>
            <option value="4294967296">32-bit</option>
        </select>
    </div>
    <div>
        <button id="run" onclick="run()">Run</button>
        <button id="debug" onclick="debug()">Debug</button>
        <button id="reset" onclick="reset()">Reset</button>
    </div>
    <div id="debug-area">
        <h2>Debug</h2>
        <div>
            <button onclick="debugRun()">Run</button>
            <button onclick="debugPause()">Pause</button>
            <span>Time between instructions</span>
            <input id="step-duration" type="number" value=5 />
			<br/>
            <button onclick="step()">Step</button>
        </div>
        <div>
            <h3>Executing Code</h3>
            <div id="running-code"></div>
        </div>
        <div id="stack">
            <h3>Stack</h3>
            <table id="stack-table"></table>
        </div>
    </div>
</div>

FAIRE:

  • ajouter des points d'arrêt
  • ajouter une vérification de plage au changement de pile
  • indicateur de progression
  • le rendre meilleur
  • ajouter un rembobinage pour le débogage
  • changer stdin en une sorte de flux?
  • code de golf un peu
  • ?

Usage:

Pour utiliser un extrait quelque part sur le site, modifiez la première ligne de l'extrait pour inclure votre code en tant que "mycode".

Pour exécuter du code sans débogueur, appuyez simplement sur Exécuter. Il met en tampon la sortie d’un demi-million d’instructions avant la mise à jour de stdout.

Pour déboguer, commencez par appuyer sur le bouton de débogage. Le bouton de pas ira à la prochaine instruction. Le bouton Exécuter lancera tout le programme, mais une étape à la fois, en mettant à jour la table de pile à chaque étape (ce qui explique pourquoi cette opération est si lente). Le temps entre les instructions est déterminé par la zone de saisie portant ce nom. Le bouton pause met en pause l'exécution du code. Vous pouvez le reprendre en appuyant de nouveau sur Exécuter.

Toutes les valeurs de la pile peuvent être modifiées en direct pour ce que vous voulez. Attention cependant, il ne vérifie pas si vous modifiez la valeur entière dans la cellule, donc si vous mettez 300 avec une taille de pile de 8 bits, il ne se soucie pas vraiment et ne le corrigera pas jusqu'à la prochaine incrémentation.


C'est plutôt chouette. J'adore le débogueur!
Ingo Bürk

14

Japt

Japt ( Ja vascri pt raccourci) est une langue que je en Septembre 2015. conçu En raison d'être paresseux occupé, je n'ai pas créé un interprète jusqu'au début Novembre. Vous pouvez trouver l'interprète officiel et la documentation ici .

Remarque: si vous avez des questions, des suggestions ou des rapports de bogues, veuillez les poster dans la salle de discussion Japt .

Fait amusant: c'était à l'origine l'interprète principal (et en fait le seul interprète). Vous pouvez le voir si vous parcourez l' historique des révisions .


Japt a-t-il un github?
Downgoat

@ Vɪʜᴀɴ Pas encore, mais je vais en créer un dans les prochaines 24 heures.
ETHproductions

2
@ Vɪʜᴀɴ j'aurais dû dire 24 minutes. ;) Ici vous allez. Le fichier Lisez-moi est en route.
ETHproductions

1
Vous devez utiliser rawgit.com au lieu de raw.githubusercontent.com - Chrome n'aime pas le type MIME.
Mama Fun Roll

1
@ nicael Vous pouvez utiliser Us q1, je crois.
ETHproductions

13

FRACTRAN

Un interprète semi-optimisé pour mon langage ésotérique préféré! Malheureusement, je n'ai pas beaucoup de temps cette semaine, donc des fonctionnalités supplémentaires devront venir plus tard.

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)
}
<div style="font-size:12px;font-family:Verdana, Geneva, sans-serif;">
  <div style="float:left; width:50%;">
    Code:
    <br>
    <textarea id="code" rows="4" style="overflow:scroll;overflow-x:hidden;width:90%;">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>
    <br>Input:
    <br>
    <textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;">2^47 * 193</textarea>
    <p>
      Timeout:
      <input id="timeout" type="checkbox" checked="true"></input>
    </p>
  </div>
  <div style="float:left; width:50%;">
    Output:
    <br>
    <textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>
    <p>
      <input id="run" type="button" value="Run" onclick="run()"></input>
      <input id="stop" type="button" value="Stop" onclick="interrupt()" disabled="true"></input>
      <input id="clear" type="button" value="Clear" onclick="clear_output()"></input>
      &nbsp;
      <span id="stderr" style="color:red"></span>
    </p>
  </div>
</div>

L'exemple de programme ci-dessus est mon programme combiné de quatre carrés - il prend l'entrée 2 n * 193 et ​​les sorties 3 a * 5 b * 7 c * 11 d , telles que a 2 + b 2 + c 2 + d 2 = n.

Faire

  • Générateur d'extraits
  • Autorise également la notation de factorisation pour les fractions
  • Validation d'entrée moins terrible
  • Nettoyer le code pour être meilleur
  • Autoriser l'impression de registres dans des conditions spéciales (par exemple, seul le registre 2est défini dans le cas du générateur principal de Conway). Actuellement, seuls les programmes qui se terminent produisent une sortie.
  • Optimisations de performances?

Usage

  • Les fractions dans le code sont divisées en [\s,]+, ce qui vous permet de séparer les fractions par des lignes, des espaces ou des virgules (ou des onglets, ou même une combinaison des éléments ci-dessus, si vous êtes fou).
  • L’entrée peut être en notation de factorisation, par exemple 2^5 * 3^7 * 11
  • Générateur d'extraits à venir quelque temps plus tard

1
Besoin de plus de points-virgules. ASI est le travail du diable.
nyuszika7h

10

Prélude

Peut-être que je pourrais augmenter un peu l’adoption de Prelude si les utilisateurs pouvaient simplement jouer avec cela dans leur navigateur. Voici donc un interpréteur JavaScript. Il est basé sur l'interprétant ingénieux Brainfuck de Sp3000 , dont la fonctionnalité tueur est une exécution interruptible et une temporisation facultative.

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 < code.length; ++i)
        if (code[i].length > 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);
}
<div style="font-size:12px;font-family:Verdana, Geneva, sans-serif;">Code:
    <br>
    <textarea id="code" rows="4" style="overflow:scroll;overflow-x:hidden;width:90%;">1(  #^    #^^   (#^+!
6 9+ 05+5+^#^+! #^ ^+!
   (((1- )#^##)^^+   )7-!)1433545514232323344949145353495314235494040404232323013334492349532333344953493435343584233475234501333449530423232349495323232323495323230494)</textarea>
    <br>Input:
    <br>
    <textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;">5a-13 11 2e3</textarea>
    <p>Numeric Input:
        <input id="num_input" type="checkbox">&nbsp; Numeric Output:
        <input id="num_output" type="checkbox">&nbsp; Timeout:
        <input id="timeout" type="checkbox" checked="checked">&nbsp;
        <br>
        <br>
        <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()">&nbsp; <span id="stderr" style="color:red"></span>

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

Alternativement, voici un JSFiddle .

L’interprète est déjà rempli avec mon quine , mais vous pouvez facilement trouver plus d’exemples de programmes à jouer en cherchant mes réponses Prelude .

Toutes les fonctionnalités de Prelude sont implémentées. Le seul inconvénient est le manque d'arithmétique de précision arbitraire, dû au type de nombre de JavaScript. Je pourrais résoudre ce problème à un moment donné, car je n'ai besoin que de prendre en charge l'addition et la soustraction pour les entiers arbitraires.

L'entrée et la sortie sont généralement les valeurs d'octet des caractères individuels, mais l'interpréteur est livré avec deux indicateurs pour lire et / ou écrire des nombres (signés).

Faire

  • Ajouter une version réduite pour la copie.
  • Soutenir l'arithmétique de précision arbitraire.
  • Ajouter un générateur d'extraits.

9

Poisson mort

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
}
<div style="font-size:12px;font-family:Verdana, Geneva, sans-serif;">
  <div style="float:left; width:50%;">
    Code:<br>
    <textarea id="code" rows="8" style="overflow:scroll;overflow-x:hidden;width:90%;" wrap="hard">iiisdsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddsdddddodddddodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddddsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiioiiiiiiofdddddddddddddddddddddddddddddddddddddddddddddoiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddsdddddodddddodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddddsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiioiiiiiiofdddddddddddddddddddddddddddddddddddddddddddddoiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiiiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioddddoiiiiiiiiiiiiiiiiioddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiiiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioddddoiiioiioiiioiiiiiiiiiiodddddddddddofddddddddddddddddddddddddddddddddoiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddsdddddodddddodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddddsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiioiiiiiio</textarea>
    <p>
      <input id="unicode" type="checkbox" checked="true" />Use ASCII/Unicode mode
    </p>
  </div>
  <div style="float:left; width:50%;">
    Output:<br>
    <textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>
  <p>
    <input id='run' type='button' value='Run' onclick='run()' />
  </p>
  </div>
</div>

Pour pré-initialiser la zone de code, il suffit de mettre quelque chose entre les balises textarea. De même, en ajoutant checked="true"dans la case à cocher la case à cocher, vous pouvez activer le mode ASCII / Unicode par défaut (voir ci-dessus).

Notez que Deadfish lui-même n’a pas réellement de sortie ASCII dans sa spécification d’origine, je le mets juste pour les questions qui peuvent permettre "la prochaine chose la plus proche". Si vous craignez que les règles d'une question n'autorisent pas Deadfish pour cette raison, vous pouvez toujours regarder quelque chose comme Deadfish ~ qui possède une sortie ASCII.

L'exemple présenté provient du sujet Joyeux anniversaire .


inputles éléments n'ont pas de contenu (ni balise de fermeture). Vous devriez utiliser <label><input />Foo</label>au lieu de<input>Foo</input>
Oriol

Besoin de plus de points-virgules. ASI est le travail du diable.
nyuszika7h

@ nyuszika7h Désolé, je mettrai à jour mon temps (Trop utilisé pour Python et je ne sais pas trop)
Sp3000

8

Poisson mort

Cela ne se conforme pas strictement à l'exigence, c'est ma vision de la manière dont nous pourrions utiliser Stack Snippets.

Je n'aime pas la quantité de passe-partout, en particulier la nécessité d'inclure du code HTML personnalisé pour un autre bouton Exécuter.

Dans ma vision:

  • placez une seule <script>étiquette pour inclure un cadre simple et l'interprète réel
  • placez le script dans la zone CSS (la coloration syntaxique peut devenir horrible)
  • utiliser le bouton existant d'extrait de code pour exécuter le code
  • obtenir la sortie dans le cadre de l'extrait

Pour l'instant pas décidé comment il serait plus agréable de spécifier l'entrée.

iiisdsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddsdddddodddddodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddddsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiioiiiiiio
dddddddddddddddddddddddddddddddddddddddddddddoiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddsdddddodddddodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddddsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiioiiiiiio
dddddddddddddddddddddddddddddddddddddddddddddoiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiiiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioddddoiiiiiiiiiiiiiiiiioddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiiiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioddddoiiioiioiiioiiiiiiiiiiodddddddddddo
ddddddddddddddddddddddddddddddddoiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiiiiiiiiooiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddddddsiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioiioddddddddddddoddddodddoiiiiiiiiiiiiiiiiiiiiiiiiodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddsdddddodddddodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddddsiiiiiiiioiiiiiiiiiiiiiiiiiiiiiioiiiiiio
<script src="https://bitbucket.org/manatwork/stackcode/raw/681610d0a6face9df62e82c50ec887d66d692e0f/interpret.js#Deadfish"></script>


il devrait y avoir un moyen d'inclure facilement l'entrée aussi bien je suppose
SztupY

Certainement, @SztupY. Pour le moment, je ne suis pas décidé à inclure l’entrée aussi dans la partie CSS ou dans celle HTML. N'utiliserait pas la pièce JavaScript pour cela, car les navigateurs l'exécuteraient auparavant et certains codes pourraient entraîner une boucle sans fin en JavaScript. Malheureusement, il n'y a pas d'autre moyen, car les autres éléments ne sont pas copiés sur le serveur d'extraits de pile. :(
manatwork

Je pense que le code est correct dans le CSS, et que l'entrée peut aller après les <script>balises (peut-être dans un petit conteneur, par exemple <pre>, afin que le script puisse y accéder. Espérons qu'un pré ne déforme pas trop l'entrée).
SztupY

Un <pre>(ou généralement une balise) apparaîtrait affiché et la syntaxe surlignée en vert. Comme JavaScript est quand même capable d'extraire la partie entrée, je ne voudrais pas inclure de balisage supplémentaire. La principale différence entre l'utilisation de la pièce CSS et celle de HTML est que CSS n'apparaît pas dans le document, contrairement à HTML. Toujours indécis.
Manatwork

3
De plus, est-ce que je manque quelque chose ou est-ce que votre extrait ne fonctionne pas maintenant?
Les passe-temps de Calvin

8

JavaScript ES7

Cela vous permet d’exécuter du code ES6 / 7 dans n’importe quel navigateur.

Les navigateurs sur lesquels je suis sûr que cela fonctionne à 100% sont: IE 11, Chrome 46 et Safari 7.

Ceci supporte les compréhensions de tableaux ( [for(a in b) c])

function color(n,e){return~[null,void 0].indexOf(n)?'<div class="out '+e+'"><span style="color: #808080">'+String(n)+"</span></div>":"string"==typeof n?'<div class="out '+e+'"><span class="string">"'+n+'"</span></div>':"number"==typeof n?'<div class="out '+e+'"><span class="number">'+n+"</span></div>":"function"==typeof n?'<div class="out '+e+'"><span style="color: #808080">function</span></div>':"undefined"!=typeof n.length?'<div class="out '+e+'">'+JSON.stringify(n).replace(/(["'])((?:(?=\\*)\\.|.)*?)\1/g,'<span class="string">$1$2$1</span>').replace(/(\d+)/g,'<span class="number">$1</span>')+"</div>":'<div class="out '+e+'">'+JSON.stringify(n,null,2).replace(/(["'])((?:(?=\\*)\\.|.)*?)\1/g,'<span class="string">$1$2$1</span>').replace(/(\d+)/g,'<span class="number">$1</span>').replace(/\n/g,"<br>")+"</div>"}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+='<div class="out error"><span>'+res+"</span></div>":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; }
<div id="demo"><h1>Code</h1><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></div><div><h1>Console Output</h1><pre id="Console" class="full"></pre></div><script src="http://babeljs.io/scripts/babel.js"></script>

Pour les permaliens, utilisez ESFiddle


Je suis réticent à cette réponse parce que lorsque j'essaie de l'exécuter, les alertes chrome s'affichentERR_NAME_NOT_RESOLVED , puis la barre se bloque!
Cat

1
Sortie de la version 57 de ChromeReferenceError: babel is not defined
Khaled.K

6

Insomnie

Les spécifications sont ambiguës concernant la sémantique des instructions 8 et 9, elles ne sont donc pas implémentées.

N'hésitez pas à l'améliorer pour prendre en charge les instructions 0 à 7. Il existe également un code incomplet pour exécuter le programme au ralenti, mais il s'agissait d'un bogue, je l'ai donc supprimé de l'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) + "<span class='highlight'>" + dispCode[ip] + "</span>" + dispCode.substring(ip + 1);
            
            document.getElementById('output').innerHTML = 
                escapeHTML(output).replace(/[\x00-\x1f\x7f-\x9f]/g, function ($0) { 
                    return "<span class='non-printable'>" + nonprint[$0] + "</span>"; 
                });
                
            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) + "<span class='highlight'>" + dispByte[7 - bp] + "</span>" + 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) {
                        interpreter.step();
                        
                        if (!halted) {
                            tid = setTimeout(auto, 200);
                        }
                    }
                })();
            }
        },
        run: 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;
            }
            
            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;
}
<h1>Insomnia<sup><a href="http://esolangs.org/wiki/Insomnia">[?]</a></sup></h1>

Currently only supports commands 0-7. Semantics of command 8 and 9 (WHILE loop) is not clearly understood, so it is not implemented.<br>
This interpreter is greatly inspired by <a href="http://www.quirkster.com/iano/js/">Ian's Befunge-93 interpreter</a>.

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

<h3>ASCII sequence</h3>
<pre id="ascii" class="code"></pre>
<input type="button" id="load" value="Load program" />

<hr>

<h3>Execution</h3>
<pre id="execcode" class="code"></pre>

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

<h3>Debug</h3>
<table>
  <tr>
    <th>Group Pointer</th>
    <td class="code" id="gp"></td>
  </tr>
  <tr>
    <th>Bit Pointer</th>
    <td class="code" id="bp"></td>
  </tr>
  <tr>
    <th>Current group</th>
    <td class="code" id="currgr"></td>
  </tr>
</table>

<h3>Output</h3>
<pre id="output" class="code box"></pre>


5

HQ9 +

Puisque Calvin's Hobbies a même utilisé HQ9 + comme exemple, j'ai décidé d'écrire une implémentation rapide pour celui-ci. Eh bien, mise en œuvre partielle, car j'ai décidé de laisser de côté l'accumulateur (vous pouvez me haïr pour ça).

L'interprète joue, par exemple, partiellement au golf. Je ne sais pas pourquoi j'ai en quelque sorte joué au golf, mais pas vraiment.

(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;
}
<div>
    <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+" />
</div>


1
votre si sur le commandement 9 est à l'envers ... dit aller au magasin et acheter un peu plus chaque fois, mais la dernière fois
pseudonyme117

1
@ pseudonym117 Oups. Fixé. Une langue avec trois commandes (utiles) et je parviens toujours à imprimer le mauvais résultat. :)
Ingo Bürk

5
Bug: "1 bouteilles de bière sur le mur."
Kennytm

5
Votre interprète ne prend pas en charge l'augmentation de l'accumulateur!
Jimmy23013

7
Je voulais dire que vous devriez au moins ignorer la +commande au lieu de générer une erreur.
Jimmy23013

5

Faisceau

Je pense vraiment que cette langue méritait d’avoir un interprète et que cela paraissait assez simple pour un non-programmeur comme moi. J'espère que j'ai bien compris. Cela semble fonctionner pour les exemples que j'ai essayés. Une grande partie du code est plagiée d'autres réponses à cette question. Mes excuses aux vrais programmeurs si j'ai commis des péchés capitaux dans mon code :)

J'ai mis l'exemple 'Reverse STDIN' à partir de la page Esolangs.

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 < code.length; ++i){
	if (code[i].length > 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);
	}
}
}
<div style="font-size:12px;font-family:Verdana, Geneva, sans-serif;">Code:
    <br>
    <textarea id="code" rows="8" style="overflow:scroll;overflow-x:hidden;width:90%;">v
(>``v
!  H(p`@`p)H
P   H
' 
r 
' 
P 
! 
>^
	</textarea>
    <br>Input:
    <br>
    <textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;">Reverse this string</textarea>
    <p>Timeout:
        <input id="timeout" type="checkbox" checked="checked">&nbsp;
        <br>
        <br>
        <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()">&nbsp; <span id="stderr" style="color:red"></span>
    </p>Output:
    <br>
    <textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>
</div>


Comment n'ai-je pas remarqué cela auparavant? C'est bien! J'adore voir des langues sauvées du gouffre de l'inimplémentation. ;)
ETHproductions

1
J'espère que cela ne vous dérange pas, mais j'ai nettoyé un peu la section JS.
ETHproductions

@ETHproductions Cela ne me pose aucun problème. Je ne suis pas un vrai programmeur comme je l'ai mentionné ci-dessus, mais je voulais vraiment pouvoir tester certaines des idées que vous avez suscitées avec votre réponse au défi Hello World.
MickyT

La fonctionnalité de délai d'attente ne semble pas fonctionner actuellement. Si j'insère une boucle infinie, il plante mon navigateur, et je me souviens d' un temps à essayer d'imprimer tous les caractères ASCII à partir !de ~, et de l' avoir toujours le temps après les trois premiers, même avec délai d' attente désactivé. Je vais jeter un coup d'oeil dans un instant.
ETHproductions

@ETHproductions qui est venu avec l'extrait que j'ai copié en grande partie pour commencer celui-ci. Je dois admettre que j'ai eu quelques problèmes avec les délais d'attente.
MickyT

5

K5

C’est un emballage simple et mince qui décrit l’ implémentation de K basée sur JavaScript, oK , et fait référence au dépôt github. J'ai déjà construit une interface beaucoup plus agréable basée sur un navigateur. oK implémente une partie très importante de K5, à part IO, et a été utilisé dans le passé pour résoudre un certain nombre de problèmes liés au débordement de pile. Le code n'est pas lu en tant que tel, mais contient bien moins de 1000 lignes, y compris les commentaires, l'analyseur, toutes les opérations primitives, l'interpréteur et le joli imprimeur.

* {
  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
}
<script src="http://johnearnest.github.io/ok/oK.js"></script>
<script>
    function runk() {
    	var code = document.getElementById("code").value;
    	var env  = baseEnv();
    	var ret  = run(parse(code), baseEnv());
    	document.getElementById("output").value = format(ret);
    }
</script>

Code:
<br>
<textarea id="code" rows="8">2*!10</textarea>
<p><input id="run" type="button" value="Run" onclick="runk()"></p>
Output:
<br>
<textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>


5

Espace blanc

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:<br/>
<textarea id="prog" rows="4" cols="60"></textarea><br/>
Input:<br/>
<textarea id="in" rows="4" cols="60"></textarea><br/>
<form>
    Is escaped as <code>STL</code>: <input id="esc" type="checkbox"/><br/>
</form>
<button onclick="document.getElementById('stack').innerText = interpret()">Interpret</button><br/>
Output:<br/>
<textarea id="out" rows="4" cols="60"></textarea><br/>
Resulting stack: <span id="stack"/>


5

Ouroboros

Un langage ésotérique créé par moi, DLosc, en octobre 2015. Le modèle d'exécution est basé sur le fait que chaque ligne de code est un serpent ouroboros . Le contrôle procède de la tête à la queue et revient en boucle à la tête; les instructions permettent au serpent d'avaler une partie de sa queue ou de régurgiter ce qu'il a avalé, modifiant ainsi le déroulement de l'exécution. Tous les serpents s'exécutent en parallèle. Les données sont stockées sur une pile partagée ainsi que sur une pile individuelle pour chaque serpent. Pour plus d'informations, des exemples de programmes et l'interpréteur le plus récent , voir le référentiel Github .

// 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 += '<span class="swallowedCode">';
    }
    if (i == this.ip) {
      if (this.wait > 0) {
        result += '<span class="nextActiveToken">';
      } else {
        result += '<span class="activeToken">';
      }
      result += escapeEntities(this.code.charAt(i)) + '</span>';
    } else {
      result += escapeEntities(this.code.charAt(i));
    }
  }
  if (this.length < this.code.length) {
    result += '</span>';
  }
  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("<br>"));
 }
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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
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;
}
<!--
Designed and written 2015 by D. Loscutoff
Much of the HTML and CSS was taken from this Befunge interpreter by Ingo Bürk: http://codegolf.stackexchange.com/a/40331/16766
-->
<h1><a href="https://github.com/dloscutoff/Esolangs/tree/master/Ouroboros">Ouroboros</a></h1>
<div class="container">
    <textarea id="source" placeholder="Enter your program here" wrap="off"></textarea>
    <div id="source-display-wrapper" onclick="sourceDisplayClick()">
        <div id="source-display"></div>
    </div>
</div>
<div id="stdin-container" class="container">
    <textarea id="stdin" placeholder="Input" wrap="off"></textarea>
    <div id="stdin-display-wrapper" onclick="stdinDisplayClick()">
        <div id="stdin-display"></div>
    </div>
</div>
<div id="controls-container" class="container clearfix">
    <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()" />
</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 Second: <span id="steps-per-second" contenteditable>10</span>
    </div>
</div>

Faire

  • Sortie de débogage: contenu des piles; combien d' entrée reste done
  • Pendant l' exécution, le code d'affichage avec des instructions en cours en surbrillance et parties avalées des queues grisées fait

4

oOo CODE

Un interpréteur très simple pour oOo CODE (première fois que j'utilise javascript). oOo CODE est un langage ésotérique basé sur le brainfuck qui utilise des majuscules et des minuscules pour stocker ses informations. Le texte lui-même importe peu. Comme oOo CODE est basé sur le brainfuck, j'ai réutilisé l'une des réponses brainfuck et ajouté une fonction permettant de traduire oOo CODE en 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 < code.length; ++i) {
    if (code[i] == "[") {
      loop_stack.push(i);

    } else if (code[i] == "]") {
      if (loop_stack.length == 0) {
        error(ERROR_BRACKET);
        return;

      } else {
        var last_bracket = loop_stack.pop();
        loop_map[last_bracket] = i;
        loop_map[i] = last_bracket;
      }
    }
  }

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

  running = true;
  start_time = Date.now();
  code_ptr = 0;
  input_ptr = 0;
  cell_ptr = Math.floor(NUM_CELLS / 2);
  cells = {};
  iterations = 0;

  bf_iter(1);
}

function bf_iter(niters) {
  if (code_ptr >= code.length || !running) {
    stop();
    return;
  }

  var iter_start_time = Date.now();

  for (var i = 0; i < niters; ++i) {
    if (cells[cell_ptr] == undefined) {
      cells[cell_ptr] = 0;
    }

    switch (code[code_ptr]) {
      case "+":
        if ((wrap == "8" && cells[cell_ptr] == 255) ||
            (wrap == "16" && cells[cell_ptr] == 65535) || 
            (wrap == "32" && cells[cell_ptr] == 2147483647)) {
            cells[cell_ptr] = 0;
        } else {
          cells[cell_ptr]++;
        }
        break;
        
      case "-":
        if (cells[cell_ptr] == 0){
          if (wrap == "8"){ cells[cell_ptr] = 255; }
          if (wrap == "16"){ cells[cell_ptr] = 65535; }
          if (wrap == "32"){ cells[cell_ptr] = 2147483647; }    
        } else {
          cells[cell_ptr]--;
        }
        break;
      
      case "<": cell_ptr--; break;
      case ">": cell_ptr++; break;

      case ".":
        document.getElementById("output").value += String.fromCharCode(cells[cell_ptr]);
        break;

      case ",":
        if (input_ptr >= input.length) {
          if (eof != "nochange") {
            cells[cell_ptr] = parseInt(eof);
          }
        } else {
          cells[cell_ptr] = input.charCodeAt(input_ptr);
          input_ptr++;
        }
        break;

      case "[":
        if (cells[cell_ptr] == 0) {
          code_ptr = loop_map[code_ptr];
        }
        break;

      case "]":
        if (cells[cell_ptr] != 0) {
          code_ptr = loop_map[code_ptr];
        }
        break;
    }

    code_ptr++;
    iterations++;

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

  setTimeout(function() { bf_iter(ITERS_PER_SEC * (Date.now() - iter_start_time)/1000) }, 0);
}
<div style="font-size:12px;font-family:Verdana, Geneva, sans-serif;">
  <div style="float:left; width:50%;">
    Code:
    <br>
    <textarea id="code" rows="4" style="overflow:scroll;overflow-x:hidden;width:90%;">JuLIeT
   O rOMeO, RoMEo! WHeREfOrE art tHoU RoMEo?
   DEnY ThY FaTHeR AnD ReFuse ThY NaME;
   oR, If ThoU wiLT not, BE but SWoRn mY loVe,
   aND i'Ll NO lONgER bE A cAPuLEt.
ROMeO
   [AsIdE] ShALl I HEar moRE, or sHAlL I sPEaK At THiS?
JuLIeT
   'TiS BUt Thy NamE thAt iS my EneMy;
   tHou ARt ThYSeLF, tHOUgH noT a mOntAguE.
   whAt's MOnTagUe? iT is Nor HanD, noR foOt,
   nOR arm (...)  </textarea>
    <br>Input:
    <br>
    <textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;"></textarea>
    <p>
      Wrap:
      <select id="wrap">
        <option value="8">8-bit</option>
        <option value="16">16-bit</option>
        <option value="32">32-bit</option>
      </select>
      &nbsp;
      Timeout:
      <input id="timeout" type="checkbox" checked="true" />&nbsp; EOF:
      <select id="eof">
        <option value="nochange">Same</option>
        <option value="0">0</option>
        <option value="-1">-1</option>
      </select>
    </p>
  </div>
  <div style="float:left; width:50%;">
    Output:
    <br>
    <textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea>
    <p>
      <input id="run" type="button" value="Run" onclick="run()" />
      <input id="stop" type="button" value="Stop" onclick="interrupt()" disabled="true" />
      <input id="clear" type="button" value="Clear" onclick="clear_output()" />
      &nbsp;
      <span id="stderr" style="color:red"></span>
    </p>
  </div>
</div>


1
Besoin de plus de points-virgules. ASI est le travail du diable.
nyuszika7h

@ nyuszika7h Intéressant, je ne savais pas que cela fonctionnait de cette façon ... (programmeur python) Le code sans point-virgule provenait de la réponse brainfuck originale de Sp3000, aussi je n'ai pas remarqué l'absence de point-virgule.
Déf

@ Sp3000 Pas de problème, j'ai écrit ma réponse pour le plaisir et pour apprendre un peu de javascript, pas pour la prime
Def

4

STATA

Edit: ajouté replace et vérifie la génération.

Prise en charge de certaines parties de l’affichage, des valeurs, de la liste, de la génération et de la mise en obs. En outre, il prend en charge la création et l'utilisation de macros (variables STATA). Il prend en charge suffisamment d'opérations pour certaines des réponses les plus simples publiées sur ce site, telles que l' évolution de "Hello World!" , Générez la séquence de Stöhr , faites-moi un arbre alphabétique (remplacez les guillemets simples par des guillemets doubles et faites-en 3 lignes au lieu de 1). C'est un travail en cours, et j'espère pouvoir le continuer bientôt, mais je me suis dit que je mettrais au moins quelque chose ici pour le moment.

<html>
<body>
Input
<textarea id="input"></textarea>
<br/>
Code
<textarea id="code"></textarea>
<br/>
<button>Run</button>
<br/>Output:
<textarea id="output"></textarea>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript">

$(function(){
    _N=0
    dataset=[];
    locals=[];
    globals=[];
    $output=$('#output');
    $input=$('#input');
    inputs=[];
    commands=[];
    comTable = [];
    comTable['di'] = 'display';
    comTable['dis'] = 'display';
    comTable['disp'] = 'display';
    comTable['displ'] = 'display';
    comTable['displa'] = 'display';
    comTable['display'] = 'display';
    comTable['loc'] = 'local';
    comTable['loca'] = 'local';
    comTable['local'] = 'local';
    comTable['gl'] = 'global';
    comTable['glo'] = 'global';
    comTable['glob'] = 'global';
    comTable['globa'] = 'global';
    comTable['global'] = 'global';
    comTable['set']='set';
    comTable['g'] = 'generate';
    comTable['ge'] = 'generate';
    comTable['gen'] = 'generate';
    comTable['gene'] = 'generate';
    comTable['gener'] = 'generate';
    comTable['genera'] = 'generate';
    comTable['generat'] = 'generate';
    comTable['generate'] = 'generate';
    comTable['replace'] = 'replace';
    comTable['l']='list';
    comTable['li']='list';
    comTable['lis']='list';
    comTable['list']='list';
    comTable['forv']='forvalues';
    comTable['forva']='forvalues';
    comTable['forval']='forvalues';
    comTable['forvalu']='forvalues';
    comTable['forvalue']='forvalues';
    comTable['forvalues']='forvalues';
    comTable['}']='No Operation';
    opTable=[];
    opTable['display']=[];
    opTable['display']['_r']='_request';
    opTable['display']['_re']='_request';
    opTable['display']['_req']='_request';
    opTable['display']['_requ']='_request';
    opTable['display']['_reque']='_request';
    opTable['display']['_reques']='_request';
    opTable['display']['_request']='_request';
    opTable['set']=[];
    opTable['set']['ob']='obs';
    opTable['set']['obs']='obs';
});
$('button').click(function () {
    _N=0
    dataset=[];
    inputNum=0;
    inputs=$input.val().split('\n');
    $output.val('');
    locals=[];
    globals=[];
    var code = $('#code').val();
    commands = code.split('\n');
    var tokens = [];
    commands.forEach(function (entry) {
        tokens.push(entry.match(/(?:[^\s"]+|"[^"]*")+/g) );
    });
    var error = '';
    var nextIndex=0;
    $.each(tokens,function (index,entry) {
        if(nextIndex!==index){
            return true;
        }
        var tok = entry[0];
        entry[0] = comTable[tok];
        if (entry[0] === undefined) {
            error = tok + ' is not a recognized command';
            outputError(error);
            return false;
        }
        nextIndex+=execute(entry,index);
        if(!nextIndex){
            return false;
        }
    });
});

function execute(command,ind){
    switch(command[0]){
        case 'display':
            return executeDisplay(command);
        case 'local':
            return executeLocal(command);
        case 'global':
            return executeGlobal(command);
        case 'set':
            return executeSet(command);
        case 'generate':
            return executeGenerate(command);
        case 'replace':
            return executeReplace(command);
        case 'list':
            return executeList(command);
        case 'forvalues':
            return executeForvalues(command,ind);
    }
}

function executeForvalues(command,ind){
    var re=/(\w+)=(.+)\((.+)\)(.+){/;
    var arr=re.exec(command[1]);
    if(arr==null){
        outputError('invalid format to command forvalues: '+command[1]);
        return false;
    }
    var locName=evaluate(arr[1],0);
    var i=Number(evaluate(arr[2],0));
    var increment=Number(evaluate(arr[3],0));
    var maximum=evaluate(arr[4],0);
    console.log(locName+' '+i+' '+increment+' '+maximum);
    maximum=Number(maximum);
    var curInd=ind+1;
    for(;i<=maximum;i+=increment){
        locals[locName]=i;
        globals['_'+locName]=i;
        for(curInd=ind+1;commands[curInd]!=='}';curInd++){
            var entry=commands[curInd].match(/(?:[^\s"]+|"[^"]*")+/g);
            var tok = entry[0];
            entry[0] = comTable[tok];
            if (entry[0] === undefined) {
                error = tok + ' is not a recognized command';
                outputError(error);
                return false;
            }
            console.log(entry);
            if(!execute(entry)){
                return false;
            }
            console.log($output.val());
        }
    }
    return curInd-ind;
}

function executeList(command){
    var out='\t'+Object.keys(dataset).join('\t')+'\n';
    for(var i=0;i<_N;i++){
        out+=(i+1)+'\t';
        Object.keys(dataset).forEach(function(element){
            out+=dataset[element][i]===undefined?'.':dataset[element][i]+'\t';
        })
        out+='\n';
    }
    $output.val(function(i,val){
        return val+out;
    });
    return 1;
}

function executeGenerate(command){
    var parts=command[1].split('=');
    if(dataset[parts[0]]){
        outputError('variable '+parts[0]+' already exists.');
        return false;
    }
    dataset[parts[0]]=[];
    for(var i=0;i<_N;i++){
        dataset[parts[0]][i]=evaluateVariables(parts[1],i);
    }
    return 1;
}

function executeReplace(command){
    var parts=command[1].split('=');
    if(!dataset[parts[0]]){
        outputError('variable '+parts[0]+' does not exist.');
        return false;
    }
    for(var i=0;i<_N;i++){
        dataset[parts[0]][i]=evaluateVariables(parts[1],i);
    }
    return 1;
}

function evaluateVariables(str,i){
    return eval(str.replace('_n',i+1));
}

function executeSet(command){
    if(opTable['set'][command[1]]=='obs'){
        _N=parseInt(command[2],10);
        return 1;
    }
    outputError('invalid option for command set: '+command[1]);
    return false;
}

function executeLocal(command){
    var parts=command[1].split('=');
    var name,value;
    if(parts.length==1){
        var re0=/^\+\+(\w+)$/;
        var re1=/^--(\w+)$/;
        var re2=/^(\w+)\+\+$/;
        var re3=/^(\w+)--$/;
        var arr=re0.exec(parts[0])||re1.exec(parts[0])||re2.exec(parts[0])||re3.exec(parts[0]);
        if(arr!=null){
            name=arr[1];
            if(parts[0].indexOf('-')>-1){
                value=globals[name]-1;
            }
            else{
                value=globals[name]+1;
            }
        }
        else{
            parts[1]=command[2];
        }
    }
    if(!value){
        value=evaluate(parts[1],0);
    }
    if(typeof value==='undefined'){
        return false;
    }
    if(!name){
        name=evaluate(parts[0]);
    }
    locals[name]=value;
    globals['_'+name]=value;
    return 1;
}

function executeGlobal(command){
    var parts=command[1].split('=');
    var name,value;
    if(parts.length==1){
        var re0=/^\+\+(\w+)$/;
        var re1=/^--(\w+)$/;
        var re2=/^(\w+)\+\+$/;
        var re3=/^(\w+)--$/;
        var arr=re0.exec(parts[0])||re1.exec(parts[0])||re2.exec(parts[0])||re3.exec(parts[0]);
        if(arr!=null){
            name=arr[1];
            if(parts[0].indexOf('-')>-1){
                value=globals[name]-1;
            }
            else{
                value=Number(globals[name])+1;
            }
        }
        else{
            parts[1]=command[2];
        }
    }
    if(!value){
        value=evaluate(parts[1],0);
    }
    if(typeof value==='undefined'){
        return false;
    }
    if(!name){
        name=evaluate(parts[0]);
    }
    if(name.charAt(0)=='_'){
        locals[name.substring(1)]=value;
    }
    globals[name]=value;
    return 1;
}

function executeDisplay(command){
    for(var i=1;i<command.length;i++){
        var comVal=command[i];
        $output.val(function(ind,val){
            var re=/^(\w+)/;
            var arr=re.exec(command[i]);
            if(arr!==null&&opTable['display'][arr[0]]=='_request'){
                re=/^\w+\((\w+)\)/;
                arr=re.exec(command[i]);
                var input=getInput();
                globals[arr[1]]=input;
                if(arr[1].charAt(0)=='_'){
                    locals[arr[1].substring(1)]=input;
                }
                return val;
            }
            return val+evaluate(command[i],0)+'\n';
        });
    }
    return 1;
}

function getInput(){
    var x=inputs[inputNum];
    inputNum++;
    return x;
}

function evaluate(str,captured){
    str=String(str);
    var index=str.indexOf('"');
    if(index==-1){
        return evaluate2(str);
    }
    var secondIndex=str.indexOf('"',index+1);
    while(secondIndex>0&&str.charAt(secondIndex-1)=='\\'){
        secondIndex=str.indexOf('"',secondIndex+1);
    }
    if(secondIndex<0){
        if(!captured){
            var error ='unmatched quotes';
            outputError(error);
            return undefined;
        }
        return '';
    }
    return (index>0?evaluate2(str.substring(0,index)):'')+evaluate2(str.substring(index,secondIndex+1))+(secondIndex<str.length-1?evaluate(str.substring(secondIndex)):'');
}

function evaluate2(str){
    var index=str.indexOf('`');
    if(index==-1){
        return evaluate3(str);
    }
    var secondIndex=str.indexOf('\'',index+1);
    while(secondIndex>0&&str.charAt(secondIndex-1)=='\\'){
        secondIndex=str.indexOf('\'',secondIndex+1);
    }
    if(secondIndex<0){
        return evaluate3(str);
    }
    var value=locals[str.substring(index+1,secondIndex)];
    if(typeof value==='undefined'){
        value='';
    }
    return evaluate((index>0?str.substring(0,index):'')+value+(secondIndex<str.length-1?str.substring(secondIndex+1):''));
}

function evaluate3(str){
    var re=/\$(\w+)/;
    var arr=re.exec(str);
    if(arr!==null){
        var index=arr.index;
        var length=arr[0].length;
        var value=globals[arr[1]];
        str=str.substring(0,index)+value+str.substring(index+length);
        return evaluate(str);
    }
    try {
        var value=eval(str.replace('_N',_N));
        return value;
    }catch(err){
        console.log(str);
        return str;
    }
}

function evaluate4(str){
    try {
        var value=eval(str);
        return value;
    }catch(err){
        console.log(str);
        return undefined;
    }
}

function outputError(error) {
    $output.val(function(ind,val){
        return val+error+'\n';
    });
}
</script>
</body>
</html>

Bug: Dans une generateexpression, seul le premier _nest remplacé.
LegionMammal978

Je suppose que la méthode de remplacement JS ne remplace que la première instance. Y a-t-il un moyen de changer cela?
bmarks

str.replace(/_n/g,i+1)
LegionMammal978

Vous avez utilisé jQuery.
Conor O'Brien

4

Labyrinthe

Un interprète pour Labyrinth, une langue totalement géniale! (Mon interprète n'a pas de grands entiers ...)

/*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(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/\n*$|(<br>)*$/, "").split(/<br>|\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(/<br>|\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>
<html>

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

<body>
  <button onclick="debug=false; run(); deb.style.display = 'none'; debugHeader.style.display = 'none';"><img src="http://i.imgur.com/XvHQHX9.png" class="buttonImg">Run</button>
  <button id="debugButton" onclick="startDebug(); deb.style.display='flex'; debugHeader.style.display = 'flex';"><img src="http://i.imgur.com/Th4Kyvd.png" class="buttonImg">Debug</button>
  <button id="stepButton" onclick="updatePointer();" disabled>Step: <span id="stepDiv">1</span>
  </button>
  <button onclick="sucide = true; updatePointer();">Stop</button>

  <div class="container">
    <h3>Maze:</h3>
    <div style="width:100%;  margin: -6px;"></div>
    <pre id="pointerOverlay"></pre>
    <pre id="lab" contentEditable="true">,)@
.(</pre>
    <div style="width:100%;"></div>
    
    <h3 id="inputHeader">Input:</h3>
    <h3 id="outputHeader">Output:</h3>
    <h3 id="debugHeader">Debugging:</h3>
    <div style="width:100%"></div>
    <textarea id="I">Labyrinth rocks!</textarea>
    <textarea id="O"></textarea>
    <textarea id="deb"></textarea>
  </div>
  <svg width="100%" id="svgId">
  </svg>
  <div id="spiderContainer">
  </div>
</body>

</html>

Voici la version la plus récente: http://output.jsbin.com/cuzoxu


Beau design d'interprète! Et le débogueur. Tu m'as donné envie d'apprendre cette langue!
RedClover

@ Soaku Merci! Si vous avez des suggestions / plaintes / etc., n'hésitez pas à me le dire. Je suis heureux de mettre en oeuvre à peu près n'importe quoi!
Stefnotch

4

Fourier

C'est maintenant une version complète de Fourier, traduite directement à partir du Python. Cela devrait rester à jour.

<!DOCTYPE html> <html> <head> <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"> <style> body { padding-left: 2em; background-color: gainsboro } textarea, input { font-family: Courier New; border: none } </style> </head> <body> <h1><a href="https://github.com/beta-decay/Fourier">Fourier</a> Interpreter</h1> <h3>Code:</h3> <textarea id="code" rows="4" oninput="javascript:chars()" cols="40"></textarea> <br/> Function: <select id="funcSelect"> <option value="exec">Execute code</option> <option value="expl">Explode code</option> <option value="debg">Debug code</option> </select> <br/> <h3>Input:</h3> <textarea id="input" rows="4" cols="40"></textarea> <br/><br/> <button id="run" onclick="javascript:main()">Engage</button> <button id="clear" onclick="javascript:clearText()">Clear</button> <br/> Character count: <span id="ccount">0</span> characters <h3>Output:</h3> <textarea id="output" readonly="readonly" rows="4" cols="40" style="cursor: default;"></textarea> <br/> <a href="javascript:getperma()">Get permalink</a> <br/> <h3>Character reference</h3> <h4>ASCII code reference</h4> <input id="charRef" cols="40" oninput="javascript:getCharCode()"> <br/> <input id="asciiRef" readonly="readonly" cols="40" style="background-color: #c2c2c2; cursor: default;"> <script src="https://rawgit.com/beta-decay/Fourier/master/javascript/editor.js"></script> <script src="https://rawgit.com/beta-decay/Fourier/master/javascript/debug.js"></script> <script src="https://rawgit.com/beta-decay/Fourier/master/javascript/interpreter.js"></script> <script> function main() { document.getElementById("output").style.color = "black"; choice = document.getElementById("funcSelect").value; if (choice == "exec") { interpreter(); } else if (choice == "debg") { debug(); } else { document.getElementById("output").value = "Sorry, those features are not ready yet"; } } </script> </body> </html>

Voir plus:


2
or ᴊ Q
Conor O'Brien

2
@ CᴏɴᴏʀO'Bʀɪᴇɴ Gah, arrêtez avec les petites capitales: D
Beta Decay

Pure course de maître JS! Subvertissez le paradigme dominant de jQuery!
Mama Fun Roll

3

Unaire (à Brainfuck)

Convertit simplement Unary en Brainfuck. Cela pourrait très facilement être associé à l'un des interprètes de Brainfuck pour exécuter le code unaire directement - inutile de réinventer la roue!

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" />
<br />
<br />
<input id="code" type="text" style="width:90%;" />
<br />
<br />
<input id="run" type="button" value="Run!" onclick="interpret()" />
<br />
<br />
<input id="result" type="text" style="width:90%;" />


3

Bonjour ++

Le langage le plus simple à mettre en œuvre ET à apprendre!

<h1>Hello++ Interpreter</h1>
<hr>
<h2>Code</h2>
<textarea id=c></textarea>
<br>
<button onclick='o.value="",c.value.replace(/[^h]/ig,"").split("").map(function($){$&&(o.value+="Hello World\n")})'>Say hello to the output!</button>
<h2>Output</h2>
<textarea id=o readonly></textarea>
<style>*{font-family:monospace}textarea{width:100%}</style>


3

CHIQRSX9 +

HQ9 + avec la complétude de Turing. J'ai collé aussi étroitement que possible aux spécifications.

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('')
}
<h1>CHIQRSX9+ Interpreter</h1>
<hr>
<h2>Code</h2>
<textarea id=c></textarea>
<br>
<h2>Input</h2>
<textarea id=i></textarea>
<br>
<button onclick='out=[],acc=0;o.value=interpret(c.value,i.value)'>Run!</button>
<h2>Output</h2>
<textarea id=o readonly></textarea>
<style>*{font-family:monospace}textarea{width:100%}</style>


3

Neoscript

Ne fonctionne que sur les navigateurs ES6

"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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "<br />");
}
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;
}
<script type="application/javascript" src="https://raw.githubusercontent.com/tuxcrafting/neoscript/master/src/stdlib/stdlib.js"></script>
<script type="application/javascript" src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<div id="console"></div>
<textarea id="code" cols="40" rows="15"></textarea><br />
<button id="run">Run</button>


2

Brainfuck

Quoi, c'est toujours du golf de code, rr-right?

Sur une note plus sérieuse, j’ai mis en place un certain nombre de langages ésotériques en javascript il ya quelque temps, n’hésitez pas à les utiliser, c’est plutôt 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>

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

<br><br>
Output: <input id="out" disabled></input>

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.