12
\$\begingroup\$

Your task is to build an interpreter to the Useless language:

Here are the functional requirements:

  • All the described commands should be accepted by the interpreter.
  • NO., NOOP and INCLUDE-xxx must be honored.
  • DONTUSEME(n) must have its base date to be easily configurable to something more reasonable for testing purposes.
  • INCLUDE-xxx must be able to generate any command with a roughly equal probability. If it generates a DONTUSEME(n), he should randomly choose a small value for n.
  • DONTUSEME(n) windows should survive the NO. instruction. Tip: spawn a new process for those windows.
  • BOOM! and KABOOM! must do something bad and scary, and KABOOM! must be worse than BOOM!. But this must not be taken too seriously, so it should not be something destructive, overly-disruptive or hard to be undone. Please, do not, do not, and do not make these instructions run a rm -rf \ command, run a fork bomb, install malware, corrupt data in the file system, or post or download inappropriate content from the internet, or any other thing clearly abusive.
  • TURINGVSALONZO should run as if it in fact was doing what it should do. Tip: Make it randomly decide if it would sleep for a random very long time, or a random short time, or forever.
  • All the other predefined instructions should do something other than the aforementioned instructions and different one to the another, but never something worse than BOOM! or KABOOM!. What they do exactly is up to you, but a simple implementation would just output an error message or some other text.
  • You should provide an easy way for the user to provide the program that would be run by the interpreter. i.e. Reading plaintext from a file or from stdin is ok. Reading it from an encrypted file somewhere in the internet is not.

Optional:

  • You might invent some new commands if you want, but they should be subject to the same rules as the others are. Do not use this to circumvent the restrictions in BOOM! and KABOOM! or to defeat DONTUSEME(n). And if you do invent new commands, explain what they do.
  • You should think about what the interpreter do if it receives input with unknown commands (or even completely unparseable random bytes gibberish).
  • Although no instruction should defeat the DONTUSEME(n) command, you might add a kill switch for it. Just don't expose that in the language.

We have a few non-functional requirements to avoid abuses:

  • Your entry must be as complete and autocontained as possible. This means that it should not be simply some sort of installer or clearly incomplete program. This way, downloading and using libraries like jQuery or packages from maven central is ok, but downloading arbitrary code and packages from your custom server is not.
  • Your entry should not get any content from this very page or from some mirror or copy of this page in order to do some sort of reflection or for any other purpose. This is essential to avoid some program that try to read other entrants answers to this question or try to disrupt the question or answers in any way.
  • Your interpreter should be immutable and not self-modify or modify its input file. But, creating a mutant copy of the interpreter or of the input file without altering the original is ok.

And finally, considering that:

  • The programs in the answers are expected to be pretty useless even if fully conformant;
  • The language is (on purpose) very underspecified, and the answerers have a lot of liberties to take and are incentived to take them;
  • The requirements and the possible implementations have a lot of subjective points;
  • The objective with this is to just get some fun and creativity.

Then, this is a , and the most upvoted answer fully conformant to the rules wins! So, you don't need to golf or obfuscate your answer (but you might do that if you want). Just be sure to post something original and creative to deserve the upvotes, i.e. please don't post lame boring entries.

\$\endgroup\$
1
  • \$\begingroup\$ You mean `rm -rf `? \$\endgroup\$ Aug 4, 2014 at 0:42

2 Answers 2

9
\$\begingroup\$

HTML + Javascript + jQuery + jQuery UI

The input should be given in the text area and should be formatted as each command in a line. The commands are not case sensitive. All of the commands were fully implemented. I hope that you enjoy.

You can try it at 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>

It has one new command:

It is the 42 command which calculates the answer of the life, the universe and everything. The only quirk is that it takes 7.5 million years to finish.

Other spoilers:

This entry has several features:

  • You will really hate the FAIL command.
  • BOOM! will screw up you "execution unit". At least the windows from DONTUSEME(n) are able to survive this.
  • KABOOM! is really dangerous to world in several bad ways.
  • DONTUSEME(n) always opens infinite unclosable empty windows, one each 0.8 seconds. But there is a hidden kill switch.
  • DONTUSEME(n) survives NO., FAIL and even BOOM!. I just couldn't make it survive the KABOOM! though. The reason is that popup windows won't work as this is not the result of a click (and popups created by other ways are long banned in all major browsers), and could not use iframes too because of a violation of same-origin policy.
  • INCLUDE-xxx can create any instruction, including DONTUSEME(n) or another INCLUDE-yyy instruction.
  • If INCLUDE-xxx does generates an INCLUDE-yyy instruction, the yyy name is generated at random. If you grab the name of the generated command with firebug or something similar, you can use it.
  • It handles malformed syntax and incomplete or empty input.

\$\endgroup\$
8
+100
\$\begingroup\$

TI-BASIC

There is a kill button for DONTUSEME, can you figure out which one it is? :)

: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
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Does that :Goto 1 means that BOOM! is just a no-op? \$\endgroup\$ Feb 4, 2014 at 1:06
  • 1
    \$\begingroup\$ @VictorStafusa Yeah. After considering it some more, I changed it to `rm -rf ` because you told me (not) to. \$\endgroup\$
    – Timtech
    Jun 9, 2015 at 23:39
  • \$\begingroup\$ I don't think you implemented INCLUDE-. \$\endgroup\$
    – lirtosiast
    Jun 10, 2015 at 0:01

Not the answer you're looking for? Browse other questions tagged or ask your own question.