Implementar un intérprete inútil [cerrado]

12

Su tarea es construir un intérprete para el lenguaje inútil :

Aquí están los requisitos funcionales:

  • Todos los comandos descritos deben ser aceptados por el intérprete.
  • NO., NOOPy INCLUDE-xxxdebe ser honrado.
  • DONTUSEME(n) debe tener su fecha base para ser fácilmente configurable a algo más razonable para fines de prueba.
  • INCLUDE-xxxdebe poder generar cualquier comando con una probabilidad aproximadamente igual. Si genera a DONTUSEME(n), debe elegir aleatoriamente un valor pequeño para n.
  • DONTUSEME(n)Las ventanas deben sobrevivir a las NO.instrucciones. Consejo: genere un nuevo proceso para esas ventanas.
  • BOOM!y KABOOM!debe hacer algo malo y aterrador, y KABOOM!debe ser peor que BOOM!. Pero esto no debe tomarse demasiado en serio, por lo que no debe ser algo destructivo, excesivamente disruptivo o difícil de deshacer. Por favor, no haga , no haga , y no haga que estas instrucciones ejecuten un rm -rf \comando, ejecuten una bomba tenedor, instalen malware, corrompan datos en el sistema de archivos, o publiquen o descarguen contenido inapropiado de Internet, o cualquier otra cosa claramente abusiva.
  • TURINGVSALONZOdebería ejecutarse como si de hecho estuviera haciendo lo que debería hacer. Consejo: Haz que al azar decida si duerme durante un tiempo aleatorio muy largo, o un tiempo aleatorio corto, o para siempre.
  • Todas las demás instrucciones predefinidas deben hacer algo diferente a las instrucciones antes mencionadas y diferentes entre sí, pero nunca algo peor que BOOM!o KABOOM!. Lo que hacen exactamente depende de usted, pero una implementación simple solo generaría un mensaje de error u otro texto.
  • Debe proporcionar una manera fácil para que el usuario proporcione el programa que sería ejecutado por el intérprete. es decir, leer texto plano de un archivo o de stdinestá bien. Leerlo desde un archivo cifrado en algún lugar de Internet no lo es.

Opcional:

  • Puede inventar algunos comandos nuevos si lo desea, pero deben estar sujetos a las mismas reglas que los demás. No use esto para eludir las restricciones en BOOM!y / KABOOM!o para vencer DONTUSEME(n). Y si inventa nuevos comandos, explique lo que hacen.
  • Debería pensar en lo que hace el intérprete si recibe información con comandos desconocidos (o incluso galimatías de bytes aleatorios completamente ilegibles).
  • Aunque ninguna instrucción debe derrotar el DONTUSEME(n)comando, puede agregarle un interruptor de apagado. Simplemente no expongas eso en el idioma.

Tenemos algunos requisitos no funcionales para evitar abusos:

  • Su entrada debe ser lo más completa y autocontenida posible. Esto significa que no debería ser simplemente una especie de instalador o un programa claramente incompleto. De esta manera, la descarga y el uso de bibliotecas como jQuery o paquetes de maven central está bien, pero la descarga de código arbitrario y paquetes de su servidor personalizado no lo está.
  • Su entrada no debe obtener ningún contenido de esta misma página o de algún espejo o copia de esta página para hacer algún tipo de reflexión o para cualquier otro propósito. Esto es esencial para evitar que algún programa intente leer las respuestas de otros participantes a esta pregunta o intente interrumpir la pregunta o las respuestas de alguna manera.
  • Su intérprete debe ser inmutable y no auto modificarse ni modificar su archivo de entrada. Pero, crear una copia mutante del intérprete o del archivo de entrada sin alterar el original está bien.

Y finalmente, considerando que:

  • Se espera que los programas en las respuestas sean bastante inútiles incluso si son totalmente conformes;
  • El lenguaje es (a propósito) muy poco especificado, y los que responden tienen muchas libertades que tomar y están incentivados para tomarlas;
  • Los requisitos y las posibles implementaciones tienen muchos puntos subjetivos;
  • El objetivo con esto es obtener diversión y creatividad.

Entonces, este es un , ¡y la respuesta más votada y totalmente conforme a las reglas gana! Por lo tanto, no necesita jugar golf u ofuscar su respuesta (pero puede hacerlo si lo desea). Solo asegúrese de publicar algo original y creativo para merecer los votos positivos, es decir, no publique entradas aburridas.

Victor Stafusa
fuente
¿Quieres decir `rm -rf`?
Simon Kuang

Respuestas:

8

TI-BASIC

Hay un botón de matar para DONTUSEME, ¿puedes averiguar cuál es? :)

:Lbl 1
:Input Str1
:If Str1="NO."
:Pause
:If Str1="FAIL"
:Disp "OBSOLETE. WHAT A FAIL."
:If Str1="NOT"
:Disp "USING NOT IS HIGHLY DISCOURAGED!"
:If Str1="NEVER"
:get(Police,911)
:If Str1="IDK"
:Disp LLLundefined
:If Str1="BOOM!"
:Disp "rm -rf \"
:If Str1="KABOOM!"
:send(virus)
:If Str1="QWAOZAPWQFUOA"
:Disp "SKIPPING QWAO... UNIMPLEMENTED"
:If Str1="WUT?"
:dayOfWk(1)
:If Str1="WHERE?"
:Disp "NON-EXISTENT. SKIPPED."
:If Str1="HOW?"
:++
:If sub(Str1,1,9)="DONTUSEME"
:Then
:While 1
:sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(sin(e)
:End
:End
:If Str1="ILLEGAL"
:Archive X
:If Str1="GODEXISTS"
:Disp "GOD EXISTS, PROVEN BY LAW."
:If Str1="WINDOWS"
:Disp "UNABLE TO OPEN START MENU!"
:If Str1="NOOP"
:Lbl 0
:If sub(Str1,1,8)="INCLUDE-"
:sub(Str1,9,length(Str1-8))
:If Str1=Ans
:Then
:If not(rand)
:Goto 0
:End
:If Str1="TURINGVSALONZO"
:Then
:"+"→Str0
:randInt(5,10)
:While Ans
:Ans-1
:If fpart(Ans,4)4=3
:Str0+"+"→Str0
:If fpart(Ans,4)4=2
:Str0+"-"→Str0
:If fpart(Ans,4)4=1
:Str0+">"→Str0
:If fpart(Ans,4)4=0
:Str0+"."→Str0
:End
:Disp "0"
:"?utm_campaign=0"
:End
:Goto 1
Timtech
fuente
2
¿Eso :Goto 1significa que BOOM!es solo un no-op?
Victor Stafusa
1
@VictorStafusa Sí. Después de considerarlo un poco más, lo cambié a `rm -rf` porque me dijiste (no) que lo hiciera.
Timtech
No creo que lo hayas implementado INCLUDE-.
lirtosiast
9

HTML + Javascript + jQuery + jQuery UI

La entrada debe darse en el área de texto y debe formatearse como cada comando en una línea. Los comandos no distinguen entre mayúsculas y minúsculas. Todos los comandos se implementaron completamente. Espero que lo disfrutes.

Puedes probarlo en http://jsfiddle.net/bCBfk/

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
    <title>Useless interpreter</title>
    <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
    <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
    <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
    <style type="text/css">
      textarea { height: auto; }
      .badshit { color: red; }
      .ui-dialog-titlebar-close { display: none; }
    </style>
    <script type="text/javascript">
      String.prototype.startsWith = function(x) {
        return this.substring(0, x.length) === x;
      };
      String.prototype.endsWith = function(x) {
        return this.substr(this.length - x.length, x.length) === x;
      };

      var npe = "<pre>java.lang.NullPointerException\n"
          + "       at org.esolangs.wiki.useless.memorymodel.ExistentObjectPool.findObject(ExistentObjectPool.java:684)\n"
          + "       at org.esolangs.wiki.useless.interpreter.WhereInstruction.visit(WhereInstruction.java:29)\n"
          + "       at org.esolangs.wiki.useless.interpreter.UselessProgram.run(UselessProgram.java:413)\n"
          + "       at org.esolangs.wiki.useless.interpreter.Main.main(Main.java:53)</pre>";

      var wut = navigator.userAgent + " - " + navigator.language + " - " + navigator.platform + " - Ii?".toLocaleUpperCase();

      var wut2 = "";
      for (var c = wut.length - 1; c >= 0; c--) {
          wut2 += wut.charAt(c);
      }

      var popupMasterMind;
      function killIt() {
        clearInterval(popupMasterMind);
        $(".dontuseme").remove();
        popupMasterMind = null;
      }

      function spawn() {
        var x = $("<div class='dontuseme' title=''><p></p></div>");
        $("body").append(x);
        x.dialog();
        var bw = $("body").innerWidth();
        var bh = $("body").innerHeight();
        if (bh < 500) bh = 500;
        var xw = x.width();
        var xh = x.height();
        x.parent().css({left: Math.random() * (bw - xw) + "px", top: Math.random() * (bh - xh) + "px"});
      }

      function dontuseme() {
        if (popupMasterMind) return;
        spawn();
        popupMasterMind = setInterval(spawn, 700);
      }

      var hasOutput = false;
      function clearOutput() {
        $("#output").empty();
        hasOutput = false;
        $("#cc").hide();
      }

      function out(a) {
        $("#output").append($(a));
        hasOutput = true;
      }

      function finish() {
        $("#running").hide();
        $("#bt").show();
        if (hasOutput) $("#cc").show();
      }

      var annoyingUser = false;
      function swap() {
        annoyingUser = true;
        $("#everything").toggle();
        setTimeout(swap, 800);
      }

      function randomString() {
        var r = "";
        var f = Math.floor(Math.random() * 12) + 8;
        for (var i = 0; i < f; i++) {
          r += "ABCDEFGHIJKLMNOPQRSTUVWXYZ.!?0123456789".charAt(Math.floor(Math.random() * 39));
        }
        return r;
      }

      var instructions;
      function includeInstruction(name) {
        name = name.toUpperCase();
        if (instructions[name]) return; // Do not add it twice or overwrite existing instructions.
        var array = [];
        for (var e in instructions) {
          array.push(e);
        }
        var rand = Math.floor(Math.random() * array.length);
        //alert(name + ": " + array[rand]);
        instructions[name] = instructions[array[rand]];
      }

      // DONTUSEME(n) are special cases handled elsewhere.
      instructions = {
        "FAIL": function() { out("<p class='badshit'>Warning: The &lt;blink&gt; tag is obsolete.</p>"); if (!annoyingUser) swap(); return "next"; },
        "NOT": function() { out("<p class='badshit'>Warning: The NOT instruction is discouraged because it breaks yor Useless program.</p>"); return "quit"; },
        "NEVER": function() { out("<pre>Wild MISSINGNO. appeared!</pre>"); return "next"; },
        "IDK": function() { out("<pre>" + {}.idk + "</pre>"); return "next"; },
        "BOOM!": function() { $("#everything").empty(); return "quit"; },
        "KABOOM!": function() { window.location = "http://answers.yahoo.com/question/index?qid=20110816062515AANqygl"; return "quit"; },
        "NO.": function() { finish(); return "quit"; },
        "QWAOZAPWQFUOA": function() { out("<p class='badshit'>Sorry, I could not understand <a href='https://www.google.com.br/#q=women+psychology+and+behaviour'>this</a>.</p>"); return "next"; },
        "WUT?": function() { out("<p>" + wut2 + "</p>"); return "next"; },
        "WHERE?": function() { out(npe); return "next"; },
        "HOW?": function() { out("<p class='badshit'>Regular expression parser failed for HTML. Cause: \"ZALGO\"</p>"); return "next"; },
        "ILLEGAL": function() { out("<pre>codegolfer is not in the sudoers file.  This incident will be reported</pre>"); return "next"; },
        "GODEXISTS": function() { out("<p>'GOD' spelled backwards is 'DOG'. A DOG is an animal that does not exists, and by backwarding this, we conclude that GOD exists and is not an animal.</p>"); return "next"; },
        "WINDOWS": function() { out("<p><img width='640' height='400' src='http://upload.wikimedia.org/wikipedia/commons/3/3b/Windows_9X_BSOD.png' alt='Sorry, this optional instruction was not implemented. Please, install the service pack.'></p>"); return "next"; },
        "NOOP": function() { return "next"; },
        "TURINGVSALONZO": function() {
          var r = Math.random() * 10;
          if (r < 2) return "next";
          if (r < 7) return "t" + (Math.random() * 14 + 1) * 1000;
          if (r < 9) return "t" + (Math.random() * 50 + 10) * 60 * 1000;
          return "quit";
        },
        "42": function() {
          out("<p>Calculating the answer of the life, the universe and everything.</p>");
          out("<p>Estimated time is 7.5 million years.</p>");
          out("<p>Don't you want to briefly take a coffe while you wait? It will not take long, I promise.</p>");
          return "quit";
        },

        // This is special, as it needs a (surprising) useless parameter, it can't be acessed directly without prior processing, this is why it is lowercase.
        "dontuseme": function() { dontuseme(); return "next"; },

        // This is special. If the INCLUDE-xxx generates a INCLUDE-yyy instruction, the yyy instruction will have an unknown random generated name.
        // Since yyy is random and unknown, it probably won't appear in the input source code, but implement it regardless.
        "include-random": function() { includeInstruction(randomString()); return "next"; }
      };

      function bad(line) {
        //alert(line);
        out("<p class='badshit'>Syntax error: </p>");
      }

      function beyondEnd() {
        out("<p class='badshit'>Unrecoverable error: Tried to execute code beyond the end or program.</p>");
      }

      function interpretInstruction(lines, idx) {
        if (idx >= lines.length) { beyondEnd(); return; }

        // The toUpperCase serves two purposes: Making the language case-insensitive and hiding private implementations as lowercase instructions.
        ins = lines[idx].trim().toUpperCase();

        var result;

        // Special handling for parsing DONTUSEME(n)
        if (ins.startsWith("DONTUSEME(") && ins.endsWith(")")) {
          try {
            parseInt(ins.substring("DONTUSEME(".length, ins.length - 1));
          } catch (e) {
            bad(ins);
            return;
          }
          ins = "dontuseme";

        // Special handling for INCLUDE-xxx
        } else if (ins.startsWith("INCLUDE-") && ins.length > 8) {
          var name = ins.substring(8);
          includeInstruction(name);
          ins = "NOOP"; // Already executed, follow-up as noop.
        }

        // Execute the instruction.
        var f = instructions[ins];
        if (!f) { bad(ins); return; }
        var result = f();

        // Move on.
        if (result === "quit") return;
        var toWait = result === "next" ? 0 : parseInt(result.substring(1));
        var ii = idx + 1;
        setTimeout(function() {
          interpretInstruction(lines, ii);
        }, toWait);
      }

      function startInterpreter() {
        $("#bt").hide();
        $("#cc").hide();
        $("#running").show();
        var src = $("#input").val();
        var lines = src.split('\n');
        interpretInstruction(lines, 0);
      }

      $(document).ready(function() {
        $("#bt").click(startInterpreter);
        $("#cc").click(clearOutput);
      });
    </script>
  </head>
  <body>
    <div id="everything">
      <p>Type here your program input:</p>
      <textarea id="input" style="width: 400px; height: 150px;"></textarea>
      <p>
        <button id="bt">Run the program</button>
        <span id="running" style="display: none;">Running the program...</span>
      </p>
      <p>Here is the program output:</p>
      <p id="output" class="useless"></p>
      <button id="cc" style="display: none;">Clear the output</button>
    </div>
  </body>
</html>

Tiene un nuevo comando:

Es el 42comando que calcula la respuesta de la vida, el universo y todo. La única peculiaridad es que lleva 7.5 millones de años terminar.

Otros spoilers:

Esta entrada tiene varias características:

  • Realmente odiarás el FAILcomando.
  • BOOM!te arruinará la "unidad de ejecución". Al menos las ventanas DONTUSEME(n)pueden sobrevivir a esto.
  • KABOOM! Es realmente peligroso para el mundo de varias maneras malas.
  • DONTUSEME(n)siempre abre infinitas ventanas vacías que no se pueden cerrar, una cada 0.8 segundos. Pero hay un interruptor oculto de matar.
  • DONTUSEME(n)sobrevive NO., FAILe incluso BOOM!. Sin embargo, no pude hacerlo sobrevivir KABOOM!. La razón es que las ventanas emergentes no funcionarán, ya que esto no es el resultado de un clic (y las ventanas emergentes creadas por otras formas están prohibidas en todos los principales navegadores), y tampoco pueden usar iframes debido a una violación de la política del mismo origen .
  • INCLUDE-xxxpuede crear cualquier instrucción, incluida DONTUSEME(n)u otra INCLUDE-yyyinstrucción.
  • Si INCLUDE-xxxgenera una INCLUDE-yyyinstrucción, el yyynombre se genera al azar. Si toma el nombre del comando generado con firebug o algo similar, puede usarlo.
  • Maneja la sintaxis con formato incorrecto y la entrada incompleta o vacía.

Victor Stafusa
fuente